Bußgeld-Kopfzeile

PinTheft CVE-2026-43494, Linux RDS to Root Through Page Cache

PinTheft is not a remote bug that lets a random internet user root every Linux server. It is more specific, and that specificity is exactly why defenders need to read it carefully. CVE-2026-43494 lives in the Linux kernel’s RDS networking code, in the zerocopy send path. The public exploitation chain combines that RDS bug with io_uring fixed buffers to overwrite page-cache-backed bytes of a SUID-root executable, turning low-privileged local code execution into root on a reachable host. The NVD record describes the kernel fix as net/rds: reset op_nents when zerocopy page pin fails, and notes that when iov_iter_get_pages2() fails inside rds_message_zcopy_from_user(), already pinned pages are released but op_nents is not properly cleared, allowing later cleanup to free them again. (NVD)

That makes PinTheft a post-compromise escalation problem. An attacker first needs a local foothold: a shell account, a compromised web process, a malicious CI job, an untrusted container workload, a developer running untrusted code, or another path to execute code as a low-privileged user. Once that local execution exists, the question becomes whether the kernel, modules, and runtime settings line up. If they do, the impact can be root. V12 Security’s public write-up describes PinTheft as an RDS zerocopy double-free that can be turned into a page-cache overwrite through io_uring fixed buffers, and the oss-security post relaying the disclosure quotes the same mechanism. (GitHub)

The most useful way to assess PinTheft is not “Am I running Linux?” It is “Can an unprivileged local user reach this exact chain?” That chain has gates: RDS must be present, RDS over TCP must be present or loadable, io_uring must be usable by the relevant process, the host must expose a suitable SUID-root executable, and the kernel must contain the vulnerable path. Some vendors ship defaults that close one or more of those gates. Others may need urgent configuration changes while kernel updates roll out. Ubuntu, for example, states that default Ubuntu systems are not affected because the distribution disables automatic loading of the vulnerable RDS module, while systems that explicitly enabled RDS change that risk calculation. (Ubuntu)

The facts that matter first

FeldCurrent best-known statusWarum das wichtig ist
CVECVE-2026-43494Use this identifier for patch tracking, scanner correlation, exception handling, and vendor advisories.
Public namePinTheftThe name refers to stealing FOLL_PIN references until io_uring is left holding a stale page pointer. V12’s README explains the naming directly. (GitHub)
Bug classLinux kernel local privilege escalationThe attacker needs local code execution first. The impact is still severe on shared or semi-trusted Linux infrastructure.
Vulnerable areaRDS zerocopy send pathThe root cause is in net/rds, not in a web service, SSH daemon, or ordinary userland package.
Exploit conversionRDS reference-count bug plus io_uring fixed buffersThe RDS bug becomes useful because io_uring can retain a page reference in a way the exploit can later turn into a page-cache write.
Target effectIn-memory page cache overwrite of a SUID-root binaryDisk content may remain unchanged while the running system observes modified cached bytes. Ubuntu explicitly notes that disk contents are not affected, though later write-back by other programs may make changes persistent. (Ubuntu)
Public exploit statusPublic PoC existsPublic exploit code changes response urgency, but it does not prove every Linux host is reachable.
Durable remediationVendor kernel update, reboot, or vendor-supported livepatch where availableModule blacklisting and io_uring restrictions are compensating controls, not the root-cause patch.
Severity scoringVendor scores differNVD had not provided its own score when checked, while Canonical assessed CVSS 3.1 as 7.8 High and Ubuntu Priority as Medium due to default mitigation. (NVD)

What RDS is, and why a rare subsystem still matters

RDS means Reliable Datagram Sockets. The Linux kernel documentation describes RDS as providing reliable, ordered datagram delivery over a single reliable connection between nodes, designed so applications in a cluster can communicate without requiring an N-by-N set of connection-oriented sockets. The same documentation notes that RDS has socket semantics exposed through AF_RDS, PF_RDSund SOL_RDS, and that extensions such as zerocopy support are implemented through control messages. (Kernel Documentation)

For most general-purpose Linux servers, RDS is not part of the normal application path. A typical NGINX server, API backend, laptop, CI runner, or Kubernetes node usually does not need it. RDS is more plausible in specialized cluster environments, high-performance systems, and deployments that intentionally use RDS transports. That distinction is important for mitigation. If a host does not need RDS, disabling RDS module loading is a low-regret hardening step. If a host does depend on RDS, especially for clustered or database workloads, security teams need to patch and test carefully rather than blindly disabling modules in production.

“Rare” does not mean “safe.” Kernel module availability and autoloading are enough to turn a rare code path into reachable attack surface. V12’s public README says the exploit asks RDS for TCP transport with SO_RDS_TRANSPORT=2, which can autoload rds_tcp on systems where the module exists and module autoloading is allowed. (GitHub)

UmweltRDS likely neededPinTheft response priorityPractical note
General web serverUsually noDisable RDS if not used, then patchMost web apps do not need RDS. Confirm before changing production images.
CI runnerUsually noHochCI workers often execute third-party or semi-trusted code, making local escalation bugs operationally useful.
Shared hosting nodeUsually noHochLow-privileged local users are part of the business model. Kernel LPEs deserve fast attention.
Kubernetes workerUsually noHigh when workloads are untrustedContainers share the host kernel. A local kernel LPE can become a node-level incident if reachable.
Developer workstationUsually noMedium to highRisk rises when developers compile PoCs, run untrusted dependency scripts, or test attacker-controlled code.
HPC clusterPossiblyPatch first, test mitigationRDS may be intentional. Do not disable it without workload owners.
Oracle RAC or specialized database clusterPossiblyPatch first, validate RDS dependencySome environments may rely on RDS-like networking assumptions. Treat mitigation as a change request.

