]> git.ipfire.org Git - thirdparty/haproxy.git/commit
BUG/MEDIUM: external-checks: close all FDs right after the fork()
authorWilly Tarreau <w@1wt.eu>
Tue, 21 Jun 2016 13:32:29 +0000 (15:32 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 21 Jun 2016 16:10:50 +0000 (18:10 +0200)
commitb7b2478733567d2f167199e02072f90930986d33
treeb9e8be5bed44343970085d74c4167d07d5333fdb
parent164dd0b6e4ad36dc90e9163eeb84d3fb4aa175e9
BUG/MEDIUM: external-checks: close all FDs right after the fork()

Lukas Erlacher reported an interesting problem : since we don't close
FDs after the fork() upon external checks, any script executed that
writes data on stdout/stderr will possibly send its data to wrong
places, very likely an existing connection.

After some analysis, the problem is even wider. It's not enough to
just close stdin/stdout/stderr, as all sockets are passed to the
sub-process, and as long as they're not closed, they are usable for
whatever mistake can be done. Furthermore with epoll, such FDs will
continue to be reported after a close() as the underlying file is
not closed yet.

CLOEXEC would be an acceptable workaround except that 1) it adds an
extra syscall on the fast path, and 2) we have no control over FDs
created by external libs (eg: openssl using /dev/crypto, libc using
/dev/random, lua using anything else), so in the end we still need
to close them all.

On some BSD systems there's a closefrom() syscall which could be
very useful for this.

Based on an insightful idea from Simon Horman, we don't close 0/1/2
when we're in verbose mode since they're properly connected to
stdin/stdout/stderr and can become quite useful during debugging
sessions to detect some script output errors or execve() failures.

This fix must be backported to 1.6.
src/checks.c