New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support pointing StandardInput/StandardOutput/StandardError to file #3991

Closed
lucaswerkmeister opened this Issue Aug 19, 2016 · 7 comments

Comments

6 participants
@lucaswerkmeister
Copy link
Member

lucaswerkmeister commented Aug 19, 2016

Submission type

  • Bug report
  • Request for enhancement (RFE)

I think it would be useful if the systemd.exec(5) options StandardInput=, StandardOutput= and StandardError= supported reading from / writing to files. Of course, this can already be emulated using

ExecStart=/bin/sh -c 'exec /path/to/program arg1 arg2 < inputfile > outputfile'

but I think it would be convenient to also support this in the dedicated directives.

Suggested syntax:

StandardInput=</read/from/this/file
StandardOutput=>/write/to/this/file
StandardError=>>/append/to/this/file

One open question is that of permissions. What should happen when a service with these options is started?

User=nobody
StandardInput=</etc/shadow # not readable by user
StandardOutput=>/etc/sudoers # not writable at all
  1. Don’t allow this. Open the file after changing user and group, so that the permissions will be checked against the unit’s user and group and the redirection will fail. (Alternatively, have systemd itself check permissions before changing user and group, but it’s probably best to leave this to the kernel.)
  2. Allow this. Open the file before changing user and group. This could be convenient to service authors, but could also be a giant security hole if any user can create or edit service files. On the other hand, this potential security hole probably already exists (ExecStart=cp /protected/file /public/location).
  3. Allow this, but require explicit specification of the intent to ignore permissions with some special syntax like StandardInput=!</read/this/protected/file.
@davide125

This comment has been minimized.

Copy link
Contributor

davide125 commented Aug 19, 2016

👍 We've seen issues in the past where processes logging a copious amount of data would end up stuck or receive SIGPIPE if systemd-journald becomes too slow or otherwise unhealthy. Being able to bypass it and write directly to files would make things more reliable and simpler for a lot of usecases.

@lucab

This comment has been minimized.

Copy link
Contributor

lucab commented Sep 19, 2016

I had a similar requirement for rkt (being able to separately redirect stdin/stdout/stderr) and I submitted #4179 for that. While it doesn't implement the direct write to file syntax suggested above, I think it provides an effective fix for the same usecase.

To demonstrate how it works, I setup a small playground at https://github.com/lucab/systemd-named-fd.

@lucaswerkmeister

This comment has been minimized.

Copy link
Member Author

lucaswerkmeister commented Sep 19, 2016

That’s a very interesting way to solve the problem, thanks! But does it actually support regular files without a helper program to, e. g., copy from a named pipe to disk?

@lucab

This comment has been minimized.

Copy link
Contributor

lucab commented Sep 19, 2016

Directly, probably not. As ListenFIFO= wants to create a fifo file and ListenSpecial= is not happy about regular files. But it may be possible via some workarounds (loop-mounting a file and using the device file) or by growing support for regular files in socket/other units.

@keszybz

This comment has been minimized.

Copy link
Member

keszybz commented Sep 23, 2016

There is no need to worry about unprivileged users writing unit files: the security model of systemd requires that only privileged users are allowed to write/start/stop units, so option 2. (always allow opening the file) seems best. In particular this would open the interesting use case of giving access to a file which would otherwise be inacessible to the process.

@towolf

This comment has been minimized.

Copy link

towolf commented Sep 28, 2016

poettering added a commit to poettering/systemd that referenced this issue Oct 27, 2017

core: add support for StandardInputFile= and friends
These new settings permit specifiying arbitrary paths as
stdin/stdout/stderr locations. We try to open/create them as necessary.
Some special magic is applied:

1) if the same path is specified for both input and output/stderr, we'll
   open it only once O_RDWR, and duplicate them fd instead.

2) If we an AF_UNIX socket path is specified, we'll connect() to it,
   rather than open() it. This allows invoking systemd services with
   stdin/stdout/stderr connected to arbitrary foreign service sockets.

Fixes: systemd#3991
@poettering

This comment has been minimized.

Copy link
Member

poettering commented Oct 27, 2017

PR #7198 implements this and is waiting for reviewers!

poettering added a commit to poettering/systemd that referenced this issue Nov 10, 2017

core: add support for StandardInputFile= and friends
These new settings permit specifiying arbitrary paths as
stdin/stdout/stderr locations. We try to open/create them as necessary.
Some special magic is applied:

1) if the same path is specified for both input and output/stderr, we'll
   open it only once O_RDWR, and duplicate them fd instead.

2) If we an AF_UNIX socket path is specified, we'll connect() to it,
   rather than open() it. This allows invoking systemd services with
   stdin/stdout/stderr connected to arbitrary foreign service sockets.

Fixes: systemd#3991

poettering added a commit to poettering/systemd that referenced this issue Nov 13, 2017

core: add support for StandardInputFile= and friends
These new settings permit specifiying arbitrary paths as
stdin/stdout/stderr locations. We try to open/create them as necessary.
Some special magic is applied:

1) if the same path is specified for both input and output/stderr, we'll
   open it only once O_RDWR, and duplicate them fd instead.

2) If we an AF_UNIX socket path is specified, we'll connect() to it,
   rather than open() it. This allows invoking systemd services with
   stdin/stdout/stderr connected to arbitrary foreign service sockets.

Fixes: systemd#3991

poettering added a commit to poettering/systemd that referenced this issue Nov 13, 2017

