|| ||Michael Kerrisk <firstname.lastname@example.org>|
|| ||O_CLOEXEC / MSG_CMSG_CLOEXEC documentation|
|| ||Wed, 05 Sep 2007 21:02:23 +0200|
|| ||lkml <email@example.com>|
For man-pages-2.66, I have added the following documentation in
the open.2 man page for the new-in-2.6.23 O_CLOEXEC.
O_CLOEXEC (Since Linux 2.6.23)
Enable the close-on-exec flag for the new file
descriptor. This is useful in multithreaded programs
since using a separate fcntl(2) F_SETFD operation to
set the FD_CLOEXEC flag does not suffice to avoid race
conditions in multithreaded programs where one thread
opens a file descriptor at the same time as another
thread does a fork(2) plus execve(2).
For the recv.2 I added the analogous:
MSG_CMSG_CLOEXEC (recvmsg() only; since Linux 2.6.23)
Set the close-on-exec flag for the file descriptor
received via a Unix domain file descriptor using the
SCM_RIGHTS operation (described in unix(7)). This
flag is useful for the same reasons as the O_CLOEXEC
flag of open(2).
Please let me know if these changes are correct and complete.
> The patch titled
> Introduce O_CLOEXEC
> has been added to the -mm tree. Its filename is
> *** Remember to use Documentation/SubmitChecklist when testing your code ***
> See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-... to find
> out what to do about this
> Subject: Introduce O_CLOEXEC
> From: Ulrich Drepper <firstname.lastname@example.org>
> The problem is as follows: in multi-threaded code (or more correctly: all
> code using clone() with CLONE_FILES) we have a race when exec'ing.
> thread #1 thread #2
> fork + exec
> In some applications this can happen frequently. Take a web browser. One
> thread opens a file and another thread starts, say, an external PDF viewer.
> The result can even be a security issue if that open file descriptor
> refers to a sensitive file and the external program can somehow be tricked
> into using that descriptor.
> Just adding O_CLOEXEC support to open() doesn't solve the whole set of
> problems. There are other ways to create file descriptors (socket,
> epoll_create, Unix domain socket transfer, etc). These can and should be
> addressed separately though. open() is such an easy case that it makes not
> much sense putting the fix off.
> The test program:
> #include <errno.h>
> #include <fcntl.h>
> #include <stdio.h>
> #include <unistd.h>
> #ifndef O_CLOEXEC
> # define O_CLOEXEC 02000000
> main (int argc, char *argv)
> int fd;
> if (argc > 1)
> fd = atol (argv);
> printf ("child: fd = %d\n", fd);
> if (fcntl (fd, F_GETFD) == 0 || errno != EBADF)
> puts ("file descriptor valid in child");
> return 1;
> return 0;
> fd = open ("/proc/self/exe", O_RDONLY | O_CLOEXEC);
> printf ("in parent: new fd = %d\n", fd);
> char buf;
> snprintf (buf, sizeof (buf), "%d", fd);
> execl ("/proc/self/exe", argv, buf, NULL);
> puts ("execl failed");
> return 1;
maintainer of Linux man pages Sections 2, 3, 4, 5, and 7
Want to help with man page maintenance? Grab the latest tarball at
read the HOWTOHELP file and grep the source files for 'FIXME'.