I never mentioned proprietary plugins. We have these things called utility libraries. They use
fork+exec to run helper binaries among other reasons.
The utility library is not a trust boundary. If you think it is, then you've already screwed
up. However the resulting exec() is a trust boundary, the kernel provides for the executed
binary to receive different security privileges to the calling process.
If you think about it a little it's obvious that closefrom() isn't the appropriate interface
on its own because it requires you to export all the information about close-on-exec rules
into some arbitrary global structure and then have all utility libraries co-operate to use and
update that structure, whereas CLOEXEC pushes the relevant /security critical/ information
into each individual file descriptor. Sure enough the other systems you're talking about all
have CLOEXEC for exactly this reason. They just haven't fixed it yet and Linux has.
Posted Aug 6, 2008 13:20 UTC (Wed) by mheily (guest, #27123)
[Link]
The addition of O_CLOEXEC to the open(2) system call is a good idea, and is part of the
solution to the problem of "secure file descriptor handling" as udrepper calls it. I didn't
mean to imply that the O_CLOEXEC flag is useless, or that closefrom(3) is the be-all-end-all
solution to the problem. They are both tools that programmers need to make software more
secure. My point is that closefrom() is simpler solution and is applicable to the majority of
the cases where fd leakage is a concern.
A utility library is the perfect example of where closefrom() is needed. Since a library runs
in the same process context as the program that it is linked against, it inherits all open
file descriptors after calling fork(2). These descriptors have meaning to the overall program,
but are meaningless to the library. The library should, on principle, close all unneeded
descriptors prior to calling execve(), but it cannot guarantee that the O_CLOEXEC flag has
been enabled on all of the descriptors. As an extra precaution, and a simple way of making
*certain* that there is no leakage, the library can call closefrom() to exclude an entire
range of descriptors.