The root cause, a stale count in an error path

The shortest technical description of CVE-2026-43494 is this: RDS zerocopy page pinning fails partway through, cleanup state becomes inconsistent, and a later cleanup path releases pages again. The NVD record says that when iov_iter_get_pages2() fails in rds_message_zcopy_from_user(), the pinned pages are released and rm->data.op_mmp_znotifier is cleared, but rm->data.op_nents is not properly cleared. Later, rds_message_purge() iterates over the incorrectly non-zero entry count and frees those pages again. The fix is to reset op_nents when appropriate in rds_message_zcopy_from_user(). (NVD)

The important security idea is an invariant failure. One field says, in effect, “there are still entries to clean up.” Another part of the state says the zerocopy notifier has been cleared and the pages have already been dropped. In normal execution, the two views should agree. In the error path, they do not.

Kernel bugs often live in places like this. The happy path gets tested. The common failure path gets some attention. The strange failure path that occurs after a partial zerocopy pin, before message completion, with cleanup later performed through another function, is where state accounting can go wrong. PinTheft sits in that uncomfortable space: not a simple missing bounds check, but a mismatch between resource ownership, reference counts, scatterlist state, notifier state, and cleanup semantics.

A useful mental model looks like this:

Kernel state elementIntended meaningPinTheft-relevant failure
Pinned user pagesPages temporarily held for zerocopy sendAlready dropped after pin failure
Scatterlist entriesMetadata describing page-backed dataRemain live enough for later cleanup logic
op_nentsCount of entries to clean upNot reset after the failed pin path
Zerocopy notifierTracks zerocopy completion stateCleared after failure
RDS purge logicReleases message-owned resourcesIterates as though entries still need cleanup

That is why the fix is small in concept but serious in effect. Reset the accounting field at the right time, and the later cleanup loop no longer double-drops references. Leave it inconsistent, and the page reference count can be manipulated by repeated failing zerocopy operations.

Wie io_uring turns the bug into a page-cache overwrite

PinTheft Exploit Chain, From RDS Page Pin Failure to Root

The RDS bug alone is the root cause. The public exploit chain becomes practical because io_uring fixed buffers give the attacker a way to hold a stale relationship to a page while the kernel later reuses that page for something valuable.

V12 describes the public PoC as registering an anonymous page as an io_uring fixed buffer, giving the page a FOLL_PIN bias of 1024 references. The exploit then uses failing RDS zerocopy sends to steal those references, frees the page, reclaims it as page cache for a SUID-root binary, and uses the stale io_uring fixed-buffer page pointer to overwrite that page cache with a small ELF payload. Executing the SUID binary then runs the cached attacker-controlled bytes as root. (GitHub)

The public write-up also lists requirements: CONFIG_RDS, CONFIG_RDS_TCP, CONFIG_IO_URING, io_uring_disabled=0, a readable SUID-root binary, and x86_64 for the included payload. It notes that the technique is architecture-independent, but the embedded shell ELF in the public PoC is x86_64. (GitHub)

For defenders, the lesson is not “memorize exploit steps.” The lesson is that modern kernel exploitation often crosses feature boundaries. RDS supplies the refcount bug. io_uring supplies a stable primitive for fixed-buffer access. The page allocator and page cache supply reuse. SUID-root programs supply the privilege boundary. One narrow bug becomes root because multiple subsystems make individually reasonable assumptions that stop being safe when chained.

Conceptual stageWhat happens at a high levelDefender takeaway
Page setupThe exploit prepares memory so a zerocopy operation fails after some pages are pinnedThe bug depends on a controlled local process, not just a packet arriving over the network.
Fixed-buffer pinio_uring holds a pinned page referenceio_uring availability is part of the exposure model.
Reference theftRepeated failing RDS zerocopy sends drain pin referencesRDS reachability is the key subsystem gate.
Page reuseThe freed page is reclaimed as page cache for a privileged executablePage-cache corruption can affect execution without changing bytes on disk.
Cached overwriteThe stale fixed-buffer pointer writes into the page-cache-backed executable pageFile integrity tools that only hash disk contents may miss the live effect.
Privileged executionThe SUID-root program executes modified cached contentMonitor suspicious SUID execution and privilege transitions, not just file changes.

Why page cache corruption is so dangerous

The page cache is the kernel’s in-memory cache of file contents. If a process reads a file, the kernel may serve it from cached memory rather than from storage every time. That is normal and essential for performance. It becomes dangerous when a bug lets an attacker write into cached pages that should represent read-only or privileged file content.

With a page-cache overwrite, disk-based integrity checks can give false comfort. A hash of /usr/bin/su on disk may still match the package database. The file may look untouched to a basic file integrity monitor. Yet a later execution path may observe the modified cached page. Ubuntu’s PinTheft mitigation post makes this distinction explicit: the vulnerability allows replacing in-memory contents of arbitrary files, disk contents are not affected, and programs that read a file, make changes, and write data back may make those changes persistent. (Ubuntu)

That places PinTheft in the same broad operational family as earlier Linux page-cache or read-only-file write bugs. It is not identical to Dirty COW or Dirty Pipe, but the defensive concern rhymes: a local user obtains a write primitive against data the system assumes is read-only or privileged, then uses that primitive to cross into root.

NVD describes Dirty COW, CVE-2016-5195, as a race condition in Linux mm/gup.c that allowed local users to gain privileges by leveraging incorrect handling of copy-on-write, and notes that it was exploited in the wild in October 2016. NVD describes Dirty Pipe, CVE-2022-0847, as a flaw involving uninitialized pipe buffer flags that could allow an unprivileged local user to write to page-cache pages backed by read-only files and escalate privileges. (NVD)

The point is not that every Linux LPE is the same. The point is that defenders should recognize a pattern: when high-performance data paths blur ownership boundaries around pages, buffers, pipes, fragments, or cached file data, small accounting mistakes can become high-impact privilege transitions.

Affected does not always mean exploitable

PinTheft is a good example of why vulnerability management cannot stop at version matching. A kernel may contain the vulnerable code, but the host may still be difficult or impossible to exploit through the public chain because one of the required gates is closed.

The most important gates are:

GateWhat to checkWarum das wichtig ist
Kernel codeVendor kernel package and stable commit statusThe root bug is in the kernel. Vendor backports matter more than upstream version strings alone.
RDS configCONFIG_RDSIf RDS is not compiled at all, the vulnerable code path is absent.
RDS TCP configCONFIG_RDS_TCPThe public chain requests RDS TCP transport where available.
Module availabilityWhether rds, rds_tcp, oder rds_rdma exist on diskA module that is not present cannot be loaded.
Module load stateWhether RDS modules are already loadedLoaded modules make the path immediately reachable.
Autoload policyWhether unprivileged socket creation can trigger module autoloadAutoload can turn dormant modules into reachable attack surface.
io_uring availabilityCONFIG_IO_URING und kernel.io_uring_disabledThe public chain uses io_uring fixed buffers.
SUID-root targetReadable SUID-root binariesThe public chain uses a privileged executable as the page-cache target.
Local executionAbility for attacker-controlled code to run locallyWithout local code execution, PinTheft is not directly reachable.
PoC compatibilityArchitecture and kernel API detailsThe included public payload is x86_64 and the PoC has API requirements.

CloudLinux’s analysis illustrates why these gates matter. It states that its RHEL-based CloudLinux OS kernels from CL7 through CL10 ship with CONFIG_RDS not set, meaning the RDS subsystem is not compiled into the kernel, the RDS modules are not present, and the relevant socket path returns unsupported. It also notes that CL9 and CL10 disable io_uring by default with kernel.io_uring_disabled=2. (blog.cloudlinux.com)

Ubuntu illustrates a different model. Ubuntu says Focal 20.04 LTS and later kernel images are affected in the sense that the vulnerable code exists, but default Ubuntu configuration mitigates the issue by disabling automatic RDS module loading through its rare network protocol blacklist. Ubuntu further says users who need RDS would have to explicitly load the module, and that configuration would allow exploitation. (Ubuntu)

That is the right framing for internal risk communication: “This CVE affects the kernel code path, but exploitability depends on our kernel build, RDS module state, autoload policy, io_uring policy, and local execution exposure.”

Vendor severity differs, and that is normal

CVE scoring for PinTheft is not uniform across sources. NVD showed the record as awaiting enrichment and did not provide its own CVSS score when checked. Canonical assessed the vulnerability as CVSS 3.1 7.8 High, but assigned Ubuntu Priority Medium because default Ubuntu configuration is safe against the issue. Amazon Linux listed CVSS v3 base score 7.8 and severity Important, with several kernel package streams shown as pending fix. SUSE rated the issue Important and displayed its own CVSS v3 score of 8.4 and CVSS v4 score of 7.3. (NVD)

Those differences do not mean one source is “wrong.” They reflect different assumptions about privileges required, attack requirements, default module state, distribution configuration, and reachable environments. For a shared hosting provider, the practical priority may be higher than for a single-user workstation. For an HPC cluster that intentionally uses RDS, patch urgency may be high but mitigation risk may also be high. For a RHEL-derived platform with RDS not compiled, the issue may be structurally unreachable unless a custom kernel is introduced.

QuellePublic status signalPractical interpretation
NVDAwaiting enrichment, kernel.org description presentUse the description and references now; do not wait for NVD scoring to begin exposure checks.
Canonical UbuntuCVSS 3.1 7.8 High, Ubuntu Priority Medium due default mitigationDefault Ubuntu may be protected, but RDS-enabled hosts need attention.
Amazon LinuxImportant, CVSS v3 7.8, package status variesTrack affected package streams and vendor fixes.
SUSEImportant, vendor CVSS v3 and v4 displayedVendor risk scoring may differ; rely on local exposure gates.
CloudLinuxRHEL-based platforms not affected due no CONFIG_RDSKernel configuration can remove the vulnerable path entirely.

Safe exposure checks for Linux hosts

PinTheft Exposure Checklist for Linux Defenders

The following commands are designed for defensive inventory and configuration review. They do not run exploit code. Run them with administrative approval on systems you own or manage.

Start with a single-host quick check:

uname -a

echo "[kernel config]"
if [ -r "/boot/config-$(uname -r)" ]; then
  grep -E 'CONFIG_(RDS|RDS_TCP|RDS_RDMA|IO_URING)=' "/boot/config-$(uname -r)" || true
elif [ -r /proc/config.gz ]; then
  zgrep -E 'CONFIG_(RDS|RDS_TCP|RDS_RDMA|IO_URING)=' /proc/config.gz || true
else
  echo "No readable kernel config found"
fi

echo "[loaded RDS modules]"
lsmod | awk '$1 ~ /^rds/ {print}'

echo "[RDS module dry-run]"
modprobe -n -v rds 2>&1 || true
modprobe -n -v rds_tcp 2>&1 || true

echo "[io_uring sysctl]"
cat /proc/sys/kernel/io_uring_disabled 2>/dev/null || echo "kernel.io_uring_disabled not present"

