[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Re: CLOEXEC safety
- From: Daurnimator <quae@...>
- Date: Fri, 20 Nov 2015 09:57:44 +1100
On 20 November 2015 at 03:49, Sean Conner <firstname.lastname@example.org> wrote:
> It was thus said that the Great Daurnimator once stated:
>> Hi all,
>> I've been thinking about safely spawning processes in a multithreaded
>> program lately.
>> The opinion of POSIX seems to be that `closefrom` is wrong, and that
>> well-written programs and libraries should always open fd with
>> O_CLOEXEC set from the start.
>> To aid this, the "e" specifier to fopen (currently a gnu extension) is
>> to be featured in the next POSIX standard.
>> This "e" flag has been widely supported by libcs on posix systems for
>> many years.
>> This same feature is available on windows as the "N" flag to fopen.
>> To prevent issues in multi-threaded applications that use lua,
>> I suggest that lua automatically append the relevant flag to the fopen 'mode'.
>> i.e. "e" on POSIX systems and "N" on windows.
> And what if I *want* to pass an open file to a child process? How do I
> specify to Lua that I *don't* want this behavior?
> -spc (or is stdin, stdout and stderr only allowed to remain open in a
> child process?)
Lua with only standard libraries doesn't expose whjich file descriptor
a file is opened as; so trying to "pass" it to a child is impossible
(you must indicate to the child which fd it should use) without making
platform specific educated guesses (which may be invalidated by a libc
update, or just running in a slightly different context).
And infact, the current behaviour is sort of unsafe (all files open in
the parent show up in the child!):
$ lua -e 'fd = io.tmpfile(); os.execute("ls -l /proc/self/fd")'
lrwx------ 1 daurnimator daurnimator 64 Nov 20 09:55 0 -> /dev/pts/9
lrwx------ 1 daurnimator daurnimator 64 Nov 20 09:55 1 -> /dev/pts/9
lrwx------ 1 daurnimator daurnimator 64 Nov 20 09:55 2 -> /dev/pts/9
lrwx------ 1 daurnimator daurnimator 64 Nov 20 09:55 3 ->
lr-x------ 1 daurnimator daurnimator 64 Nov 20 09:55 4 -> /proc/10743/fd
If you're using a library that allows spawning scripts, it should have
a way to pass descriptors to the child.
This may be implemented by using fcntl to turn off FD_CLOEXEC.
Or more commonly, a library will use `dup2` after the fork to copy the
file descriptor from the old (arbitary) fd to a well-known one.