This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]