-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 According to Bruno Haible on 8/23/2009 6:01 PM: > Now that we have pipe2, accept4, the next step is to combine them with > the *-safer functionality. This overlaps with F_DUPFD and F_DUPFD_CLOEXEC. > So, the actual better primitives are > dup_ex (int fd, int flags, int minimum)
I almost wonder if it is better to change the signature of the existing dup_safer to take extra parameters. There are a few clients of dup_safer that would have to pass the extra argument, but most users go via "unistd--.h" which can adjust the #define appropriately. In other words, I see no reason to invent dup_ex, rather just adjust the API of dup_safer. Whether or not we change the signature of dup_safer, I think this would be a better primitive (then we can map dup, dup2, fcntl, and dup_safer onto the same primitive): /* Duplicate FD into a new file descriptor, at least as large as MINIMUM, and first closing any existing fd at minimum if OVERWRITE. FLAGS can contain O_CLOEXEC, O_TEXT, or O_BINARY. */ gl_dup (int fd, int minimum, int flags, bool overwrite) dup (n) -> gl_dup (n, 0, 0, false) dup2 (n, m) -> gl_dup (n, m, 0, true) dup3 (n, m, flags) -> gl_dup (n, m, flags, true) fcntl (n, F_DUPFD, m) -> gl_dup (n, m, 0, false) fcntl (n, F_DUPFD_CLOEXEC, m) -> gl_dup (n, m, O_CLOEXEC, false) dup_safer (n) -> gl_dup (n, 3, 0, false) dup_safer_noinherit (n) -> gl_dup (n, 3, O_CLOEXEC, false) > pipe2_ex (int fd[2], int flags, int minimum) Seems okay (although maybe the name gl_pipe2 is better than pipe2_ex): pipe (fd) -> pipe2_ex (fd, 0, 0) pipe2 (fd, flags) -> pipe2_ex (fd, flags, 0) pipe_safer (fd) -> pipe2_ex (fd, 0, 3) pipe2_safer (fd, flags) -> pipe2_ex (fd, flags, 3) and "unistd--.h" would automatically pick up pipe2_safer. > accept4_ex (int s, struct sockaddr *addr, socklen_t *addrlen, int flags, > int minimum) Likewise. Another thought I had would be inventing our own O_SAFER flag (which we then mask off before calling the real underlying functions, but use its presence to guarantee that any fd returned will be 3 or larger). It doesn't map very well to fcntl or dup2, (but those interfaces can already specify a minimum or target fd), and doesn't make sense with dup3 (which specifies a target fd). But it makes life for all the other safer variants possible; and it very much does imply that we'd need a gl_dup primitive for dup/dup_safer/dup_noinherit. For that matter, proposing an O_SAFER to the glibc folks might be worthwhile. At which point, we have things like: open_safer (s, f [, m]) -> open (s, f | O_SAFER [, m]) pipe (fd) -> pipe2 (fd, 0) pipe_safer (fd) -> pipe2 (fd, O_SAFER) pipe2_safer (fd, flags) -> pipe2 (fd, flags | O_SAFER) dup (n) -> gl_dup (n, 0) dup_safer (n) -> gl_dup (n, O_SAFER) dup_safer_noinherit (n) -> gl_dup (n, O_SAFER | O_CLOEXEC) > > I prefer the dup_ex interface to fcntl, because it supports not only > O_CLOEXEC but also O_TEXT / O_BINARY and possibly other flags in the future. But at least you can change O_TEXT/O_BINARY after the fact, without risking the security hole that O_CLOEXEC was invented to plug. - -- Don't work too hard, make some time for fun as well! Eric Blake [email protected] -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (Cygwin) Comment: Public key at home.comcast.net/~ericblake/eblake.gpg Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAkqR/O8ACgkQ84KuGfSFAYAUvQCgq8KoWW6YI25I1SxqjdZt5xfF DJ0AoIu9bheU4D2AHSdJW4quKyt/bBK0 =fNJs -----END PGP SIGNATURE-----
