LWN.net Logo

File descriptor handling changes in 2.6.27

File descriptor handling changes in 2.6.27

Posted Mar 2, 2011 21:12 UTC (Wed) by foom (subscriber, #14868)
In reply to: File descriptor handling changes in 2.6.27 by nybble41
Parent article: File descriptor handling changes in 2.6.27

That's not true: bash knows (or could easily keep track of) which fds the shell script it's running has requested be opened, and thus which it should pass to future executed programs. (since the semantics of the shell scripting language are that all the opened fds get passed to all programs you run).

That doesn't imply that all *other* non-shell-script-requested exec that get called from bash (e.g. execing a program from a NSS plugin) should also pass those same FDs! The right place really would've been for the list to be specified in exec. But...it's too late for that.


(Log in to post comments)

File descriptor handling changes in 2.6.27

Posted Mar 2, 2011 23:18 UTC (Wed) by nybble41 (subscriber, #55106) [Link]

The top-level interactive instance of bash knows, but the script *doesn't*, at least not without parsing the filename it was given. (I assume you agree that it would normally be a bad idea for programs to assign meaning to specific filename patterns?)

The first exec() is not the problem; as you say, bash knows that it opened a certain FD to pass to the script and would avoid closing it. The issue arises when the script tries to pass the /dev/fd/N filename it received to some other command. If the script closes all the file descriptors apart from stdin/stdout/stderr and any others *it* knows about--which would not include the FD opened by its parent process--the child process will either receive an error, or even duplicate an unrelated FD, when attempting to open the original path.

Keep in mind that this is a simple case; there could be any number of levels of fork()/exec() between that interactive session and the actual user(s) of the /dev/fd/N path; only the first is likely to be aware of the need to preserve the associated file descriptor.

I agree that there are cases (such as your NSS helper example) where it makes sense to close most or all file descriptors between fork() and exec(). However, at the very least, any time you pass on a filename received directly or indirectly from a parent process you should also pass on any file descriptors which were open when your process was started; anything less risks breaking the ability to use <(...) or >(...) from the shell in place of a regular file (among other uses).

File descriptor handling changes in 2.6.27

Posted Mar 2, 2011 23:40 UTC (Wed) by foom (subscriber, #14868) [Link]

Ah, indeed. I had forgotten about that evil little non-portable hack. Well, if you instead use the temporary fifo implementation of <() (which bash already supports), you won't have that problem. And since we're talking in hypotheticals here (it's not like exec is actually going to change), I declare that a perfectly acceptable solution to the issue.

Copyright © 2013, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds