LWN.net Logo

Advertisement

Front, Kernel, Security, Distributions, Development. See your byline here on LWN.net.

Advertise here

More fun with file descriptors

More fun with file descriptors

Posted Jun 14, 2007 14:41 UTC (Thu) by nix (subscriber, #2304)
In reply to: More fun with file descriptors by davecb
Parent article: More fun with file descriptors

That works fine in apps, but not in libraries. If a library wants to open some persistent fd, it currently has no guarantee that the app hasn't closed that fd on it, or dup2()ed another one over the top of it. I've seen problems with syslog() caused by exactly this in the past, and even problems with the three standard fds (buggy app closes them all rather than opening /dev/null three times and wackiness ensues.)


(Log in to post comments)

More fun with file descriptors

Posted Jun 14, 2007 14:52 UTC (Thu) by davecb (subscriber, #1574) [Link]

Hmmn, any app writer who kills his own syslog get exactly what
they deserve (;-))

Joking aside, the code snippit was from a LD_PRELOAD library that
I tested with approximtely 2954 popular apps (on Solaris, mind
you) without getting whacked.

I suspect normal evolution will prune out the exceptions over
time: the commercial plus open-source Solaris space seems
to be pretty well clean.

--dave

More fun with file descriptors

Posted Jun 14, 2007 18:24 UTC (Thu) by vmole (guest, #111) [Link]

Hmmn, any app writer who kills his own syslog get exactly what they deserve (;-))

Any syslog that allows the user app to kill it through normal standard procedures (e.g. closing fds for a daemon) is broken. :-)

Unfortunately, this is one of those cases where you have to know something about the underlying libc implementation to avoid screwing yourself. In particular, most of the implementations I've worked with only break if you've called openlog().

More fun with file descriptors

Posted Jun 15, 2007 19:12 UTC (Fri) by giraffedata (subscriber, #1954) [Link]

Any syslog that allows the user app to kill it through normal standard procedures (e.g. closing fds for a daemon) is broken. :-)

Unfortunately, this is one of those cases where you have to know something about the underlying libc implementation to avoid screwing yourself.

It's not that you have to know the underlying libc implementation. Rather, you have to know libc's requirements of its environment. You don't leave a file descriptor open because you know syslog functions use it; you leave it open because the syslog facility requires you not to mess with any file descriptor you didn't create.

There are dozens of ways a library places requirements on its environment because of resources shared among all code in the process. Some of the requirements are easily accepted, such as that a caller should not write over any memory it did not allocate (which allows the library to keep memory of its own). Sometimes the requirements are onerous, but "broken" is too strong a word for a library with inconvenient requirements. "less useful" or "dangerous" are better descriptions. Signal handlers, alarms, environment variables, stack space, terminal display space, Standard Error file contents, etc. are all controversial.

More fun with file descriptors

Posted Jun 15, 2007 19:01 UTC (Fri) by giraffedata (subscriber, #1954) [Link]

If a library wants to open some persistent fd, it currently has no guarantee that the app hasn't closed that fd on it, or dup2()ed another one over the top of it.

But that's also true of the kernel modifications being proposed. And it's similar to the risk that the app will write over memory that was malloc'ed by the library. The app and library, in a single thread, can stay out of each others' way with the F_DUPFD method if they observe obvious protocol. That is in contrast with simple open(), in which a library call can defeat its caller's assumptions of sequentially allocated file descriptors.

What the kernel proposal has that F_DUPFD doesn't is that 1) it works even multithreaded (the F_DUPFD method requires the library to temporarily to use a low FD, and another thread could see that) and 2) it allows the high fds to be higher (today, the maximum fd is quite low because of the way the kernel data structures are).

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