Subject: Re: Addition to force open to open only regular files
To: None <>
From: Wolfgang Solfrank <>
List: tech-kern
Date: 11/20/2000 15:37:48

> In the case of $HOSTALIASES and rewind tape devices it would in effect
> prevent the library routines using $HOSTALIASES from accidentally
> opening a tape device when called from a set-ID process where the
> current effective-ID was permitted to open that device.  I.e. the
> library would do something like:
>   fd = open_as(getenv("HOSTALIASES"), O_RDONLY, (mode_t) 0, getuid());
> and since the tape device wouldn't normally be accessible by the real
> user-ID, the call would fail with EPERM.

But since you need to know the user-ID to give to open_as as argument,
I ask again, what is different to a seteuid(getuid()); open(...); setback();
sequence?  Especially, the argument, that you could have swapped the
uids with another call to seteuid() doesn't count, does it?

> A special set of filesystem-ID credentials in the process structure
> would be used in a similar way -- the set-ID program would call
> setfuid(getuid()) [and maybe setfgid(getgid()), etc.] before calling
> open() [or any other filesystem affecting system call], and as a result
> the kernel would do filesystem accesses not as the effective user, but
> rather as the real user.  Presumably this would/could be undone by
> resetting the fs-IDs to be the same as the set-IDs again.

Again, I don't see what this would buy us.  Can anyone explain what
separate credentials for filesystem calls would be of use for?

> In smail-3.2.0.x I've done something similar with a function called
> fopen_as_user(), and what's unique about my implementation over the one
> that preceded it is that I use fork() and setuid() instead of seteuid().
> This allows smail to hopefully safely open things like ~/.forward files
> because the open() is done as the user.  Of course in a portable
> user-land implemtation, such as the one in smail, it's still necessary
> to first open the file as the effective user (i.e. root) since portable
> implementations have to work where there are no file descriptor passing
> facilities (and thus my implementation is not safe against a race attack
> of a file like the tape rewind-on-close device).  If FD passing is
> possible then the child process can do the sole open and just pass back
> the resulting descriptor to the parent, but I've not implemented that
> version (yet).  Without FD passing it's necessary to open the file
> twice, once in the parent, and then again in the child as the real user,
> and then compare the fstat() results to ensure that both opened the same
> file (i.e. avoided all race conditions).

Hmm, what about doing all accesses to the file in question via the child
process?  I.e., why does the parent itself have to have an FD for the file
at all?

BTW, people keep arguing that a problem with using these library
functions is that they cannot rely on the caller to not have switched
the user (or group) ID before calling the library function.  Huh?
Just document it that the caller mustn't call the function with switched
IDs and be done with it.  It sure isn't possible for the average user
to switch IDs and cause library functions to be called arbitrarily in
an executable he doesn't own, or is it?  And if it is, you are lost
anyway, are you not?

ws@TooLs.DE     Wolfgang Solfrank, TooLs GmbH 	+49-228-985800