From: William Ahern on 16 Apr 2010 20:38 Chris Friesen <cbf123(a)mail.usask.ca> wrote: <snip> > This is all covered in the man pages for fork() and exec(). Generally > open files of various kinds are what you need to worry about. File > locks are not preserved over fork() but are over exec(). BSD locks a la flock() are preserved across a fork(), which makes it eminently more useful than POSIX locks, IMO.
From: David Schwartz on 16 Apr 2010 21:44 On Apr 16, 5:30 pm, William Ahern <will...(a)wilbur.25thandClement.com> wrote: > A good post, but it's missing the most portable option, getdtablesize(2). > > It's often considered "non-portable", and yet it's available in Linux, *BSD, > AIX, Solaris, and HP/UX (at least according to their online documentation). Some older versions of Linux incorrectly return a compile-time constant for 'getdtablesize', usually 256 or 1,024, even though larger numbers of file descriptors are 100% supported on those platforms. If you want to be completely safe on every platform I know of, you can use the highest of getdtablesize, getconf(_POSIX_OPEN_MAX), and getrlimit(RLIMIT_NOFILE). DS
From: Casper H.S. Dik on 17 Apr 2010 10:23 David Schwartz <davids(a)webmaster.com> writes: >On Apr 16, 5:30=A0pm, William Ahern <will...(a)wilbur.25thandClement.com> >wrote: >> A good post, but it's missing the most portable option, getdtablesize(2). >> >> It's often considered "non-portable", and yet it's available in Linux, *B= >SD, >> AIX, Solaris, and HP/UX (at least according to their online documentation= >). >Some older versions of Linux incorrectly return a compile-time >constant for 'getdtablesize', usually 256 or 1,024, even though larger >numbers of file descriptors are 100% supported on those platforms. If >you want to be completely safe on every platform I know of, you can >use the highest of getdtablesize, getconf(_POSIX_OPEN_MAX), and >getrlimit(RLIMIT_NOFILE). In Solaris it is possible to open a file descriptor, dup is to the highest available file descriptor and then lower the limit; it has closefrom() which is what Solaris applications use. Casper -- Expressed in this posting are my opinions. They are in no way related to opinions held by my employer, Sun Microsystems. Statements on Sun products included here are not gospel and may be fiction rather than truth.
From: William Ahern on 17 Apr 2010 13:35 Casper H.S. Dik <Casper.Dik(a)sun.com> wrote: <snip> > In Solaris it is possible to open a file descriptor, dup is to the > highest available file descriptor and then lower the limit; That's good to know. I was always curious, but downloading and installing OpenSolaris was too much work. I've tried twice and gave up. Maybe it's easier now. > it has closefrom() which is what Solaris applications use. The Solaris closefrom() man page suggests it may be using /proc, which would not be cool for chroot'd applications. Is this the case? OpenBSD's closefrom() is a system call, which seems more reasonable given the most common use for this is as a step immediately before or upon a fork or exec.
From: Ersek, Laszlo on 17 Apr 2010 14:00
On Fri, 16 Apr 2010, Joshua Maurice wrote: > On Apr 16, 4:19�pm, sc...(a)slp53.sl.home (Scott Lurndal) wrote: >> Joshua Maurice <joshuamaur...(a)gmail.com> writes: >>> However, if a process misbehaves, like not settings "close on >>> exec" when opening the file descriptor (an option only available in >>> recent Linux kernels) >> >> � The "Close on Exec" option has been part of _every_ unix and linux kernel >> since basically forever. � In Unix v7 it was an ioctl (FIOCLEX/FIONCLEX), >> in System V it was made an fcntl(2) flag. > > Race condition. Up until a recent Linux kernel version, you could not > set close on exec in open; you could only set it with fcntl. In a > multithreaded program, there is a small window between open and fcntl > in which fork could be called, resulting in that file descriptor being > leaked. This lack of possible correctness was fixed when you could > specify O_CLOEXEC to open. See > http://udrepper.livejournal.com/20407.html > for full details. Okay, now I see; I've read your other posting earlier. I would not have suggested the redirection of fd 77 from a temporary regular file under these circumstances. However, I can't help but note the following (perhaps I'm conflating two different objectives of yours): - first you wish to get rid of the complete inherited process environment, - then you complain you can't name a single property that would permeate a whole process tree, connected by nothing else than fork() lineage. I kind of see a contradiction between these points. What's worse, the wish to close file descriptors for security reasons offers a false sense of security. As long as a process can ptrace() another one, it is all snake oil. I can attach a gdb instance to any process, call fstat() on fd's 0 to 1024, call lseek(fd, 0, SEEK_CUR) to find out file offsets, call getpeername() to find out about internet peers, call pipe() and dup2() and fork() to embed a sniffer child between the original program code and the socket it writes to. I could read byte arrays before encryption, all on the process' behalf. Unless ptrace() is disabled on a system by default, or it is guaranteed that all subprocesses that should not have address-space level access to the parent and/or each other, are exec()'d from setuid images with pairwise different non-privileged uid's, I think this debate about setting FD_CLOEXEC atomically with open() is pointless. (Or, at least, insufficient in itself.) In the stackoverflow.com example, the parent itself is privileged enough to set different uid's for its children between the fork() and exec() calls. Unfortunately, if an external library calls fork() + exec() anywhere (even in a synchronously called subroutine), it can (and most probably will) omit this crucial step, and then again we'll have a child process that can ptrace() the parent or do whatever else it wants. The end result is that one can't link a library into a binary designed to be run as root without knowing that library inside out. But in that case, all fork() points are known, and the programmer might as well use manual close() instead of FD_CLOEXEC. Any rebuttal is highly appreciated. Thanks. Cheers, lacos |