[patch] SOCK_CLOEXEC, SOCK_NONBLOCK and MSG_CMSG_CLOEXEC

Jilles Tjoelker jilles at stack.nl
Tue Mar 19 20:20:59 UTC 2013


On Mon, Mar 18, 2013 at 10:59:57PM +0200, Konstantin Belousov wrote:
> On Sun, Mar 17, 2013 at 10:23:53PM +0100, Jilles Tjoelker wrote:
> > Here are some more modifications to allow creating file descriptors with
> > close-on-exec set. Like in linux/glibc, SOCK_CLOEXEC and SOCK_NONBLOCK
> > can be OR'ed in socket() and socketpair()'s type parameter, and
> > MSG_CMSG_CLOEXEC to recvmsg() makes file descriptors (SCM_RIGHTS)
> > atomically close-on-exec.

> > The numerical values for SOCK_CLOEXEC and SOCK_NONBLOCK are as in
> > NetBSD. MSG_CMSG_CLOEXEC is the first free bit for MSG_*.

> > I do not pass the SOCK_* flags to MAC because this may cause incorrect
> > failures and can be done later via fcntl() anyway. I expect audit to
> > cope with the new flags.

> > For MSG_CMSG_CLOEXEC, I had to change unp_externalize to take a flags
> > argument.

> This looks fine to me.

Thanks for the review.

> The only note I have, which is not directly related to your patch,
> is the recvmsg(2) behaviour when the undefined flag is passed.
> The syscall silently ignores the flags. I think this is quite wrong,
> and would cause interesting (security) implications if the program
> using the MSG_CMSG_CLOEXEC is run on older kernel which does not
> interpret the flag.

This is indeed unfortunate and it also affects open(2).

It may have originally been done for reasons of modularity; the
sys_open() and kern_open() need not know about the valid flag bits this
way and a device driver or filesystem can define new bits.

The effect of an older kernel ignoring MSG_CMSG_CLOEXEC is probably not
that bad, considering that running new userland on an old kernel is not
supported. Most compatibility shims for MSG_CMSG_CLOEXEC and similar
flags (such as the one in Wayland) simply contain the race condition, so
you lose anyway with an old kernel. It would be possible to use
closefrom() or an emulation of it or to lock fork() conditionally on the
necessary CLOEXEC flags not being available but it appears that people
do not go to that trouble.

> Might be, we should start returning EINVAL for unknown flag, despite
> SUSv4 not specifying the condition ?

Per POSIX it is valid to do this but it might cause a compatibility
problem if there are applications that pass garbage in flags.

-- 
Jilles Tjoelker


More information about the freebsd-hackers mailing list