core: add support for StandardInputFile= and friends
These new settings permit specifiying arbitrary paths as
stdin/stdout/stderr locations. We try to open/create them as necessary.
Some special magic is applied:

1) if the same path is specified for both input and output/stderr, we'll
   open it only once O_RDWR, and duplicate them fd instead.

2) If we an AF_UNIX socket path is specified, we'll connect() to it,
   rather than open() it. This allows invoking systemd services with
   stdin/stdout/stderr connected to arbitrary foreign service sockets.

Fixes: systemd#3991

poettering added a commit to poettering/systemd that referenced this issue Nov 14, 2017

core: add support for StandardInputFile= and friends
These new settings permit specifiying arbitrary paths as
stdin/stdout/stderr locations. We try to open/create them as necessary.
Some special magic is applied:

1) if the same path is specified for both input and output/stderr, we'll
   open it only once O_RDWR, and duplicate them fd instead.

2) If we an AF_UNIX socket path is specified, we'll connect() to it,
   rather than open() it. This allows invoking systemd services with
   stdin/stdout/stderr connected to arbitrary foreign service sockets.

Fixes: systemd#3991

poettering added a commit to poettering/systemd that referenced this issue Nov 15, 2017

core: add support for StandardInputFile= and friends
These new settings permit specifiying arbitrary paths as
stdin/stdout/stderr locations. We try to open/create them as necessary.
Some special magic is applied:

1) if the same path is specified for both input and output/stderr, we'll
   open it only once O_RDWR, and duplicate them fd instead.

2) If we an AF_UNIX socket path is specified, we'll connect() to it,
   rather than open() it. This allows invoking systemd services with
   stdin/stdout/stderr connected to arbitrary foreign service sockets.

Fixes: systemd#3991

poettering added a commit to poettering/systemd that referenced this issue Nov 15, 2017

core: add support for StandardInputFile= and friends
These new settings permit specifiying arbitrary paths as
stdin/stdout/stderr locations. We try to open/create them as necessary.
Some special magic is applied:

1) if the same path is specified for both input and output/stderr, we'll
   open it only once O_RDWR, and duplicate them fd instead.

2) If we an AF_UNIX socket path is specified, we'll connect() to it,
   rather than open() it. This allows invoking systemd services with
   stdin/stdout/stderr connected to arbitrary foreign service sockets.

Fixes: systemd#3991

poettering added a commit to poettering/systemd that referenced this issue Nov 16, 2017

core: add support for StandardInputFile= and friends
These new settings permit specifiying arbitrary paths as
stdin/stdout/stderr locations. We try to open/create them as necessary.
Some special magic is applied:

1) if the same path is specified for both input and output/stderr, we'll
   open it only once O_RDWR, and duplicate them fd instead.

2) If we an AF_UNIX socket path is specified, we'll connect() to it,
   rather than open() it. This allows invoking systemd services with
   stdin/stdout/stderr connected to arbitrary foreign service sockets.

Fixes: systemd#3991

poettering added a commit to poettering/systemd that referenced this issue Nov 16, 2017

core: add support for StandardInputFile= and friends
These new settings permit specifiying arbitrary paths as
stdin/stdout/stderr locations. We try to open/create them as necessary.
Some special magic is applied:

1) if the same path is specified for both input and output/stderr, we'll
   open it only once O_RDWR, and duplicate them fd instead.

2) If we an AF_UNIX socket path is specified, we'll connect() to it,
   rather than open() it. This allows invoking systemd services with
   stdin/stdout/stderr connected to arbitrary foreign service sockets.

Fixes: systemd#3991

poettering added a commit to poettering/systemd that referenced this issue Nov 16, 2017

core: add support for StandardInputFile= and friends
These new settings permit specifiying arbitrary paths as
stdin/stdout/stderr locations. We try to open/create them as necessary.
Some special magic is applied:

1) if the same path is specified for both input and output/stderr, we'll
   open it only once O_RDWR, and duplicate them fd instead.

2) If we an AF_UNIX socket path is specified, we'll connect() to it,
   rather than open() it. This allows invoking systemd services with
   stdin/stdout/stderr connected to arbitrary foreign service sockets.

Fixes: systemd#3991

poettering added a commit to poettering/systemd that referenced this issue Nov 17, 2017

core: add support for StandardInputFile= and friends
These new settings permit specifiying arbitrary paths as
stdin/stdout/stderr locations. We try to open/create them as necessary.
Some special magic is applied:

1) if the same path is specified for both input and output/stderr, we'll
   open it only once O_RDWR, and duplicate them fd instead.

2) If we an AF_UNIX socket path is specified, we'll connect() to it,
   rather than open() it. This allows invoking systemd services with
   stdin/stdout/stderr connected to arbitrary foreign service sockets.

Fixes: systemd#3991

poettering added a commit to poettering/systemd that referenced this issue Nov 17, 2017

core: add support for StandardInputFile= and friends
These new settings permit specifiying arbitrary paths as
stdin/stdout/stderr locations. We try to open/create them as necessary.
Some special magic is applied:

1) if the same path is specified for both input and output/stderr, we'll
   open it only once O_RDWR, and duplicate them fd instead.

2) If we an AF_UNIX socket path is specified, we'll connect() to it,
   rather than open() it. This allows invoking systemd services with
   stdin/stdout/stderr connected to arbitrary foreign service sockets.

Fixes: systemd#3991
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment