Bug 1727895 - systemd user instance crashes for SELinux restricted accounts
Summary: systemd user instance crashes for SELinux restricted accounts
Keywords:
Status: CLOSED EOL
Alias: None
Product: Fedora
Classification: Fedora
Component: selinux-policy
Version: 33
Hardware: Unspecified
OS: Unspecified
low
low
Target Milestone: ---
Assignee: Zdenek Pytela
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks: 1767779
TreeView+ depends on / blocked
 
Reported: 2019-07-08 13:08 UTC by Martin Pitt
Modified: 2021-11-30 16:24 UTC (History)
13 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2021-11-30 16:24:45 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)

Description Martin Pitt 2019-07-08 13:08:56 UTC
Description of problem: The systemd user instance does not start up for users who are other than unconfined_u. That by itself is largely an SELinux policy behaviour (see bug 1727887; I'm not sure yet whether it's intended or a bug), but systemd unceremoniously segfaults in that case, which isn't good.


Version-Release number of selected component (if applicable):

systemd-241-8.git9ef65cb.fc30.x86_64
selinux-policy-3.14.3-39.fc30.noarch


How reproducible: Always

Steps to Reproduce:
1. Create a new user: useradd unpriv; echo 'unpriv:foobar' | chpasswd
2. Change it away from unconfined_u: semanage login -a -s guest_u unpriv
3. log in as that user with ssh: ssh unpriv@localhost
4. check systemd user instance: /usr/bin/systemctl --user status

Actual results:

audit: type=1103 audit(1562590891.865:322): pid=7511 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:sshd_t:s0-s0:c0.c1023 msg='op=PAM:setcred grantors=pam_unix acct="unpriv" exe="/usr/sbin/sshd" hostname=::1 addr=::1 terminal=ssh res=success'
New session 5 of user unpriv.
Created slice User Slice of UID 1002.
audit: type=1006 audit(1562590891.865:323): pid=7511 uid=0 subj=system_u:system_r:sshd_t:s0-s0:c0.c1023 old-auid=4294967295 auid=1002 tty=(none) old-ses=4294967295 ses=5 res=1
Starting User Runtime Directory /run/user/1002...
[...]
pam_unix(systemd-user:session): session opened for user unpriv by (uid=0)
user: Main process exited, code=killed, status=11/SEGV
user: Failed with result 'protocol'.

There is no coredump (coredumpctl is empty), so maybe this just looks like a segfault, but it's actually reasonably well defined. 

Expected results: Handle this more gracefully,  perhaps with a non-zero exit code or an assertion failure (SIGABRT).


Additional info: The crash does not happen on RHEL 8.1 with systemd-239-15.el8.x86_64.