echo "[SUID-root examples]"
find /usr/bin /bin -xdev -perm -4000 -user root -type f 2>/dev/null | head -50

Interpret the result conservatively:

ErgebnisBedeutungNext action
CONFIG_RDS is not setRDS is not compiled into this kernelPublic PinTheft chain should not reach the RDS bug path. Continue patch governance, but urgency drops.
CONFIG_RDS=m and modules existRDS is available as a moduleCheck loaded state and autoload policy.
rds oder rds_tcp already loadedRDS path is activeTreat as higher priority unless there is a documented business need.
modprobe -n -v rds_tcp shows install /bin/false or blacklist behaviorAutoload is blockedThis closes a key exploitation gate.
kernel.io_uring_disabled=0Unrestricted creation according to upstream semanticsIf RDS is reachable and local users exist, exposure is higher.
kernel.io_uring_disabled=1Unprivileged creation is restricted unless group policy allows itReview group membership and workload needs.
kernel.io_uring_disabled=2New io_uring creation is disabled for all processesPublic PinTheft chain loses the io_uring gate, though compatibility impact must be understood.

The upstream Linux kernel documentation says kernel.io_uring_disabled=0 allows all processes to create io_uring instances, 1 disables creation for unprivileged processes not in the configured group, and 2 disables creation for all processes. Red Hat’s RHEL 9.4 documentation similarly describes io_uring_disabled as a sysctl that prevents processes from creating new io_uring instances and shrinks kernel attack surface, with 2 as the documented default in that RHEL context. (Kernel Documentation)

For repeatable fleet checks, use a small script that records gates rather than a single vulnerable/not-vulnerable label:

#!/usr/bin/env bash
set -euo pipefail

host="$(hostname -f 2>/dev/null || hostname)"
kernel="$(uname -r)"
config="/boot/config-$kernel"

get_config() {
  local key="$1"
  if [ -r "$config" ]; then
    grep -E "^${key}=" "$config" || echo "${key}=UNKNOWN"
  elif [ -r /proc/config.gz ]; then
    zgrep -E "^${key}=" /proc/config.gz || echo "${key}=UNKNOWN"
  else
    echo "${key}=UNKNOWN"
  fi
}

loaded_modules="$(lsmod | awk '$1 ~ /^rds/ {print $1}' | paste -sd, -)"
io_uring_value="$(cat /proc/sys/kernel/io_uring_disabled 2>/dev/null || echo UNKNOWN)"
rds_dryrun="$(modprobe -n -v rds 2>&1 | tr '\n' ';' || true)"
rds_tcp_dryrun="$(modprobe -n -v rds_tcp 2>&1 | tr '\n' ';' || true)"
suid_count="$(find /usr/bin /bin -xdev -perm -4000 -user root -type f 2>/dev/null | wc -l | tr -d ' ')"

printf 'host=%s\n' "$host"
printf 'kernel=%s\n' "$kernel"
get_config CONFIG_RDS
get_config CONFIG_RDS_TCP
get_config CONFIG_RDS_RDMA
get_config CONFIG_IO_URING
printf 'loaded_rds_modules=%s\n' "${loaded_modules:-none}"
printf 'kernel.io_uring_disabled=%s\n' "$io_uring_value"
printf 'rds_modprobe_dryrun=%s\n' "$rds_dryrun"
printf 'rds_tcp_modprobe_dryrun=%s\n' "$rds_tcp_dryrun"
printf 'suid_root_binary_count_in_usr_bin_and_bin=%s\n' "$suid_count"

The output should go into your vulnerability management system with evidence attached. Avoid a binary “safe/unsafe” conclusion until an engineer has reviewed module availability, autoload policy, business use of RDS, io_uring policy, and the vendor patch state.

Defensive osquery checks

If you use osquery, start by checking whether RDS modules are loaded or present in module inventory:

SELECT name, used_by, status
FROM kernel_modules
WHERE name IN ('rds', 'rds_tcp', 'rds_rdma');

Check SUID-root binaries that an exploit might conceptually target. The goal is not to remove SUID everywhere without planning, but to understand privilege boundaries on hosts that also expose kernel LPE risk:

SELECT path, uid, gid, mode
FROM suid_bin
WHERE uid = 0
ORDER BY path;

Track io_uring policy through file reads or configuration collection where your osquery deployment supports it:

SELECT path, data
FROM file
WHERE path = '/proc/sys/kernel/io_uring_disabled';

These queries do not prove exploitation. They help answer the exposure question: “Do we have the gates that make the public chain plausible?”

Temporary mitigation, block RDS if you do not use it

The most direct compensating control is to block RDS modules on systems that do not require RDS. Ubuntu’s mitigation guidance checks whether the rds module is loaded, whether automatic loading is disabled through alias net-pf-21 off, and whether RDS is configured to load at boot. It also states that no manual mitigation is necessary on default Ubuntu systems, but if RDS was previously enabled, users can remove it and add a blacklist entry. (Ubuntu)

A conservative Linux hardening pattern for hosts that do not need RDS is:

sudo tee /etc/modprobe.d/pintheft-rds.conf >/dev/null <<'EOF'
# PinTheft CVE-2026-43494 defense-in-depth
# Do not load RDS modules on hosts that do not require RDS.
install rds /bin/false
install rds_tcp /bin/false
install rds_rdma /bin/false
alias net-pf-21 off
EOF

sudo modprobe -r rds_tcp rds_rdma rds 2>/dev/null || true

modprobe -n -v rds 2>&1 || true
modprobe -n -v rds_tcp 2>&1 || true
lsmod | awk '$1 ~ /^rds/ {print}'

Before applying this across production, confirm that no workload depends on RDS. CloudLinux’s note is a useful reminder: RDS is used almost exclusively in HPC clusters and Oracle RAC-style deployments, not by typical web-hosting, shared-hosting, or general-purpose workloads, but “usually not needed” is still not the same as “never needed.” (blog.cloudlinux.com)

For immutable images, bake the modprobe policy into the base image and verify it in CI. For pets or long-lived servers, record the mitigation as a temporary control and replace it with a kernel update as soon as the vendor-supported fix is available.

Restricting io_uring, useful but not free

io_uring is not “the vulnerability.” It is part of the public weaponization chain. Restricting it can reduce exposure not only for PinTheft but for future kernel attack surface involving the same interface. The kernel documentation is clear that kernel.io_uring_disabled can prevent creation of new io_uring instances. Value 1 restricts unprivileged creation except for privileged or group-authorized users, while value 2 disables creation for all processes. Existing instances can still be used. (Kernel Documentation)

A cautious temporary restriction might look like this:

# Restrict unprivileged io_uring creation where supported.
sudo sysctl -w kernel.io_uring_disabled=1

# Make it persistent after testing.
echo 'kernel.io_uring_disabled = 1' | sudo tee /etc/sysctl.d/90-io-uring-hardening.conf
sudo sysctl --system

A stricter setting is:

# Disable creation of new io_uring instances for all processes where supported.
sudo sysctl -w kernel.io_uring_disabled=2

Do not roll this out blindly. Some workloads use io_uring for performance or I/O behavior. Databases, storage services, virtualization stacks, Samba, QEMU, and newer high-performance applications may rely on it directly or indirectly. Red Hat’s documentation explicitly frames the sysctl as attack-surface reduction, but compatibility still belongs to the operator. (docs.redhat.com)

A practical rollout plan is:

SchrittAktionReason
1Inventory kernel.io_uring_disabled across the fleetKnow the current state before changing it.
2Identify workloads that use io_uringAvoid breaking performance-sensitive systems.
3Apply 1 to shared or semi-trusted hosts firstThis targets the highest-risk local-user environments.
4Monitor application errors and latencyio_uring restrictions can cause runtime changes.
5Erwägen Sie 2 only for hardened profilesFull disablement is stronger but more disruptive.
6Remove or relax only after patch and risk reviewDo not leave emergency changes undocumented.

Durable remediation is still a kernel fix

Compensating controls are valuable because patch windows are messy. They are not a substitute for the fix. The root issue is a kernel bug, and the durable remediation is the vendor kernel package that includes the fix, followed by reboot or a supported livepatch path if your vendor offers one.

NVD references multiple kernel.org stable commits for CVE-2026-43494 and records the kernel.org description of the fix. The oss-security follow-up also states that CVE-2026-43494 was assigned by the Kernel CNA to the fix in commit e174929793195e0cd6a4adb0cad731b39f9019b4. (NVD)

A safe remediation checklist:

KontrolleWhat it doesBeschränkungen
Vendor kernel updateFixes root cause in supported kernel packageRequires reboot or livepatch validation.
RDS module blockRemoves a major exploitation gate where RDS is not neededBreaks real RDS workloads. Does not fix kernel code.
io_uring restrictionRemoves or narrows the weaponization path used by public PoCMay break workloads. Does not fix RDS bug.
Local execution reductionLimits attacker’s ability to reach local LPEOperationally hard in CI, hosting, and container environments.
SUID reductionReduces privileged executable targetsRequires careful package and OS policy review.
Runtime monitoringDetects suspicious behaviorCannot guarantee prevention.

Detection, do not rely only on file hashes

PinTheft Detection and Mitigation Map

PinTheft’s page-cache angle means disk-only file integrity monitoring is not enough. If the on-disk SUID binary remains unchanged, a periodic hash of that path may not see the live in-memory problem. Detection should instead combine module activity, rare subsystem usage, io_uring creation, SUID execution, privilege transitions, and kernel warnings.

Start with module and policy monitoring:

# Audit attempts to load or unload kernel modules.
sudo auditctl -a always,exit -F arch=b64 -S init_module -S finit_module -S delete_module -k kernel-module-change

# Watch modprobe policy changes.
sudo auditctl -w /etc/modprobe.d/ -p wa -k modprobe-policy
sudo auditctl -w /etc/modules-load.d/ -p wa -k modules-load-policy

Monitor io_uring creation where audit supports the syscall names on your kernel and audit stack:

sudo auditctl -a always,exit -F arch=b64 -S io_uring_setup -k io_uring-create

Monitor privileged execution patterns. This is noisy, so tune by environment:

# Example: watch common SUID-root programs for unusual execution patterns.
sudo auditctl -w /usr/bin/su -p x -k suid-exec
sudo auditctl -w /usr/bin/passwd -p x -k suid-exec
sudo auditctl -w /usr/bin/mount -p x -k suid-exec
sudo auditctl -w /usr/bin/pkexec -p x -k suid-exec

A detection matrix is more useful than a single rule:

SignalConfidenceWarum das wichtig istCaveat
rds oder rds_tcp loads on a host that should not use RDSHochOpens a key PinTheft gateSome HPC or database workloads may be legitimate.
Modprobe policy changed to allow RDSHochCould weaken a compensating controlAdmin changes can be legitimate. Require change ticket correlation.
Low-privileged process creates many io_uring instancesMittelPublic chain depends on io_uringModern apps may use io_uring legitimately. Baseline first.
Unexpected execution of SUID-root binaries by service usersMedium to highPublic chain targets SUID executionService accounts may run helper binaries in normal operations.
Sudden root shell spawned from unusual parent processHochPost-exploitation behaviorNeeds EDR or audit correlation.
Kernel warnings around RDS or memory managementMittelMay indicate failed attempts or instabilityExploits may not crash. Absence of logs is not proof of safety.
Disk hash unchanged but runtime behavior abnormalHochPage cache issues can evade disk-only checksRequires behavior monitoring, not just FIM.

