systemd: allow user environment helpers to communicate with systemd --user

"systemd --user" spawns programs from
/usr/lib/systemd/user-environment-generators/ in order to gather
environment variables. On a Debian 10 virtual machine which gnupg, this
directory contains:

    $ ls -Z /usr/lib/systemd/user-environment-generators
    system_u:object_r:bin_t 30-systemd-environment-d-generator
    system_u:object_r:bin_t 90gpg-agent

For sysadm, these programs are run as sysadm_t (because there is a
transition in systemd_role_template() in systemd.if:
corecmd_bin_domtrans($1_systemd_t, $3)) but use file descriptors created
by their parent process, which runs as sysadm_systemd_t. This leads to:

    type=AVC msg=audit(1569756917.537:244): avc:  denied  { use } for
    pid=9713 comm="30-systemd-envi"
    path=2F6D656D66643A33302D73797374656D642D656E7669726F6E6D656E742D642D67656E657261746F72202864656C6574656429
    dev="tmpfs" ino=24859 scontext=sysadm_u:sysadm_r:sysadm_t
    tcontext=sysadm_u:sysadm_r:sysadm_systemd_t tclass=fd permissive=0

    type=AVC msg=audit(1569756917.537:244): avc:  denied  { use } for
    pid=9713 comm="30-systemd-envi"
    path="/usr/lib/systemd/user-environment-generators/30-systemd-environment-d-generator"
    dev="vda1" ino=655822 scontext=sysadm_u:sysadm_r:sysadm_t
    tcontext=sysadm_u:sysadm_r:sysadm_systemd_t tclass=fd permissive=0

    type=SYSCALL msg=audit(1569756917.537:244): arch=c000003e syscall=59
    success=no exit=-13 a0=5647d12cf020 a1=7ffc605b1fb0 a2=7ffc605b2420
    a3=0 items=0 ppid=9712 pid=9713 auid=1000 uid=1000 gid=1000
    euid=1000 suid=1000 fsuid=1000 egid=1000 sgid=1000 fsgid=1000
    tty=(none) ses=10 comm="30-systemd-envi"
    exe="/usr/lib/systemd/user-environment-generators/30-systemd-environment-d-generator"
    subj=sysadm_u:sysadm_r:sysadm_t key=(null)

    [...]

    type=AVC msg=audit(1569756917.541:246): avc:  denied  { use } for
    pid=9714 comm="90gpg-agent"
    path=2F6D656D66643A39306770672D6167656E74202864656C6574656429
    dev="tmpfs" ino=24860 scontext=sysadm_u:sysadm_r:sysadm_t
    tcontext=sysadm_u:sysadm_r:sysadm_systemd_t tclass=fd permissive=0

    type=AVC msg=audit(1569756917.541:246): avc:  denied  { use } for
    pid=9714 comm="90gpg-agent" path="/usr/bin/bash" dev="vda1"
    ino=524662 scontext=sysadm_u:sysadm_r:sysadm_t
    tcontext=sysadm_u:sysadm_r:sysadm_systemd_t tclass=fd permissive=0

In systemd's source, here are the relevant functions:

* manager_run_environment_generators() calls execute_directories(paths,
  DEFAULT_TIMEOUT_USEC, gather_environment, ...) [1], with
  gather_environment a global table defined in exec-util.c [2]

* execute_directories() opens a "serialization fd" [3], that creates a
  memfd for communication with the child processes [4].

* execute_directories() calls fork() and do_execute() [5] in order to
  run each child process, providing them with the memfd descriptor in
  order to gather their output.

* When a child process is executed, its context transitions from
  sysadm_systemd_t to sysadm_t. The child then writes environment
  variables to its output.

* The parent process (systemd --user) collects the environment variables
  that have been written, and "consumes" the produced output in order to
  override its environment variables.

[1] https://github.com/systemd/systemd/blob/v243/src/core/manager.c#L3836
[2] https://github.com/systemd/systemd/blob/v243/src/shared/exec-util.c#L413
[3] https://github.com/systemd/systemd/blob/v243/src/shared/exec-util.c#L213
[4] https://github.com/systemd/systemd/blob/v243/src/shared/serialize.c#L200
[5] https://github.com/systemd/systemd/blob/v243/src/shared/exec-util.c#L226

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
This commit is contained in:
Nicolas Iooss 2019-09-30 22:43:31 +02:00
parent 4f1346357a
commit ea816582f0
No known key found for this signature in database
GPG Key ID: C191415F340DAAA0
1 changed files with 3 additions and 0 deletions

View File

@ -55,6 +55,9 @@ template(`systemd_role_template',`
allow $1_systemd_t $3:process { setsched rlimitinh }; allow $1_systemd_t $3:process { setsched rlimitinh };
corecmd_shell_domtrans($1_systemd_t, $3) corecmd_shell_domtrans($1_systemd_t, $3)
corecmd_bin_domtrans($1_systemd_t, $3) corecmd_bin_domtrans($1_systemd_t, $3)
# Allow using file descriptors for user environment generators
allow $3 $1_systemd_t:fd use;
') ')
###################################### ######################################