curl / Mailing Lists / curl-library / Single Mail
Buy commercial curl support from WolfSSL. We help you work out your issues, debug your libcurl applications, use the API, port to new platforms, add new features and more. With a team lead by the curl founder himself.

Re: Supporting atomic noninheritability of FDs

From: Eric Wong via curl-library <curl-library_at_cool.haxx.se>
Date: Thu, 12 Dec 2019 07:21:18 +0000

Jeff Mears via curl-library <curl-library_at_cool.haxx.se> wrote:
> By default, file handles are inheritable. This means that if
> you have a server using libcurl and call fork() + exec(), the
> file handles used by libcurl are inherited by the child
> process. This can have security implications in some cases,
> but more commonly just results in unreliability: close() won't
> disconnect the TCP connection because the socket is still open
> in an unaware child process for who knows how long.
>
> Fixing this is complicated, though. Many UNIX systems have a
> way to mark a socket as close-on-exec. It has to be atomic,
> though, because in a multi-threaded application, a fork() may
> come at any moment.

Fwiw, some high-level scripting languages (Perl 5.6+, and more
recently, Ruby 2.0+) default to close-on-exec. I think it'd be
a good change to curl with minimal risk of incompatibilities.

> In Linux, open() and socket() have platform-specific flags to
> make the handle close-on-exec atomically. For open(), it's
> O_CLOEXEC, and for socket(), it's SOCK_CLOEXEC bitwise-or'd
> into the "type" parameter. accept() has no room for such a
> parameter, so Linux defines an alternate version, accept4(),
> that takes a 4th parameter to which SOCK_CLOEXEC can be
> passed. (Linux also supports O_NONBLOCK/SOCK_NONBLOCK to set
> non-blocking mode without another system call, but this is
> just a performance improvement.)

Yup. For what it's worth, open(...O_CLOEXEC) is in POSIX
nowadays, and some BSDs (FreeBSD and OpenBSD, at least) also
have accept4 and socket(...SOCK_CLOEXEC/NONBLOCK), so the
expectation is all that good stuff will be in POSIX one day...

<snip>
No idea about the proprietary OSes...

> Even with all this, the problem can't fully be solved on
> Linux, because calls to fopen() by anything create an
> inheritable handle. OpenSSL reading the certificate file
> would leak a handle in parallel with a fork(), as a simple
> example.

fopen(..."e") works in glibc and aforementioned BSDs.
open(...O_CLOEXEC) && fdopen(fd...) also works.

> Is it worth trying?

I believe it is, if you have the time :)

Also in OpenSSL/GnuTLS and any other libraries libcurl uses (but
maybe they do already).
-------------------------------------------------------------------
Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library
Etiquette: https://curl.haxx.se/mail/etiquette.html
Received on 2019-12-12