For container platforms, detection should be node-centric. Containers share the host kernel. A container workload does not need to modify the container image to exploit a kernel path if the host exposes that path. Focus on worker nodes running untrusted workloads, build jobs, notebook services, plugin execution platforms, and environments where users can upload code.

Container and Kubernetes risk

PinTheft is not automatically a container escape in every configuration. Ubuntu states that the impact in containerized environments is unclear, noting that an attacker in a container may not be able to escape by itself but could corrupt data for other containers or the host if raw storage for files is shared. (Ubuntu)

That uncertainty should lead to disciplined validation, not dismissal. Container platforms run on a shared kernel. If a containerized process can reach AF_RDS, trigger module autoload, create io_uring instances, and interact with suitable file mappings or shared storage behavior, the practical risk may be higher than a simple “local only” label suggests.

Kubernetes teams should ask:

FrageWarum das wichtig ist
Do worker nodes allow untrusted or third-party workloads?Local kernel LPEs matter most when attackers can run code.
Are RDS modules present in the node kernel or image?If absent, the public chain loses the RDS path.
Can workloads trigger module autoload?Autoload can make dormant kernel modules reachable.
Ist io_uring unrestricted for containers?Public PinTheft uses io_uring fixed buffers.
Are privileged containers or broad capabilities allowed?Extra capabilities can turn narrow bugs into easier attack paths.
Are SUID binaries present inside containers or on shared host paths?SUID targets and shared file behavior affect exploitability and impact.
Are runtime security tools watching module loads and privilege transitions on the node?Container-only logs may miss host-level behavior.

Mitigation for container nodes often means hardening the node, not the pod. Disable unused kernel modules at the host level. Restrict io_uring where compatible. Reduce privileged containers and broad capabilities. Patch and reboot nodes through controlled rolling updates. Preserve evidence of kernel package versions, loaded modules, sysctl settings, and node pool rollout status.

Prioritization, where PinTheft should land in the queue

Do not let the word “local” push PinTheft to the bottom of the list by default. Also do not treat it as a universal internet emergency without checking exposure gates. The right priority depends on where low-privileged code can run.

Host typePrioritätReason
Shared hosting nodeCritical or highLocal users exist by design. A local LPE can become full host compromise.
CI/CD runner for pull requests or third-party codeCritical or highAttackers may reach local execution through build scripts, tests, or dependencies.
Kubernetes worker running untrusted workloadsHochContainers share the host kernel, and node compromise is serious.
Developer workstation used for untrusted PoCsMedium to highSocial engineering and malicious code execution are plausible.
Single-purpose internal server with no local users and no untrusted jobsMittelPatch normally, confirm RDS and io_uring gates.
HPC or database cluster using RDSHigh, with careful change controlRDS dependency raises exposure, but mitigation may break workloads.
RHEL-derived system with no CONFIG_RDSLow for this chainContinue patch governance, but the RDS gate is closed.

A useful internal severity statement might be:

“PinTheft CVE-2026-43494 is a high-impact local privilege escalation if the host exposes RDS and io_uring to unprivileged local code. We are prioritizing shared, multi-tenant, CI, container worker, and RDS-enabled systems first. Hosts with RDS absent or autoload blocked remain in normal patch cadence unless other local execution risks exist.”

That language is more accurate than “all Linux servers are critical” or “local only, ignore.”

Related Linux CVEs, the pattern behind the names

PinTheft belongs in a lineage of Linux local privilege escalation bugs where memory ownership, page cache behavior, zero-copy paths, or read-only-file assumptions fail. The specific code paths differ, but the operational lesson is consistent: performance shortcuts and shared-page semantics require extremely precise ownership tracking.

BugCVECore primitiveInitial access neededWhy it is relevant
Dirty COWCVE-2016-5195Copy-on-write race allowing write access to read-only mappingsLocal userShows how a memory-management invariant failure can become real-world privilege escalation; NVD notes in-the-wild exploitation in 2016. (NVD)
Dreckiges RohrCVE-2022-0847Pipe buffer flag issue enabling writes to page-cache pages backed by read-only filesLocal userDirectly relevant to page cache and read-only file trust boundaries. (NVD)
Copy FailCVE-2026-31431AF_ALG, AEAD, splice, and page-cache write behaviorLocal userAnother 2026 Linux page-cache-to-root case; NVD describes reverting in-place algif_aead operation. (NVD)
Dirty FragCVE-2026-43284 and CVE-2026-43500ESP/RxRPC fragment handling and page-cache corruptionLocal userExtends the same family into networking fragments and in-place decrypt behavior; CERT/CC describes it as a chain involving xfrm-ESP and RxRPC page-cache write issues. (kb.cert.org)
PinTheftCVE-2026-43494RDS zerocopy reference-count bug plus io_uring fixed buffersLocal userShows how RDS page pinning and modern async I/O can combine into a SUID-root page-cache overwrite.

The connection to Copy Fail is especially useful for defenders who already had to triage page-cache-to-root exposure earlier in 2026. Penligent’s Copy Fail analysis made the operational point that local kernel bugs become serious when attackers already have a foothold on CI runners, shared build hosts, container nodes, developer VMs, or multi-tenant servers; that same prioritization logic applies to PinTheft, even though the vulnerable subsystem is different. (penligent.ai)

