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. (एनवीडी)
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. (गिटहब)
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
| क्षेत्र | Current best-known status | यह क्यों मायने रखती है |
|---|---|---|
| सीवीई | CVE-2026-43494 | Use this identifier for patch tracking, scanner correlation, exception handling, and vendor advisories. |
| Public name | PinTheft | The name refers to stealing FOLL_PIN references until io_uring is left holding a stale page pointer. V12’s README explains the naming directly. (गिटहब) |
| कीट वर्ग | Linux kernel local privilege escalation | The attacker needs local code execution first. The impact is still severe on shared or semi-trusted Linux infrastructure. |
| Vulnerable area | RDS zerocopy send path | The root cause is in net/rds, not in a web service, SSH daemon, or ordinary userland package. |
| Exploit conversion | RDS reference-count bug plus io_uring fixed buffers | The 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 effect | In-memory page cache overwrite of a SUID-root binary | Disk 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 status | Public PoC exists | Public exploit code changes response urgency, but it does not prove every Linux host is reachable. |
| Durable remediation | Vendor kernel update, reboot, or vendor-supported livepatch where available | Module blacklisting and io_uring restrictions are compensating controls, not the root-cause patch. |
| Severity scoring | Vendor scores differ | NVD 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. (एनवीडी) |
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_RDS, और 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. (गिटहब)
| पर्यावरण | RDS likely needed | PinTheft response priority | Practical note |
|---|---|---|---|
| General web server | Usually no | Disable RDS if not used, then patch | Most web apps do not need RDS. Confirm before changing production images. |
| सीआई रनर | Usually no | उच्च | CI workers often execute third-party or semi-trusted code, making local escalation bugs operationally useful. |
| Shared hosting node | Usually no | उच्च | Low-privileged local users are part of the business model. Kernel LPEs deserve fast attention. |
| Kubernetes worker | Usually no | High when workloads are untrusted | Containers share the host kernel. A local kernel LPE can become a node-level incident if reachable. |
| Developer workstation | Usually no | Medium to high | Risk rises when developers compile PoCs, run untrusted dependency scripts, or test attacker-controlled code. |
| HPC cluster | Possibly | Patch first, test mitigation | RDS may be intentional. Do not disable it without workload owners. |
| Oracle RAC or specialized database cluster | Possibly | Patch first, validate RDS dependency | Some 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(). (एनवीडी)
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 element | Intended meaning | PinTheft-relevant failure |
|---|---|---|
| Pinned user pages | Pages temporarily held for zerocopy send | Already dropped after pin failure |
| Scatterlist entries | Metadata describing page-backed data | Remain live enough for later cleanup logic |
op_nents | Count of entries to clean up | Not reset after the failed pin path |
| Zerocopy notifier | Tracks zerocopy completion state | Cleared after failure |
| RDS purge logic | Releases message-owned resources | Iterates 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.
How io_uring turns the bug into a page-cache overwrite

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. (गिटहब)
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. (गिटहब)
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 stage | What happens at a high level | Defender takeaway |
|---|---|---|
| Page setup | The exploit prepares memory so a zerocopy operation fails after some pages are pinned | The bug depends on a controlled local process, not just a packet arriving over the network. |
| Fixed-buffer pin | io_uring holds a pinned page reference | io_uring availability is part of the exposure model. |
| Reference theft | Repeated failing RDS zerocopy sends drain pin references | RDS reachability is the key subsystem gate. |
| Page reuse | The freed page is reclaimed as page cache for a privileged executable | Page-cache corruption can affect execution without changing bytes on disk. |
| Cached overwrite | The stale fixed-buffer pointer writes into the page-cache-backed executable page | File integrity tools that only hash disk contents may miss the live effect. |
| Privileged execution | The SUID-root program executes modified cached content | Monitor 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. (एनवीडी)
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:
| Gate | What to check | यह क्यों मायने रखती है |
|---|---|---|
| Kernel code | Vendor kernel package and stable commit status | The root bug is in the kernel. Vendor backports matter more than upstream version strings alone. |
| RDS config | CONFIG_RDS | If RDS is not compiled at all, the vulnerable code path is absent. |
| RDS TCP config | CONFIG_RDS_TCP | The public chain requests RDS TCP transport where available. |
| Module availability | Whether rds, rds_tcp, या rds_rdma exist on disk | A module that is not present cannot be loaded. |
| Module load state | Whether RDS modules are already loaded | Loaded modules make the path immediately reachable. |
| Autoload policy | Whether unprivileged socket creation can trigger module autoload | Autoload can turn dormant modules into reachable attack surface. |
io_uring availability | CONFIG_IO_URING और kernel.io_uring_disabled | The public chain uses io_uring fixed buffers. |
| SUID-root target | Readable SUID-root binaries | The public chain uses a privileged executable as the page-cache target. |
| Local execution | Ability for attacker-controlled code to run locally | Without local code execution, PinTheft is not directly reachable. |
| PoC compatibility | Architecture and kernel API details | The 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. (एनवीडी)
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.
| स्रोत | Public status signal | Practical interpretation |
|---|---|---|
| एनवीडी | Awaiting enrichment, kernel.org description present | Use the description and references now; do not wait for NVD scoring to begin exposure checks. |
| Canonical Ubuntu | CVSS 3.1 7.8 High, Ubuntu Priority Medium due default mitigation | Default Ubuntu may be protected, but RDS-enabled hosts need attention. |
| Amazon Linux | Important, CVSS v3 7.8, package status varies | Track affected package streams and vendor fixes. |
| SUSE | Important, vendor CVSS v3 and v4 displayed | Vendor risk scoring may differ; rely on local exposure gates. |
| CloudLinux | RHEL-based platforms not affected due no CONFIG_RDS | Kernel configuration can remove the vulnerable path entirely. |
Safe exposure checks for Linux hosts

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:
| Result | Meaning | Next action |
|---|---|---|
CONFIG_RDS is not set | RDS is not compiled into this kernel | Public PinTheft chain should not reach the RDS bug path. Continue patch governance, but urgency drops. |
CONFIG_RDS=m and modules exist | RDS is available as a module | Check loaded state and autoload policy. |
rds या rds_tcp already loaded | RDS path is active | Treat as higher priority unless there is a documented business need. |
modprobe -n -v rds_tcp shows install /bin/false or blacklist behavior | Autoload is blocked | This closes a key exploitation gate. |
kernel.io_uring_disabled=0 | Unrestricted creation according to upstream semantics | If RDS is reachable and local users exist, exposure is higher. |
kernel.io_uring_disabled=1 | Unprivileged creation is restricted unless group policy allows it | Review group membership and workload needs. |
kernel.io_uring_disabled=2 | New io_uring creation is disabled for all processes | Public 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:
| कदम | Action | Reason |
|---|---|---|
| 1 | Inventory kernel.io_uring_disabled across the fleet | Know the current state before changing it. |
| 2 | Identify workloads that use io_uring | Avoid breaking performance-sensitive systems. |
| 3 | Apply 1 to shared or semi-trusted hosts first | This targets the highest-risk local-user environments. |
| 4 | Monitor application errors and latency | io_uring restrictions can cause runtime changes. |
| 5 | Consider 2 only for hardened profiles | Full disablement is stronger but more disruptive. |
| 6 | Remove or relax only after patch and risk review | Do 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. (एनवीडी)
A safe remediation checklist:
| Control | What it does | Limitations |
|---|---|---|
| Vendor kernel update | Fixes root cause in supported kernel package | Requires reboot or livepatch validation. |
| RDS module block | Removes a major exploitation gate where RDS is not needed | Breaks real RDS workloads. Does not fix kernel code. |
io_uring restriction | Removes or narrows the weaponization path used by public PoC | May break workloads. Does not fix RDS bug. |
| Local execution reduction | Limits attacker’s ability to reach local LPE | Operationally hard in CI, hosting, and container environments. |
| SUID reduction | Reduces privileged executable targets | Requires careful package and OS policy review. |
| Runtime monitoring | Detects suspicious behavior | Cannot guarantee prevention. |
Detection, do not rely only on file hashes

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:
| Signal | Confidence | यह क्यों मायने रखती है | Caveat |
|---|---|---|---|
rds या rds_tcp loads on a host that should not use RDS | उच्च | Opens a key PinTheft gate | Some HPC or database workloads may be legitimate. |
| Modprobe policy changed to allow RDS | उच्च | Could weaken a compensating control | Admin changes can be legitimate. Require change ticket correlation. |
Low-privileged process creates many io_uring instances | मध्यम | Public chain depends on io_uring | Modern apps may use io_uring legitimately. Baseline first. |
| Unexpected execution of SUID-root binaries by service users | Medium to high | Public chain targets SUID execution | Service accounts may run helper binaries in normal operations. |
| Sudden root shell spawned from unusual parent process | उच्च | Post-exploitation behavior | Needs EDR or audit correlation. |
| Kernel warnings around RDS or memory management | मध्यम | May indicate failed attempts or instability | Exploits may not crash. Absence of logs is not proof of safety. |
| Disk hash unchanged but runtime behavior abnormal | उच्च | Page cache issues can evade disk-only checks | Requires 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:
| Question | यह क्यों मायने रखती है |
|---|---|
| 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. |
Is 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 type | Priority | Reason |
|---|---|---|
| Shared hosting node | Critical or high | Local users exist by design. A local LPE can become full host compromise. |
| CI/CD runner for pull requests or third-party code | Critical or high | Attackers may reach local execution through build scripts, tests, or dependencies. |
| Kubernetes worker running untrusted workloads | उच्च | Containers share the host kernel, and node compromise is serious. |
| Developer workstation used for untrusted PoCs | Medium to high | Social engineering and malicious code execution are plausible. |
| Single-purpose internal server with no local users and no untrusted jobs | मध्यम | Patch normally, confirm RDS and io_uring gates. |
| HPC or database cluster using RDS | High, with careful change control | RDS dependency raises exposure, but mitigation may break workloads. |
RHEL-derived system with no CONFIG_RDS | Low for this chain | Continue 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.
| Bug | सीवीई | Core primitive | Initial access needed | Why it is relevant |
|---|---|---|---|---|
| Dirty COW | CVE-2016-5195 | Copy-on-write race allowing write access to read-only mappings | Local user | Shows how a memory-management invariant failure can become real-world privilege escalation; NVD notes in-the-wild exploitation in 2016. (एनवीडी) |
| Dirty Pipe | CVE-2022-0847 | Pipe buffer flag issue enabling writes to page-cache pages backed by read-only files | Local user | Directly relevant to page cache and read-only file trust boundaries. (एनवीडी) |
| Copy Fail | CVE-2026-31431 | AF_ALG, AEAD, splice, and page-cache write behavior | Local user | Another 2026 Linux page-cache-to-root case; NVD describes reverting in-place algif_aead operation. (एनवीडी) |
| Dirty Frag | CVE-2026-43284 and CVE-2026-43500 | ESP/RxRPC fragment handling and page-cache corruption | Local user | Extends 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) |
| PinTheft | CVE-2026-43494 | RDS zerocopy reference-count bug plus io_uring fixed buffers | Local user | Shows 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. (पेनलिजेंट.एआई)
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. (एनवीडी)
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:
| पर्यावरण | यह क्यों मायने रखती है |
|---|---|
| CI runners | Build jobs often run attacker-influenced code. |
| Container workers | Workloads share the host kernel. |
| Shared hosting | Local users are expected. |
| Bastion hosts | Many users may have shell access. |
| Developer workstations | Untrusted PoCs and dependency scripts are common. |
| Research servers | Multi-user experimentation increases local code risk. |
| HPC clusters | RDS 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:
| प्रमाण | यह क्यों मायने रखती है |
|---|---|
| Host list and scope | Shows which assets were reviewed. |
| Kernel package version | Shows remediation state. |
| Running kernel version | Confirms reboot or livepatch effectiveness. |
| Module policy files | Proves compensating controls. |
io_uring sysctl value | Documents attack-surface reduction. |
| Exception list | Captures RDS-dependent systems and owners. |
| Retest timestamp | Shows 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. (पेनलिजेंट.एआई)
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:
| क्षेत्र | उदाहरण |
|---|---|
| Asset | hpc-node-17.example.internal |
| Reason | RDS required for cluster workload |
| Business owner | HPC platform team |
| Security owner | Infrastructure security |
| Temporary control | Kernel update scheduled, extra monitoring enabled |
| पहचान | Module load baseline, SUID execution audit, EDR watchlist |
| Expiry | Date when patch or replacement is expected |
| Approval | Change 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.
अक्सर पूछे जाने वाले प्रश्न
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_uringfixed 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_TCP, औरCONFIG_IO_URING. - Check whether
rds,rds_tcp, याrds_rdmaare loaded or can be autoloaded. - जाँचें
kernel.io_uring_disabled; unrestrictedio_uringincreases 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_uringactivity.
Should I disable io_uring because of PinTheft?
- Consider restricting
io_uringon shared, multi-tenant, CI, sandbox, and container-worker hosts after compatibility testing. kernel.io_uring_disabled=1restricts unprivileged creation except for authorized users or groups, depending on configuration.kernel.io_uring_disabled=2disables creation of newio_uringinstances 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_uringis 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. (एनवीडी)
- V12 Security’s PinTheft repository is the primary public technical write-up for the exploitation chain and requirements. (गिटहब)
- 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.

