
Pack2TheRoot (CVE-2026-41651) — a local privilege escalation in Linux systems through a TOCTOU vulnerability in the PackageKit service. This service provides a unified interface for installing and removing packages via D-Bus and acts as a layer between user applications and the distribution’s package manager (APT, RPM, etc.). All operations are performed by the privileged packagekitd service as root.
To interact with PackageKit, the exploit uses the D-Bus API of the GLib library, specifically the InstallFiles() method, which is intended for installing local deb/rpm packages. The method takes a set of transaction flags that determine its behavior. Some flags are considered safe and can be used without full authorization. For example, the simulate flag only performs dependency checks and does not lead to actual software installation.
The vulnerability is related to the processing of an already created transaction. After the initial security check, PackageKit marks the transaction as safe, but when the transaction parameters are later changed, the security check is not repeated. This creates a TOCTOU condition: a transaction created with the simulate flag can be changed to a full package installation with the none flag, while PackageKit considers the authorization to have already been passed.
The PoC creates two local packages: a dummy package and a payload package. The first is used to pass the security check in simulate mode. The second contains a postinst payload that is executed in the context of packagekitd. In the published PoC, the command
install -m 4755 /bin/bash /tmp/.suid_bashis used, which creates a SUID copy of bash. After that, the attacker can gain root access by running bash with the -p argument.
To exploit the vulnerability, two transactions need to be created through g_dbus_connection_call(). The first calls InstallFiles() for the dummy package with simulate flag: g_variant_new("(u^as)", 4, ...). The second immediately reuses the same transaction object, replacing the package with the payload and setting the flag for full installation: g_variant_new("(u^as)", 0, ...). After calling g_dbus_connection_flush_sync(), both operations are almost simultaneously added to the processing queue.
As a result, PackageKit installs the second package as root, despite the fact that authorization was only obtained for a safe operation. The backend package manager (dpkg/rpm) runs the postinst/preinst scripts of the payload package with root privileges.
On Debian/Ubuntu, this looks like:
/bin/sh /var/lib/dpkg/info/<package>.postinst configureOn RPM systems:
/bin/sh /var/tmp/rpm-tmp.*Post-exploitation depends on the contents of the installation script. It could be creating a SUID shell, modifications to /etc/shadow, adding SSH keys, creating systemd unit files, modifying PAM configurations, and other mechanisms for persistence.
How to protect yourself:
If it’s not possible to update PackageKit to a patched version, detect the attack by monitoring PackageKit/GLib API calls or the process chain of the package manager.
For Debian-based systems, an indicator can be the execution of postinst/preinst scripts from /var/lib/dpkg/info/ followed by a call to chmod or install that sets the SUID/SGID bits.
For RPM-based systems, a similar indicator is the execution of temporary scripts /var/tmp/rpm-tmp.*.
It’s also useful to monitor the initiators of package manager calls. Suspicious activity may be the execution of dpkg-deb and rpmbuild processes not through standard package management tools (apt, apt-get, dpkg, rpm, dnf, yum, zypper, mock, koji).
Additional IoC can be PackageKit log entries about failed authentication, which occur during the exploitation of the vulnerability:
May 23 13:00:00 hostname PackageKit[PID]: uid 1000 is trying to obtain org.freedesktop.packagekit.package-install-untrusted auth (only_trusted:0)
May 23 13:00:01 hostname PackageKit[PID]: uid 1000 failed to obtain auth