What defenders should not get wrong

The first mistake is dismissing PinTheft because it is local. Local privilege escalation is exactly what attackers need after initial access. A compromised low-privileged web service account, malicious dependency script, stolen developer SSH key, or untrusted build job may be enough to reach the starting line.

The second mistake is treating every Linux host as equally exposed. PinTheft has real gates. RDS may be absent. RDS may be blocked from autoloading. io_uring may be disabled. The public PoC may not compile against older kernels. A vendor kernel may already contain a backported fix. Asset-specific validation matters.

The third mistake is relying on disk hashes alone. Page-cache overwrite bugs are dangerous precisely because live in-memory file content can diverge from disk content. File integrity monitoring remains useful, but it is not sufficient for runtime exploitation detection.

The fourth mistake is disabling io_uring or RDS without understanding business impact. RDS is rare but not nonexistent. io_uring is increasingly common in performance-sensitive workloads. Emergency controls need owners, rollback plans, and post-patch cleanup.

The fifth mistake is assuming NVD enrichment is the start signal. For CVE-2026-43494, NVD showed kernel.org’s description and references while its own scoring was not yet provided. Kernel, vendor, and distribution advisories can be actionable before every database is fully enriched. (NVD)

A practical response playbook

Security teams should run PinTheft response as a short, evidence-backed workflow.

Step 1, identify hosts with local execution risk

Start with environments where low-privileged code execution is normal or plausible:

UmweltWarum das wichtig ist
CI runnersBuild jobs often run attacker-influenced code.
Container workersWorkloads share the host kernel.
Shared hostingLocal users are expected.
Bastion hostsMany users may have shell access.
Developer workstationsUntrusted PoCs and dependency scripts are common.
Research serversMulti-user experimentation increases local code risk.
HPC clustersRDS may be present for legitimate reasons.

Step 2, collect exposure gates

For each host or image, collect:

kernel release
vendor kernel package version
CONFIG_RDS
CONFIG_RDS_TCP
CONFIG_RDS_RDMA
CONFIG_IO_URING
loaded rds modules
modprobe dry-run output for rds and rds_tcp
kernel.io_uring_disabled
SUID-root binary inventory
local user or workload trust model
vendor advisory status
last reboot or livepatch status

Step 3, apply compensating controls where safe

For general-purpose hosts that do not need RDS, block RDS loading. For shared or semi-trusted systems, evaluate io_uring restriction. For container nodes, roll controls through node pools. For RDS-dependent systems, prioritize vendor kernel fixes and schedule testing.

Step 4, patch and reboot

Install the vendor-supported kernel package. Reboot or validate livepatch status. Confirm the running kernel is the patched kernel, not just that the package is installed.

echo "[installed kernel packages]"
rpm -qa 'kernel*' 2>/dev/null | sort || true
dpkg -l 'linux-image*' 2>/dev/null | awk '/^ii/ {print $2, $3}' || true

echo "[running kernel]"
uname -r

echo "[last boot]"
who -b 2>/dev/null || uptime -s

Step 5, verify the controls after remediation

After patching, confirm:

grep -E 'CONFIG_(RDS|RDS_TCP|IO_URING)' /boot/config-$(uname -r) 2>/dev/null || true
lsmod | awk '$1 ~ /^rds/ {print}'
cat /proc/sys/kernel/io_uring_disabled 2>/dev/null || true
modprobe -n -v rds 2>&1 || true
modprobe -n -v rds_tcp 2>&1 || true

Step 6, preserve evidence

For audit and incident response, store:

BeweiseWarum das wichtig ist
Host list and scopeShows which assets were reviewed.
Kernel package versionShows remediation state.
Running kernel versionConfirms reboot or livepatch effectiveness.
Module policy filesProves compensating controls.
io_uring sysctl valueDocuments attack-surface reduction.
Exception listCaptures RDS-dependent systems and owners.
Retest timestampShows closure, not just planned remediation.

Security teams that use AI-assisted validation should keep the workflow evidence-driven. For a vulnerability like PinTheft, an AI system is useful only if it helps map assets, preserve scope, collect defensible configuration evidence, retest after remediation, and produce a report another engineer can verify. Penligent positions its platform around authorized AI-assisted pentesting and evidence-oriented workflows, which is the right kind of context for page-cache-to-root issues: the tool can support validation and reporting discipline, but it does not replace vendor kernel patches or change-control judgment. (penligent.ai)

Example internal advisory text

Security teams often need a concise advisory that is accurate without being alarmist. This is a usable starting point:

PinTheft CVE-2026-43494 is a Linux kernel local privilege escalation issue in the RDS zerocopy send path. Public exploit code exists. The public chain uses RDS/RDS_TCP and io_uring fixed buffers to overwrite page-cache-backed content of a SUID-root binary, allowing a low-privileged local user to obtain root when all exploitation gates are present.

This is not a remote unauthenticated RCE. Risk is highest on systems where untrusted or semi-trusted local code can run, including CI runners, shared hosting, container worker nodes, research servers, bastion hosts, and RDS-enabled clusters.

Immediate actions:
1. Identify whether CONFIG_RDS, CONFIG_RDS_TCP, and CONFIG_IO_URING are present.
2. Confirm whether rds or rds_tcp are loaded or autoloadable.
3. Review kernel.io_uring_disabled.
4. Apply vendor kernel updates and reboot or validate livepatch status.
5. Disable RDS modules on systems that do not require RDS.
6. Consider io_uring restrictions on shared or semi-trusted hosts after compatibility testing.
7. Monitor module loading, io_uring creation, and unusual SUID-root execution.

