Hide Forgot
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 fexecve(). 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).
Created attachment 155559 [details] A program that demonstrates the bug.
Then why are you filling that against glibc?
(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 properly.
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.
This is exclusively a kernel issue and is at least in F7 fixed.