Comment 1 Zbigniew Jędrzejewski-Szmek 2020-03-04 11:31:55 UTC
I can see this happening, but after trying to debug this, I can't figure out what is going on.
no avcs are reported, either in permissive mode (where this works) or in enforcing mode
(where it doesn't work), disabling dontaudit doesn't help, strace doesn't work (no output).

Some notes:
with the defaults:
$ systemctl start user@1002
Job for user failed because the control process exited with error code.
See "systemctl status user" and "journalctl -xe" for details.

This "control process exited" is because we have ExecStart=- in the unit file. This
seems to be a leftover, the minus should be dropped.

without the minus:
$ systemctl start user@1002
Job for user failed because a fatal signal was delivered to the control process.
See "systemctl status user" and "journalctl -xe" for details.

After a few reloads of the policy selinux seems to have gotten into a twist and
even journald has stopped working... No idea what is going on here. I'm not even sure
if the reported SEGV is a valid or just a bogus error.

Comment 2 Zbigniew Jędrzejewski-Szmek 2020-03-04 21:50:10 UTC
msekletar reports:
[pid  2408] execve("/usr/lib/systemd/systemd", ["/usr/lib/systemd/systemd", "--user"], 0x559820cc20e0 /* 10 vars */) = -1 EACCES (Permission denied)
[pid  2408] --- SIGSEGV {si_signo=SIGSEGV, si_code=SI_KERNEL, si_addr=NULL} ---

Comment 3 Ondrej Mosnacek 2020-03-05 09:39:21 UTC
After disabling dontaudit rules with "semodule -DB" and doing the so-called "full auditing" hack (auditctl -D; auditctl -w /etc/shadow -p w), I got this record:

type=PROCTITLE msg=audit(03/04/2020 11:04:23.720:427) : proctitle=(systemd) 
type=PATH msg=audit(03/04/2020 11:04:23.720:427) : item=1 name=/lib64/ld-linux-x86-64.so.2 inode=137635 dev=fc:01 mode=file,755 ouid=root ogid=root rdev=00:00 obj=system_u:object_r:ld_so_t:s0 nametype=NORMAL cap_fp=none cap_fi=none cap_fe=0 cap_fver=0 cap_frootid=0 
type=PATH msg=audit(03/04/2020 11:04:23.720:427) : item=0 name=/usr/lib/systemd/systemd inode=147457 dev=fc:01 mode=file,755 ouid=root ogid=root rdev=00:00 obj=system_u:object_r:init_exec_t:s0 nametype=NORMAL cap_fp=none cap_fi=none cap_fe=0 cap_fver=0 cap_frootid=0 
type=CWD msg=audit(03/04/2020 11:04:23.720:427) : cwd=/ 
type=SYSCALL msg=audit(03/04/2020 11:04:23.720:427) : arch=x86_64 syscall=execve success=no exit=EACCES(Permission denied) a0=0x55cfa0beebe0 a1=0x55cfa0b153b0 a2=0x55cfa0c4b940 a3=0x7fe882b91deb items=2 ppid=1 pid=2168 auid=unpriv uid=unpriv gid=unpriv euid=unpriv suid=unpriv fsuid=unpriv egid=unpriv sgid=unpriv fsgid=unpriv tty=(none) ses=7 comm=systemd exe=/usr/lib/systemd/systemd subj=guest_u:guest_r:guest_t:s0 key=(null) 
type=AVC msg=audit(03/04/2020 11:04:23.720:427) : avc:  denied  { map } for  pid=2168 comm=systemd path=/usr/lib/systemd/systemd dev="vda1" ino=147457 scontext=guest_u:guest_r:guest_t:s0 tcontext=system_u:object_r:init_exec_t:s0 tclass=file permissive=0 
type=AVC msg=audit(03/04/2020 11:04:23.720:427) : avc:  denied  { siginh } for  pid=2168 comm=systemd scontext=system_u:system_r:init_t:s0 tcontext=guest_u:guest_r:guest_t:s0 tclass=process permissive=0 
type=AVC msg=audit(03/04/2020 11:04:23.720:427) : avc:  denied  { read write } for  pid=2168 comm=systemd path=socket:[29910] dev="sockfs" ino=29910 scontext=guest_u:guest_r:guest_t:s0 tcontext=system_u:system_r:init_t:s0 tclass=unix_stream_socket permissive=0 
type=AVC msg=audit(03/04/2020 11:04:23.720:427) : avc:  denied  { read write } for  pid=2168 comm=systemd path=socket:[29910] dev="sockfs" ino=29910 scontext=guest_u:guest_r:guest_t:s0 tcontext=system_u:system_r:init_t:s0 tclass=unix_stream_socket permissive=0 

The relevant denial here is the "denied  { map }", which represents the denial to map the systemd binary for the new process. This eventually leads to the error path at [1], which kills the process with SIGSEGV. This is contrary to the execve(2) documentation, which says it would be killed by SIGKILL. This was the case until kernel 3.18 [2], where the various error paths with SIGKILL/SIGSEGV were consolidated into just SIGSEGV (why not SIGKILL? IDK, ask Al Viro...).

I'm not going to make judgement whether the code is wrong or the documentation, but this is what is happening. I recommend reporting this to linux-fsdevel.org (with Al Viro <viro.org.uk> in Cc) if you believe this is a kernel bug.

Either way, selinux-policy should be updated to allow guest_t to map systemd_systemctl_exec_t files. On RHEL-8 the file map permission is allowed by default due to the domain_can_mmap_files boolean, so it doesn't happen there.

[1] https://elixir.bootlin.com/linux/v5.6-rc4/source/fs/exec.c#L1670
[2] https://github.com/torvalds/linux/commit/19d860a140beac48a1377f179e693abe86a9dac9

Comment 4 Zbigniew Jędrzejewski-Szmek 2020-03-05 16:10:38 UTC
(In reply to Ondrej Mosnacek 🌽 from comment #3)
> The relevant denial here is the "denied  { map }", which represents the
> denial to map the systemd binary for the new process. This eventually leads
> to the error path at [1], which kills the process with SIGSEGV. This is
> contrary to the execve(2) documentation, which says it would be killed by
> SIGKILL.

I don't think we care that much. SEGV is misleading, that's all.

> Either way, selinux-policy should be updated to allow guest_t to map
> systemd_systemctl_exec_t files. On RHEL-8 the file map permission is allowed
> by default due to the domain_can_mmap_files boolean, so it doesn't happen
> there.

Ack. I'll reassign to selinux-policy then.

Comment 5 Zdenek Pytela 2020-03-09 17:06:48 UTC
FYI this is the current state in F31:

  # sesearch -A -t init_exec_t -c file -p map|grep -w -e user_t -e staff_t -e sysadm_t -e root -e unconfined_t -e guest_u -e xguest_u
allow staff_t init_exec_t:file { execute execute_no_trans getattr ioctl map open read };
allow sysadm_t init_exec_t:file { execute execute_no_trans getattr ioctl lock map open read };
allow unconfined_t init_exec_t:file { execute execute_no_trans getattr ioctl lock map open read };
allow user_t init_exec_t:file { execute execute_no_trans getattr ioctl map open read };

and F32:
  # sesearch -A -t init_exec_t -c file -p map|grep -w -e user_t -e staff_t -e sysadm_t -e root -e unconfined_t -e guest_u -e xguest_u
allow staff_t init_exec_t:file { execute execute_no_trans getattr ioctl map open read };
allow sysadm_t init_exec_t:file { execute execute_no_trans map };
allow user_t init_exec_t:file { execute execute_no_trans getattr ioctl map open read };

Comment 6 Ben Cotton 2020-08-11 15:35:51 UTC
This bug appears to have been reported against 'rawhide' during the Fedora 33 development cycle.
Changing version to 33.

Comment 7 Ben Cotton 2021-11-04 17:31:57 UTC
This message is a reminder that Fedora 33 is nearing its end of life.
Fedora will stop maintaining and issuing updates for Fedora 33 on 2021-11-30.
It is Fedora's policy to close all bug reports from releases that are no longer
maintained. At that time this bug will be closed as EOL if it remains open with a
Fedora 'version' of '33'.

Package Maintainer: If you wish for this bug to remain open because you
plan to fix it in a currently maintained version, simply change the 'version' 
to a later Fedora version.

Thank you for reporting this issue and we are sorry that we were not 
able to fix it before Fedora 33 is end of life. If you would still like 
to see this bug fixed and are able to reproduce it against a later version 
of Fedora, you are encouraged  change the 'version' to a later Fedora 
version prior this bug is closed as described in the policy above.

Although we aim to fix as many bugs as possible during every release's 
lifetime, sometimes those efforts are overtaken by events. Often a 
more recent Fedora release includes newer upstream software that fixes 
bugs or makes them obsolete.

Comment 8 Ben Cotton 2021-11-30 16:24:45 UTC
Fedora 33 changed to end-of-life (EOL) status on 2021-11-30. Fedora 33 is
no longer maintained, which means that it will not receive any further
security or bug fix updates. As a result we are closing this bug.

If you can reproduce this bug against a currently maintained version of
Fedora please feel free to reopen this bug against that version. If you
are unable to reopen this bug, please file a new report against the
current release. If you experience problems, please add a comment to this
bug.

Thank you for reporting this bug and we are sorry it could not be fixed.


Note You need to log in before you can comment on or make changes to this bug.