systemd / systemd/systemd

systemctl status <unit> information leakage with selinux user_u compared to ps / systemctl status

Open
#11,061 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

needs-discussion 🤔 pid1 selinux
Dominant language
C
Stars
16.7k
Forks
4.7k
Avg merge
1d 6h
Merged PRs (30d)
140

Description

systemd version the issue has been seen with

systemd-239-6.git9f3aed1.fc29.x86_64

Used distribution

Fedora 29 x86_64

Expected behaviour you didn't see

I'm using selinux user user_u to limit access of the system. I don't see process command lines of most system processes or other users processes command line. Only my own. Output compared to ps -fe.

Unexpected behaviour you saw

I got full command lines of all processes.

Steps to reproduce the problem
You need to create user wiht user_u as selinux user. First create a new user normally, then run to setup user:

semanage login -a -s user_u -r s0 <newusername>
restorecon -RFv ~<newusername>

ssh @localhost

run ps like this

$ ps -fe
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 Dec04 ?        00:01:31 /usr/lib/systemd/systemd --switched-root --system --deserialize 33
root       893     1  0 Dec04 ?        00:00:00 /usr/sbin/abrtd -d -s
root      2155  2153  0 Dec04 ?        00:00:00 (sd-pam)
gdm       5179  5177  0 Dec04 ?        00:00:00 (sd-pam)
root      5300     1  0 Dec04 ?        00:00:02 /usr/sbin/abrt-dbus -t133
maage     6091  6087  0 Dec04 ?        00:00:00 (sd-pam)
markus    9308 14810  0 16:35 pts/1    00:00:00 ps -fe
markus   14803 14787  0 Dec04 ?        00:00:01 sshd: markus@pts/1
markus   14810 14803  0 Dec04 pts/1    00:00:00 -bash

You see very limited number of processes, same with top or find /proc.

When I run:

% systemctl status
   CGroup: /
           ├─    2 n/a
           ├─    3 n/a
...
           ├─32558 n/a
           ├─32700 n/a
           ├─user.slice
           │ ├─user-1973.slice
           │ │ └─session-304.scope
           │ │   ├─10104 systemctl status
           │ │   ├─10105 (pager) status
           │ │   ├─14787 n/a
           │ │   ├─14803 sshd: markus@pts/1
           │ │   └─14810 -bash
...
           │     └─25666 n/a
           ├─init.scope
           │ └─1 /usr/lib/systemd/systemd --switched-root --system --deserialize 33
           └─system.slice
             ├─rngd.service
             │ └─879 n/a
             ├─irqbalance.service
             │ └─846 n/a
             ├─abrt-journal-core.service
             │ └─925 n/a
...

Only my own processes still have visible command line.
But if I run:

$ systemctl status system.slice
...
   Memory: 139.6M
   CGroup: /system.slice
           ├─NetworkManager.service
           │ └─970 /usr/sbin/NetworkManager --no-daemon
           ├─abrt-journal-core.service
           │ └─925 /usr/bin/abrt-dump-journal-core -D -T -f -e
...

I get full command lines for all processes. And same to any other slice too.

I guess problem is as systemctl status uses local user and path is: show -> show_system_status -> show_cgroup -> show_cgroup_by_path -> show_cgroup_one_by_path -> show_pid_array -> get_process_cmdline -> procfs_file_alloca and it fails because missing permissions and we get n/a.
And show -> show_one -> bus_map_all_properties and it uses pid 1 permissions to get information about cgroups and obviously does get full information.

Curiously:

$ systemctl status user.slice
Failed to get properties: Access denied

But for gdm (uid 42) I get full list or processes:

$ systemctl status user-42.slice
● user-42.slice - User Slice of UID 42
   Loaded: loaded
  Drop-In: /usr/lib/systemd/system/user-.slice.d
           └─10-defaults.conf
   Active: active since Tue 2018-12-04 21:56:21 EET; 18h ago
     Docs: man:user@.service(5)
    Tasks: 129 (limit: 10813)
   Memory: 59.9M
   CGroup: /user.slice/user-42.slice
           ├─session-c220.scope
           │ ├─5211 gdm-session-worker [pam/gdm-launch-environment]
           │ ├─5219 /usr/libexec/gdm-x-session gnome-session --autostart /usr/share/gdm/greeter/autostart
...

Anyways in either case systemctl status and for a in <list-of-slices>;do systemctl status $a;done should provide about the same info.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the SELinux user_u case and compare systemctl status with systemctl status system.slice. Start with the mentioned path from show_system_status through show_cgroup_by_path and show_pid_array, then compare it with show_one and bus_map_all_properties. Done means status output follows the same access restrictions as ps and does not expose unauthorized command lines.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, linux
Domain
cli, operating-systems, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.