A fully unprivileged container can break out of its sandbox and execute arbitrary code on the underlying node. That's the alarming promise of Copy-Fail (CVE-2026-31431), a Linux kernel vulnerability turned into a working proof-of-concept for Kubernetes. The PoC demonstrates how an attacker with minimal permissions inside a pod can corrupt the in-memory page cache of a binary, and then trigger that corruption when a privileged DaemonSet—like kube-proxy—runs the same binary from a shared image layer. Validated on Alibaba Cloud ACK, Amazon EKS, and Google GKE, the attack achieves node-level code execution without needing to escape the container via traditional means.

The approach

The attack hinges on three properties that often coexist in Kubernetes clusters:

  1. Kernel page-cache corruption (CVE-2026-31431) – an unprivileged process can overwrite the cached pages of any file it can open read-only, without write permissions to the file itself.
  2. Image layer sharing – container runtimes use overlay filesystems, so identical image layers map to the same page-cache pages across containers.
  3. Privileged DaemonSets – many clusters run DaemonSets with elevated privileges (hostNetwork, privileged, broad capabilities) that periodically execute binaries from their image.

When these conditions align, an unprivileged pod can corrupt a binary in a shared image layer, and a privileged DaemonSet on the same node will unknowingly execute the corrupted binary with its elevated privileges.

The exploitation chain has three stages. First, the PoC corrupts the page cache via an AF_ALG splice race. It opens the target binary read-only, creates an AF_ALG AEAD socket, sends a small payload with MSG_MORE, and then splices the file descriptor into the socket. Due to a CoW bug, the kernel writes the attacker’s payload bytes into the target’s page-cache pages instead of isolating them. This corrupts the in-memory cache; the on-disk file remains unchanged.

Second, because the attacker’s container image is built from the same base as the privileged DaemonSet, both containers share the overlay lower-dir. Consequently, the corrupted page cache is instantly visible to the DaemonSet container without any cross-container communication.

Third, when the DaemonSet executes the corrupted binary (e.g., during its normal reconciliation loop), the kernel loads the corrupted pages. The attacker’s payload runs with the DaemonSet’s full privileges—potentially including root on the node, all capabilities, and host namespace access. The default payload simply mounts the host filesystem and writes a marker file to prove node-level execution. As the README puts it, “any privileged DaemonSet sharing image layers with an attacker-controlled container can be weaponized for container escape.” While the PoC uses kube-proxy as a concrete example, the technique generalizes to any privileged workload, such as monitoring agents, CNI plugins, or log collectors.

Copy-Fail-CVE-2026-31431-Kubernetes-PoC/main/docs/eks-poc-res.png" alt="Copy-Fail-CVE-2026-31431-Kubernetes-PoC screenshot 1">

What you actually get

The repository provides a self-contained PoC with the following components:

  • Core exploit logic in C, using the AF_ALG subsystem to perform the splice race and corrupt page cache.
  • A Go-based launcher that embeds the compiled payload and orchestrates the corruption loop.
  • Three tailored payloads (ACK/upstream, EKS, GKE) that write a marker file to the host filesystem; each payload auto-detects the appropriate root device or stateful partition.
  • Dockerfiles and build scripts to produce cloud-specific images, leveraging registry.k8s.io/kube-proxy for ACK/upstream, eks-distro base for EKS, and GKE’s provider-managed images for GKE.
  • Kubernetes deployment manifests (poc.yaml, poc-eks.yaml, poc-gke.yaml) that deploy an unprivileged pod with imagePullPolicy: IfNotPresent.
  • Detailed walkthroughs for EKS and GKE in the docs folder, covering image layer analysis, build steps, and validation.
  • A nolibc directory containing a tiny libc for static, no-dependency payloads.

The PoC is explicitly for educational and defensive testing; it is not a