Module Name:    src
Committed By:   kre
Date:           Sun Nov 10 00:11:43 UTC 2024

Modified Files:
        src/sys/kern: kern_descrip.c

Log Message:
Make O_CLOEXEC always close specified files on exec

It turns out that close-on-exec doesn't always close on exec.

If all close-on-exec fd's were made close-on-exec via dup3() or
fcntl(F_DUPFD_CLOEXEC) or use of the internal fd_clone() (whose uses
I did not fully investigate but I think is used to create a fd for
the open of a cloner device, and perhaps other things) then none
of the close-on-exec file descriptors will be closed when an exec
happens - but will be passed through to the new process (still marked,
apparently, as close-on-exec - but still won't be closed if another exec
happens) - that is unless...

If at least one fd in the process has close-on-exec set some other way
(fcntl(F_SETFD), open(O_CLOEXEC) (and the similar functions for sockets,
and epoll) and perhaps others then all close-on-exec file descriptors
in the process will be correctly closed when an exec happens (however
they obtained the close-on-exec status).

There are two steps that need to be taken (in the kernel) when turning
on close on exec - the obvious one of setting the ff_exclose field in
the struct fdfile for the fd.   And second, marking the file descriptor
table (which holds the fdfile's for one or more processes) as containing
file descriptors with close-on-exec set (it is a simple yes/no, and once
set is never cleared until an actual exec happens).  If it was set during
an exec, all the file descriptors are examined, and those marked
close-on-exec are closed.   If the file descriptor table doesn't indicate
that close-on-exec fds exist in the table, none of that happens.

Several places were setting ff_exclose in the struct fdfile but
not bothering to set the fd_exclose field in the file descriptor table.

There's even a function (fd_set_exclose()) whose whole purpose is to do
this properly - but it wasn't being used.

Now it is, everywhere (I hope).


To generate a diff of this commit:
cvs rdiff -u -r1.263 -r1.264 src/sys/kern/kern_descrip.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Reply via email to