Bugzilla – Bug 1217783
VUL-0: pcp: pmie_farm_check.service and pmlogger_farm_check.service use unsafe tmp directories
Last modified: 2024-07-12 13:53:08 UTC
During our weekly systemd service change review for openSUSE:Factory the following pcp entries popped up: > 4 new services detected > ======================= > > RPM: pcp-5.3.7-1.1.x86_64.rpm on x86_64 > Package: pcp > Service path: /usr/lib/systemd/system/pmie_farm.service > Runs as: pcp:pcp > Exec lines: > ExecStart=/usr/libexec/pcp/bin/pmie_farm $PMIE_CHECK_PARAMS > > RPM: pcp-5.3.7-1.1.x86_64.rpm on x86_64 > Package: pcp > Service path: /usr/lib/systemd/system/pmie_farm_check.service > Runs as: root:root > Exec lines: > ExecStart=/usr/bin/pmiectl -m check > > RPM: pcp-5.3.7-1.1.x86_64.rpm on x86_64 > Package: pcp > Service path: /usr/lib/systemd/system/pmlogger_farm.service > Runs as: pcp:pcp > Exec lines: > ExecStart=/usr/libexec/pcp/bin/pmlogger_farm $PMLOGGER_CHECK_PARAMS > > RPM: pcp-5.3.7-1.1.x86_64.rpm on x86_64 > Package: pcp > Service path: /usr/lib/systemd/system/pmlogger_farm_check.service > Runs as: root:root > Exec lines: > ExecStart=/usr/bin/pmlogctl -m check What sticks out is that two services run as root, while two run as pcp:pcp. In the service file for pmie_farm_check.service it is stated that running it as root is intended. A first look into the code shows the following: These are all bash scripts that are hard to get into - as usual for large bash projects. PCP_TMPFILE_DIR is drwxrwxr-x 8 pcp pcp 4.0K Dez 4 15:40 /var/lib/pcp/tmp The pmiectl script uses `mkdtemp -d` to create a safe sub-directory in there. /var/lib/pcp is controlled by root only. The safely created tmp dir can be removed by pcp:pcp and then replaced by a pcp controlled directory full with all local attack vectors that are involved in such cases. Symlink protection won't trigger, because there is no sticky bit. Possible attack vectors: - DoS via $tmp/usage and many other files places there. - Integrity violation by changing one of many files that are stored in $tmp/ for scratch results - Not unlinkely a full root exploit by: - overwriting system files with partly or fully attacker controlled data - tricking the script into executing attacker controlled data stored in $tmp/ So this more or less completely breaks the isolation between pcp:pcp and root. We found issues in this package a couple of years ago in bug 1171883 already. The `pmlogctl` luckily is the same as `pmiectl`, they're symlinked. This needs closer investigation and involving upstream.
I'll look into this more closely. I already checked Fedora and Debian and both package /var/lib/pcp as root:root and /var/lib/pcp/tmp as pcp:pcp as well. So we're not deviating here. The systemd tmpfiles configuration file lists 809 paths to be created. This is certainly over the top and not a healthy state anymore. I will now a bit closer into the bash scripts and the exploitability of the issue.
Okay the full local root exploit from `pcp` to `root is already here. I looked in `pmcd.service` which also runs as root and executes the bash script /usr/libexec/pcp/lib/pmcd. This has as part of its start routine in `_reboot_setup()`: ``` if [ ! -d "$PCP_TMP_DIR/pmlogger" ] then mkdir -p -m 775 "$PCP_TMP_DIR/pmlogger" chown $PCP_USER:$PCP_GROUP "$PCP_TMP_DIR/pmlogger" if which restorecon >/dev/null 2>&1 then restorecon -r "$PCP_TMP_DIR" fi else ``` Remember, PCP_TMP_DIR = "/var/lib/pcp/tmp", owned by pcp:pcp Since the code does not exit on errors we don't even need to bother to win a race condition. The following exploit works: ``` root # sudo -u pcp -g pcp bash pcp $ cd /var/lib/pcp/tmp pcp $ rm -r pmlogger pcp $ ln -s /etc/shadow pmlogger root # systemctl start pcmd.service root # ls -l /etc/shadow -rw-r----- 1 pcp pcp 1.2K Dec 7 15:47 /etc/shadow ``` The issue with this pcp user are pretty vast and upstream needs to work over this. I will contact them.
adding IBS maintainer also to this bug
Internal CRD: 2024-03-07
Upstream has already released version 6.1.1 while we are still with version 5.3.7 in Factory. This vulnerability is still found in the current upstream sources, though.
I just sent a detailed email about this issue and bug 1217826 to the upstream maintainers, offering coordinated disclosure. I will post any further developments here.
Please refer to bug 1217826 comment 10 for an update about the disclosure process for these two findings.
Making the bug public, upstream already published the fixes in https://github.com/performancecopilot/pcp/pull/1873, embargo has been over since 2024-02-15.