Pack2TheRoot: CVE-2026-41651 Turns Local Linux Access Into Root

A dormant TOCTOU race in PackageKit — the daemon almost every Linux distro ships — lets any local user poison a transaction and install a root-owned package with no password. It hid for 12 years, and a public exploit is already out.

Share
Minimalist white art on crimson showing a ladder with a dot at the base ascending into a solid circle, representing local privilege escalation from user to root.

The scariest Linux bugs are rarely the exotic ones. Pack2TheRoot (CVE-2026-41651) is a plain logic error that sat quietly in PackageKit — the software-install daemon almost every mainstream distribution ships and enables by default — for roughly twelve years. Any user who can reach a shell on the box can abuse it to install a root-owned package and take over the system, no password required. It was disclosed on April 22, 2026 by Telekom Security, and a working exploit was public within a day.

Rated CVSS 8.8 (High), it matters most on systems defenders treat as low-risk: shared desktop pools, jump hosts, CI runners, and multi-user servers where an attacker already has a limited foothold. On those boxes it is a clean, quiet path from ordinary user to root — and it works the same way across Ubuntu, Fedora, Debian, and Rocky Linux, because the bug lives in shared upstream code.

The mechanics are worth understanding, because the fix is more than a single package bump.

  ONE D-BUS CALL, FROM USER TO ROOT
How Pack2TheRoot races PackageKit’s state machine to install a root-owned package with no password.
UNPRIVILEGED FOOTHOLD
A local, low-privilege user (reverse shell, service account) can talk to the PackageKit daemon over D-Bus.
FLAG POISON (POLKIT SIDESTEP)
An InstallFiles() call sets attacker-chosen transaction flags — using the SIMULATE flag, which skips polkit — before authorization is ever checked.
GUARD FAILS TO REVERT
The daemon rejects the illegal state transition but leaves the corrupted cached_transaction_flags in place instead of restoring them.
ROOT ACHIEVED
The backend reads the poisoned flags, installs the attacker’s package, and runs its maintainer scriptlets as root.
Source: Telekom Security (Pack2TheRoot advisory); oss-security CVE-2026-41651.

A 12-Year Race Condition

At its heart, Pack2TheRoot is a time-of-check-to-time-of-use (TOCTOU) race in how PackageKit handles D-Bus transactions. According to the oss-security advisory, the daemon unconditionally overwrites its cached_transaction_flags on every InstallFiles() call, without first checking what state the transaction is in. An unprivileged caller supplies those flags — and they land in the cache before the daemon ever decides whether the request is authorized.

The daemon does have a guard: it knows a transaction should not move “backward” from running to waiting-for-authorization. But when it catches that illegal transition, it rejects the move and fails to revert the flags it already cached. By the time the backend schedules the real work, it reads the attacker-controlled flags and installs whatever package was pointed at it, running its maintainer scriptlets as root. Telekom's researchers made the race reliable by leaning on a GLib quirk — D-Bus messages are dispatched at a higher priority than idle callbacks — so the poison lands before execution nearly every time.

The Part the First Reports Understated: polkit

It is tempting to read this as a pure race condition, but the authorization layer is central. PackageKit gates privileged actions through polkit, and the exploit's opening move abuses a transaction flag — PK_TRANSACTION_FLAG_SIMULATE — that skips the polkit check entirely. That “simulate” call is what poisons the transaction state without ever prompting for a password. The publicly released proof-of-concept lab makes the dependency explicit: the reliable exploit path assumes a permissive polkit rule allowing local users to install packages, a configuration many desktop images ship by default.

That detail is good news for defenders who cannot patch immediately, because it means tightening polkit is a real interim mitigation — the lab ships a hardened ruleset that blocks the authentication-less install path even on an unpatched daemon.

Who Is Affected

The bug spans PackageKit 1.0.2 through 1.3.4 — every release since 2014 — and is fixed in 1.3.5 plus distribution backports. Telekom and the advisories confirm exposure across default installs of Ubuntu Desktop and Server (18.04 through the 26.04 line), Debian Trixie 13.4, Fedora 43 Desktop and Server, and Rocky Linux 10.1 Desktop. Because the defect is in upstream code rather than a vendor patch, the practical rule is simple: if a system runs PackageKit older than 1.3.5, assume it is exploitable.

My Read

Pack2TheRoot is a case study in how convenience becomes attack surface. PackageKit exists so a GUI can install software without every app shipping its own privileged helper — a sensible design that also means a root-capable daemon is listening on D-Bus on millions of desktops that will never open a software center. The bug survived twelve years precisely because it is logic, not memory corruption: there is no unsafe strcpy for a fuzzer or static analyzer to flag, just a state machine that trusts input a beat too early and forgets to clean up after itself. Those flaws are invisible to the tools most teams rely on.

The broader signal is that privileged userspace daemons reachable over D-Bus are now a first-class escalation target. Turning a legitimate tool like pkcon into a root shell is far quieter than a kernel exploit that might trip EDR — it looks like normal package activity in the logs. Minimal-install assumptions do not save you; plenty of “headless” server images ship PackageKit for automated patching.

What To Do Now

  • Patch PackageKit to 1.3.5 or your distro's backport. Update through your vendor's security channel (Ubuntu USN, Fedora/Rocky advisories, Debian DSA) and prioritize multi-user hosts, shared desktops, jump boxes, and CI runners where local footholds are most likely.
  • Reboot or restart the daemon after updating. PackageKit is a persistent service; a running instance keeps the old binary. Restart packagekit.service or reboot so no stale, vulnerable transaction handler survives the upgrade.
  • Harden polkit as an interim shield. If you cannot patch at once, tighten the polkit rules governing org.freedesktop.packagekit so local, unauthenticated users cannot install packages — this blocks the exploit's entry path even on a vulnerable daemon.
  • Disable or mask PackageKit where it isn't needed. On servers that never use GUI-driven package management, mask packagekit.service to remove the D-Bus attack surface entirely.
  • Audit your other D-Bus-exposed privileged services. PackageKit is one of many root-capable daemons on a default desktop; inventory them and treat each as a potential LPE path, not a trusted internal.
  • Hunt for abuse in logs. Review PackageKit and journal entries for unexpected InstallFiles transactions or local package installs that no admin initiated, especially retroactively given a public exploit exists.

Open Questions

Because the bug is twelve years old, the obvious worry is prior undisclosed abuse. As of publication there is no confirmed in-the-wild exploitation, and the “likely used by sophisticated actors” framing remains speculation, not evidence — a low-noise LPE that blends into package logs is exactly the kind of activity that would be hard to spot after the fact. It is also unclear how many long-tail distributions and appliance images that embed PackageKit will receive timely backports versus quietly staying vulnerable. With a proof-of-concept and a CTF-style lab already public, the practical window for opportunistic exploitation is open now.

Primary Documents

Read more