oss-sec mailing list archives

Re: Local information disclosure in apport and systemd-coredump


From: Solar Designer <solar () openwall com>
Date: Thu, 5 Jun 2025 02:32:36 +0200

On Wed, Jun 04, 2025 at 09:52:43AM +0200, David Fernandez Gonzalez wrote:
I think I implemented most of what Qualys described (of the parts
relevant to systemd-coredump rather than only to apport), except that I
simply use fork() rather than clone() (slower PID reuse) and I didn't
implement usage of inotify (harder to win the race leading to password
hashes in dump).  I've been testing this after:

sysctl kernel.pid_max=2000
control unix_chkpwd public # Undo SIG/Security hardening

With the PID range reduced from the default of 4M down to 2K, PID reuse
is quick even with simple fork().  I am getting frequent unix_chkpwd
coredumps (without password hashes in them, which is as expected without
inotify), but none of them are getting ACLs set for read by the user
(unexpected - I thought I'd win this easier race once in a while), e.g.:

The POC looks good to me overall but the issue is that the replacement 
is not really happening while the dump is being generated.

Since the signal from the SUID process is not handled when it exits, it 
will remain defunct for too long. Either SIG_IGN or waitpid for the 
signal right after SIGKILL. Then you need to spawn the extra processes 
to replace the PID "fast enough". fork is too slow for this I think, you 
may need to use clone as Qualys mentioned, for me it always works with 
clone. After that, it should work!

Good point, but this wasn't the issue.  A wait() was reached before the
replacement PID would have been reached by the loop anyway.

Rather, as Qualys pointed out to me off-list, the biggest issue was that
I had the replacement process exit immediately.  I had copy-pasted this
from the first into the second loop and didn't re-think it through.

Simply fixing this (and tuning a few other things while at it) made the
attack work on Rocky Linux 9.5, but I do still have to lower
kernel.pid_max as above (or even lower) to have it succeed quickly.

I've attached the revised files.  As written, the script will stop when
it sees a constant string that's part of unix_chkpwd in the core dump.
I've also tried editing and running it until it finds password hashes,
which it actually did quite a few times as well (that's even without any
inotify magic suggested by Qualys).  Always the user's, but often also
other users' and root's.

Somehow in my testing the core dumps after winning the race only appear
when the target PID is low, in the ~300 to ~425 range.  I tried this on
two different systems (one bare metal and one VM) and observed this same
behavior.  I don't know why.  Also changes to kernel.pid_max and to CPU
affinity didn't affect this lucky range in my experiments.

Anyway, this is good enough now as a non-weaponized PoC to confirm that
the vulnerability is indeed present on RHEL 9.5 rebuilds and to confirm
that its mitigations or fixes make a difference.

Alexander

Attachment: CVE-2025-4598.c
Description:

Attachment: CVE-2025-4598.sh
Description:


Current thread: