[systemd-devel] systemd's connections to /run/systemd/private ?

Lennart Poettering mzxreary at 0pointer.de
Wed Aug 14 09:34:21 UTC 2019


On Mi, 14.08.19 18:53, Michael Chapman (mike at very.puzzling.org) wrote:

> On Wed, 14 Aug 2019, Michael Chapman wrote:
> > On Wed, 14 Aug 2019, Brian Reichert wrote:
> > > On Thu, Aug 01, 2019 at 07:18:20PM +0000, Zbigniew J??drzejewski-Szmek wrote:
> > > > Yes. (With the caveat that there *are* legitimate reasons to have new
> > > > long-lived fds created, so not every long-lived fd is "wrong".)
> > >
> > > I finally was able to track down what's happening on my system.
> > >
> > > This is sufficient to reproduce the effect of increasing the number
> > > of file descriptors open to /run/systemd/private; at least, on my
> > > box, in it's current state:
> > >
> > >   sh -c 'exec 1>&-; /usr/bin/systemctl status ntpd.service'
> >
> > I can reproduce this on CentOS 7's systemd 219, but not on Fedora 29's
> > systemd 239.
>
> Looking in to this further, my guess is that this is fixed in:
>
>   commit 7fe2903c2315db9d9f501ae255a6b6e4f01ba46c
>   Author: Lennart Poettering <lennart at poettering.net>
>   Date:   Fri Feb 9 17:53:28 2018 +0100
>
>       fd-util: move certain fds above fd #2 (#8129)
>
> which was introduced in systemd 238.
>
> What's happening is that systemctl is getting fd 1 for the socket to
> /run/systemd/private, as it's the lowest unused fd, but fd 1 (aka stdout)
> is also where it sends its regular human-readable output. This commit
> ensures that the socket is moved to a file descriptor that can't be
> mistaken for a standard stream.
>
> I'm not sure if systemd >= 238 itself still suffers from the problem where
> any "extra" data on that connection causes it to leak its file descriptor.
> That may still be a problem, or it may have been fixed by a different
> commit.

Quite frankly, invoking generic UNIX programs with fds < 3 closed is a
really bad idea in general. That systemctl nowadays is particularly
careful and deals with situations like that is not an invitation to
actually invoke things like this. After all UNIX guarantees that
open() (and the other calls that allocate an fd) allocated the lowest
available one, hence they will necessarily step into
stdin/stdout/stderr territory when invoked with any of those fds
closed.

Hence: your code that closes fd1 like this is simply buggy. Don't do
that, you are shooting yourself in the foot. And even if newer
systemctl will handle cases like this more gracefully pretty much any
other tool you might call will break in some form or another too,
since a simple printf() will already spill into the wrong fds in that
case.

Lennart

--
Lennart Poettering, Berlin


More information about the systemd-devel mailing list