Handling exceptions

Some teams will discover hosts that cannot immediately disable RDS or restrict io_uring. Treat those as exceptions, not as invisible risk.

An exception record should include:

FeldBeispiel
Assethpc-node-17.example.internal
ReasonRDS required for cluster workload
Business ownerHPC platform team
Security ownerInfrastructure security
Temporary controlKernel update scheduled, extra monitoring enabled
ErkennungModule load baseline, SUID execution audit, EDR watchlist
ExpiryDate when patch or replacement is expected
ApprovalChange ticket or risk acceptance record

The goal is not to force every host into one configuration. The goal is to make every deviation explicit, time-bound, and reviewable.

FAQ

What is PinTheft in plain terms?

  • PinTheft is the public name for a Linux kernel local privilege escalation chain associated with CVE-2026-43494.
  • The underlying bug is in the RDS zerocopy send path, where failed page pinning can leave cleanup state inconsistent.
  • The public exploit chain uses io_uring fixed buffers to turn that reference-counting issue into a page-cache overwrite.
  • The practical result, when all gates are present, is that a low-privileged local user may become root.

Is PinTheft remotely exploitable?

  • Not by itself, based on the public technical descriptions.
  • The attacker needs a way to execute code locally on the target system first.
  • That still matters because many real environments intentionally run local code from semi-trusted sources, including CI jobs, containers, shared shell accounts, plugin systems, and developer scripts.
  • Treat it as a post-compromise root escalation issue, not as a standalone internet-facing RCE.

How do I know if my Linux host is exposed?

  • Check whether your running kernel includes CONFIG_RDS, CONFIG_RDS_TCPund CONFIG_IO_URING.
  • Check whether rds, rds_tcp, oder rds_rdma are loaded or can be autoloaded.
  • Siehe kernel.io_uring_disabled; unrestricted io_uring increases relevance of the public chain.
  • Check whether untrusted or semi-trusted users can run local code on the host.
  • Confirm vendor kernel package status and whether the patched kernel is actually running after reboot or livepatch.

Does Ubuntu need emergency action for PinTheft?

  • Default Ubuntu systems are generally mitigated according to Canonical because Ubuntu disables automatic loading of the affected RDS module through its rare network protocol blacklist.
  • Ubuntu systems where RDS was manually enabled deserve closer review.
  • Ubuntu 20.04 LTS and later kernel images contain the affected code path according to Canonical’s advisory, but default configuration changes exploitability.
  • The safest workflow is still to verify RDS load state, autoload policy, kernel package status, and local execution exposure.

Why does page cache overwrite matter if the file on disk is unchanged?

  • The kernel may execute or read cached file pages from memory rather than reloading bytes from disk.
  • A page-cache overwrite can alter what the live system observes without changing the on-disk file.
  • Disk-only file integrity monitoring may miss this class of runtime corruption.
  • Detection should include runtime behavior, SUID execution, privilege transitions, module loading, and unusual io_uring activity.

Should I disable io_uring because of PinTheft?

  • Consider restricting io_uring on shared, multi-tenant, CI, sandbox, and container-worker hosts after compatibility testing.
  • kernel.io_uring_disabled=1 restricts unprivileged creation except for authorized users or groups, depending on configuration.
  • kernel.io_uring_disabled=2 disables creation of new io_uring instances for all processes where supported.
  • Do not apply it blindly to performance-sensitive systems without testing, because some applications may depend on io_uring.

Should I disable RDS everywhere?

  • Disable RDS on hosts that do not need it.
  • Do not disable RDS blindly on HPC, cluster, or database environments where it may be a legitimate dependency.
  • A good default for general-purpose servers is to block RDS modules and document the control until the patched kernel is deployed.
  • For RDS-dependent hosts, patching and controlled maintenance are the safer primary path.

How should teams prioritize PinTheft against other Linux LPEs?

  • Put shared-hosting nodes, CI runners, Kubernetes workers, developer systems running untrusted code, and RDS-enabled clusters first.
  • Lower priority is reasonable for systems where RDS is absent, autoload is blocked, io_uring is restricted, and no untrusted local execution exists.
  • Do not rely only on CVSS. Use exposure gates and business context.
  • Track it alongside other page-cache and local-root issues such as Dirty Pipe, Copy Fail, Dirty Frag, and related Linux kernel LPEs.

Useful primary resources

  • NVD CVE-2026-43494 is the canonical CVE record for the kernel.org description, enrichment status, and stable kernel references. (NVD)
  • V12 Security’s PinTheft repository is the primary public technical write-up for the exploitation chain and requirements. (GitHub)
  • Ubuntu’s PinTheft mitigation post is useful for default configuration, affected Ubuntu releases, exposure checks, and manual mitigation. (Ubuntu)
  • The Linux kernel RDS documentation explains what RDS is and why it is a specialized but security-relevant subsystem. (Kernel Documentation)

Closing assessment

PinTheft is dangerous because it is narrow and powerful at the same time. It does not flatten every Linux server from the internet. It does not matter equally on every distribution. It does not automatically bypass every container boundary. But on the right host, with RDS reachable and io_uring available to local code, it turns a subtle cleanup bug into root through the page cache.

The practical response is straightforward: confirm the gates, patch the kernel, disable RDS where it is not used, restrict io_uring where compatibility allows, monitor runtime behavior instead of trusting disk hashes alone, and preserve retest evidence. That is the difference between reacting to a vulnerability name and actually reducing exposure.

Teilen Sie den Beitrag:
Verwandte Beiträge
de_DEGerman