Bug 241609 - fexecve() fails after calling setuid() or seteuid()
Summary: fexecve() fails after calling setuid() or seteuid()
Alias: None
Product: Fedora
Classification: Fedora
Component: kernel
Version: 5
Hardware: All
OS: Linux
Target Milestone: ---
Assignee: Kernel Maintainer List
QA Contact: Brian Brock
Depends On:
TreeView+ depends on / blocked
Reported: 2007-05-28 21:12 UTC by Rennie deGraaf
Modified: 2007-11-30 22:12 UTC (History)
1 user (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Last Closed: 2007-08-20 22:35:25 UTC
Type: ---

Attachments (Terms of Use)
A program that demonstrates the bug. (540 bytes, text/x-csrc)
2007-05-28 21:12 UTC, Rennie deGraaf
no flags Details

Description Rennie deGraaf 2007-05-28 21:12:18 UTC
Description of problem:
Linux currently lacks a proper fexecve() system call, so fexecve() is
implemented as a glibc library call that looks up the file to execute in
/proc/self/fds and calls execve().  However, if a program that starts as root
drops root privileges by calling setuid() or seteuid() before calling fexecve()
(for instance, in order to execute a program as another user), then it no longer
has read access to /proc/self/fds, and fexecve() fails.

The man page for fexecve() does not mention this failure mode.  (Incidentally,
the man page for fexecve() in not included in FC5.)

Version-Release number of selected component (if applicable):
This bug occurs in glibc-2.4-11 from FC5.  Since sysdeps/unix/sysv/linux/fexec.c
in the glibc sources (the file implementing the fexecve() emulation) hasn't
changed, I expect that this issue occurs in all versions of glibc that implement

Steps to Reproduce:
Run the attached program *as root*.  (If user id 99 doesn't exist on your
system, change the arguments of the setuid() or seteuid() call a user id that
does exist.)  It should produce no output and return 0, but it instead prints
"fexecve() failed; errno = 13" and returns 255, indicating that the call to
fexecve() failed. (errno code 13 is EACCES).  If the setuid() and seteuid()
calls are both commented out, the program works as expected.

Additional Info:
I don't think that this can be fixed in libc; we need a proper kernel
implementation.  A work-around is to use execve() directly, but this leads to
race conditions under some circumstances (such as when trying to execute a file
with the file owner's permissions).

Comment 1 Rennie deGraaf 2007-05-28 21:12:18 UTC
Created attachment 155559 [details]
A program that demonstrates the bug.

Comment 2 Jakub Jelinek 2007-05-28 23:17:42 UTC
Then why are you filling that against glibc?

Comment 3 Rennie deGraaf 2007-05-28 23:33:31 UTC
(In reply to comment #2)
> Then why are you filling that against glibc?

Because fexecve() is currently implemented there.  At the very least, this issue
should be added to the glibc documentation as a known bug, and the glibc wrapper
will need to be fixed when a better solution becomes available.  There is also a
possibility that the glibc gurus can come up with a better way of implementing
fexecve() in userspace.

The kernel bug is that fexecve() isn't implemented, not that it doesn't work

Comment 4 Rennie deGraaf 2007-05-29 00:49:07 UTC
I just discovered that a patch was added to the kernel as of 2.6.22-rc1 that
allows access to /proc/self/fd/ by programs that have called setuid().  This may
solve this issue; I don't currently have a system lying around that I want to
test a pre-release kernel on.

Comment 5 Ulrich Drepper 2007-08-20 22:35:25 UTC
This is exclusively a kernel issue and is at least in F7 fixed.

Note You need to log in before you can comment on or make changes to this bug.