Fedora Account System
Red Hat Associate
Red Hat Customer
AI_ONLY_REPORT package: mrtg-2.17.10-12.el10 ------ Summary: Symlink-based arbitrary file clobber/chown via --pid-file when run as root in daemon mode: MRTG creates and `chown`s the PID file before dropping privileges, allowing an attacker who can influence or pre-place the PID path to make root follow a symlink and transfer ownership of an arbitrary existing file to the daemon user; the accompanying `create_pid()` logic also carries limited TOCTOU / non-existent-target clobber risk. Requirements to exploit: The attacker needs local low-privileged access on the target and a deployment where MRTG is started as root with `--daemon` and later drops privileges to another user. The attacker must be able to influence the PID file path, control the config-derived PID path, or pre-place a symlink at that path in a writable location before startup. This issue is not remotely reachable, and starts that already execute MRTG as an unprivileged user do not expose the root-side `chown` primitive. Component affected: MRTG daemon startup logic in `bin/mrtg.socket6` and `lib/mrtg2/MRTG_lib.pm` (the same pre-drop PID-file logic is also present in `bin/mrtg`) Version affected: 2.17.10-12.el10 (confirmed in the available source checkout). The full upstream introduction range is unknown from the available history; in the local clone, the pre-drop `create_pid()` + `chown` block is present from commit `2ca68627078a..HEAD`, while the unsafe `create_pid()` pattern is present from base commit `767bce1636bc..HEAD`. Patch available: no Version fixed (if any already): unknown Upstream coordination: Not yet notified. The source material includes a draft disclosure email to the MRTG maintainers. CVSS: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N - 7.1 (HIGH) AV:L - Local access to the affected host is required. AC:L - Once MRTG is started as root in an affected daemon deployment and the attacker can control or pre-place the PID path, exploitation is straightforward. PR:L - Low privileges are needed to control a writable PID path or plant the symlink in affected setups. UI:N - No additional user interaction is required after the vulnerable service start. S:U - The vulnerable code and impacted files are within the same operating-system security scope. C:H - Ownership takeover of a sensitive file can expose data that should remain root-only. I:H - Ownership takeover of a sensitive file can allow direct modification and privilege escalation. A:N - The primary demonstrated primitive is file ownership takeover; direct availability impact is secondary and configuration-dependent. Impact: Important. In affected root-start daemon deployments, this is a local privilege-escalation / file-ownership-takeover issue: a low-privileged local attacker who can influence or pre-place the PID file path can make root `chown` an arbitrary existing file to the daemon user before privileges are dropped. The issue is narrower than a generic local root exploit because it depends on root-started daemon mode and attacker control over the PID path, but the resulting confidentiality and integrity impact can still be high. Embargo: yes Reason: This is a plausible local privilege-escalation issue in a supported daemon-start path, and no upstream fix is known from the source material. Coordinated disclosure is preferable so PID-file handling can be corrected before publication. Acknowledgement: Aisle Research Steps to reproduce: 1. Prepare a root-owned target file and a symlinked PID path: ```bash sudo rm -f /tmp/mrtg.pid /tmp/owned_by_root sudo touch /tmp/owned_by_root sudo chown root:root /tmp/owned_by_root ln -s /tmp/owned_by_root /tmp/mrtg.pid ``` 2. Start MRTG as root in daemon mode, dropping privileges: ```bash sudo /usr/bin/mrtg --daemon --pid-file=/tmp/mrtg.pid --user=nobody /etc/mrtg/mrtg.cfg ``` 3. Verify ownership of the symlink target changed: ```bash ls -l /tmp/owned_by_root ``` 4. Expected result: the target file becomes owned by `nobody` (or the selected drop user/group), confirming that root followed the symlink during the pre-drop `chown`. Mitigation: Do not start MRTG as root with `--daemon` unless it is strictly necessary; prefer starting it directly as the intended service user. Do not place the PID file in attacker-writable locations and do not allow untrusted users to influence `--pid-file` or the config-derived PID path. Keep any PID-file directory root-owned and not writable by unprivileged users if root startup is unavoidable. Refuse symlinks for PID files and create them securely with `sysopen(..., O_WRONLY|O_CREAT|O_EXCL, 0644)` or equivalent. Prefer creating the PID file only after privileges have been dropped. Vulnerability details: ```perl bin/mrtg.socket6 if (defined $opts{"daemon"}) { Create a pidfile, then chown it so we can use it once we change user &create_pid($pidfile); chown $uid, $gid, $pidfile; } ($(,$)) = ($gid,$gid); ($<,$>) = ($uid,$uid); ``` ```perl lib/mrtg2/MRTG_lib.pm sub create_pid ($) { my $pidfile = shift; return if ($OS eq 'NT' ); return if -e $pidfile; if ( open(PIDFILE,">$pidfile")) { close PIDFILE; } } ``` The most reliable demonstrated primitive is symlink-following `chown` on an existing target file. The `create_pid()` `-e`/`open(">...")` sequence is still unsafe and introduces TOCTOU / non-existent-target clobber risk, but direct clobber of an already existing file is not the primary demonstrated behavior because of the `-e` guard. Most relevant CWEs: CWE-59: Improper Link Resolution Before File Access CWE-367: Time-of-check Time-of-use race condition Proposed fix: ```diff diff --git a/bin/mrtg.socket6 b/bin/mrtg.socket6 @@ if (defined $opts{"daemon"}) { # Create a pidfile, then chown it so we can use it once we change user &create_pid($pidfile); chown $uid, $gid, $pidfile; } + # Do not create/chown pidfile as root on user-influenced path. diff --git a/bin/mrtg b/bin/mrtg @@ if (defined $opts{"daemon"}) { # Create a pidfile, then chown it so we can use it once we change user &create_pid($pidfile); chown $uid, $gid, $pidfile; } + # Do not create/chown pidfile as root on user-influenced path. diff --git a/lib/mrtg2/MRTG_lib.pm b/lib/mrtg2/MRTG_lib.pm @@ +use Fcntl qw(O_WRONLY O_CREAT O_EXCL); @@ sub create_pid ($) { my $pidfile = shift; return if ($OS eq 'NT' ); return if -e $pidfile; if ( open(PIDFILE,">$pidfile")) { close PIDFILE; } else { warn "cannot write to $pidfile: $!\n"; } + if (lstat($pidfile)) { + die "Refusing symlink pid file: $pidfile\n" if -l _; + return; + } + sysopen(my $fh, $pidfile, O_WRONLY|O_CREAT|O_EXCL, 0644) + or die "cannot securely create pid file $pidfile: $!\n"; + close($fh) or die "cannot close pid file $pidfile: $!\n"; } ``` ------ This report was generated using AI technology. Always review AI-generated content prior to use
Tracker filed for rhel-10.3: https://issues.redhat.com/browse/RHEL-189242