This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
exec* vs. initially-closed file descriptors in a set-ID context
- From: Jim Meyering <jim at meyering dot net>
- To: Ulrich Drepper <drepper at redhat dot com>
- Cc: libc-alpha at sources dot redhat dot com
- Date: Tue, 08 Nov 2005 21:12:19 +0100
- Subject: exec* vs. initially-closed file descriptors in a set-ID context
Hi Uli,
As I know you already know :-)
POSIX allows exec-family functions to ensure that the first
three file descriptors are open for programs that are run set-ID:
http://www.opengroup.org/susv3xsh/execl.html
glibc implements this in sysdeps/generic/check_fds.c with this code:
check_one_fd (STDIN_FILENO, O_RDONLY | O_NOFOLLOW);
check_one_fd (STDOUT_FILENO, O_RDWR | O_NOFOLLOW);
check_one_fd (STDERR_FILENO, O_RDWR | O_NOFOLLOW);
Can you think of a reason *not* to change it to look like this?
check_one_fd (STDIN_FILENO, O_WRONLY | O_NOFOLLOW);
check_one_fd (STDOUT_FILENO, O_RDONLY | O_NOFOLLOW);
check_one_fd (STDERR_FILENO, O_RDONLY | O_NOFOLLOW);
Note that that would make the reopened stdin *write-only*,
and the other two would be *read-only*.
Here's the motivation:
I'd like my robust hello-world program to fail when its stdout
is redirected to a closed file descriptor, and it usually does:
$ ./hello >&-
./hello: write error: Bad file descriptor
The problem is that when I make my program set-ID root, it no
longer fails, because the C library opens /dev/null on stdout
*for writing*. So the actual write syscall succeeds (the output
goes to /dev/null), and the set-ID program has no chance of
detecting the conceptual failure.
If instead glibc opened /dev/null read-only, this particular program
would fail (as I think it should) even when set-ID root.
However, it'd be even better if it could open some special
device for which *any* operation on the file descriptor would
fail. Otherwise, a set-ID program that calls e.g., lseek on
an initially-closed standard file descriptor would mistakenly
succeed in this unusual case. If we could find/use such a special
device, a set-ID program run with initially-closed standard file
descriptors that does something contrary like reading stdout or
writing stdin would fail (as it should), too.
Jim