A local privilege-escalation flaw in the Linux kernel's AF_PACKET socket layer — tracked as CVE-2020-14386 — lets an attacker who already holds (or can acquire) the CAP_NET_RAW capability corrupt kernel heap memory and potentially escalate to root. The bug lives in net/packet/af_packet.c, the code path that backs raw packet sockets, and it is especially relevant to containerized environments where CAP_NET_RAW is frequently granted by default or is reachable inside unprivileged user namespaces. Because the flaw requires only a capability that is common — not rare — in modern Linux deployments, it turned into a practical container-escape and host-compromise primitive rather than a theoretical curiosity.
What's actually broken
AF_PACKET sockets let a process send and receive raw Ethernet frames, bypassing most of the normal networking stack. To do that efficiently, the kernel maintains ring buffers for packet data, and userspace can tune those buffers with the PACKET_RESERVE socket option, which reserves extra header space in each ring slot.
The vulnerability is a length-calculation bug in tpacket_rcv(), the receive path for these ring-buffer sockets. When a packet arrives, the kernel computes how much space to leave before the payload — a macoff/netoff offset calculation that combines the packet's own header length with the reserved space a socket requested via PACKET_RESERVE. Under crafted conditions, that arithmetic underflows: a value the kernel treats as unsigned effectively goes negative, wraps around, and produces an offset far larger than the actual ring buffer slot.
The kernel then writes packet data at that miscalculated offset — an out-of-bounds heap write. At minimum this crashes the box (an easy, repeatable denial of service). With enough control over packet contents and ring layout, a local attacker can use the OOB write to corrupt adjacent kernel heap objects and pivot toward arbitrary code execution in kernel context, which is the standard route from "memory corruption" to "I am root."
The catch that makes this more than an academic bug: reaching tpacket_rcv() with a controllable PACKET_RESERVE value only requires CAP_NET_RAW. That capability is:
- Granted by default to many container runtimes and orchestrators unless explicitly dropped.
- Available to any process inside an unprivileged user namespace that has been granted (or inherits) net-raw rights.
- Commonly left enabled on general-purpose servers, monitoring agents, and network-diagnostic tooling that legitimately need raw sockets.
That combination — a widely-held capability plus a kernel-heap write — is why this class of bug routinely appears in container-escape research and why defenders should treat it as a real host-compromise path, not just a kernel oddity.
Affected versions and components
- Component: Linux kernel, AF_PACKET subsystem (
net/packet/af_packet.c), specifically thetpacket_rcv()receive path used byPF_PACKET/SOCK_RAWand memory-mapped (PACKET_MMAP) ring-buffer sockets. - Affected kernels: Mainline Linux kernel versions prior to the fix landing ahead of the 5.9 release. In practice this means essentially every long-term-support and distribution kernel shipping before the patch was backported — RHEL 7 and RHEL 8, CentOS, Ubuntu LTS releases, Debian stable, SUSE, and any custom or embedded kernel built from an unpatched 4.x/5.x tree.
- Exploitability precondition: The calling process needs
CAP_NET_RAW, either on the host or inside a container/user namespace. Fully unprivileged processes with no raw-socket capability cannot trigger the vulnerable code path. - Distributions: Every major enterprise Linux vendor shipped an advisory and a backported kernel fix (Red Hat, Canonical/Ubuntu, Debian, SUSE, Amazon Linux, and others), reflecting how broadly the AF_PACKET code is shared across kernel trees.
Severity, exploitation likelihood, and KEV status
- CVSS: NVD scores CVE-2020-14386 7.8 (High) under CVSS v3.1, vector
AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H— local attack vector, low complexity, low privileges required, no user interaction, and a full confidentiality/integrity/availability impact once escalation succeeds. Several distro vendors (Red Hat included) independently confirmed a High-severity rating for their affected kernel builds. - EPSS: Published EPSS scoring for this CVE sits well below the threshold associated with active mass exploitation — consistent with what you'd expect from a local, capability-gated kernel bug rather than a remotely reachable, unauthenticated vulnerability. Treat EPSS here as a signal about opportunistic internet-wide exploitation, not as a statement about targeted or container-escape risk, which this bug is specifically useful for.
- CISA KEV: As of this writing, CVE-2020-14386 does not appear on CISA's Known Exploited Vulnerabilities catalog. Absence from KEV is not the same as "safe to ignore" — KEV tracks confirmed in-the-wild exploitation, and local privilege-escalation bugs in widely-shared kernel code are exactly the kind of thing that gets used quietly in post-compromise chains without generating the telemetry that lands a CVE on that list.
The practical takeaway: this is not an internet-facing, worm-able bug, but it's a reliable "step two" for any attacker or malicious tenant who has already landed a foothold with raw-socket rights — which describes a meaningful slice of real-world container and multi-tenant Linux estates.
Timeline
- Discovery/report: The flaw was identified and reported by security researcher Or Cohen of Palo Alto Networks, as part of a broader review of AF_PACKET and related raw-socket code paths in the Linux kernel.
- Kernel fix: Upstream Linux maintainers landed a fix that corrects the offset/length arithmetic in the AF_PACKET receive path ahead of the 5.9 kernel release cycle, adding proper bounds validation before the ring-buffer write.
- CVE assignment and public disclosure: CVE-2020-14386 was assigned and subsequently published with a detailed advisory describing the
PACKET_RESERVE-driven underflow and its privilege-escalation potential. - Downstream backports: Enterprise and community distributions backported the fix into their respective LTS and stable kernel branches, issuing their own security advisories (RHSA, USN, DSA, and equivalents) with updated kernel package versions.
- Ongoing relevance: Because the bug requires only
CAP_NET_RAW, it continues to surface in container-escape writeups and hardening guidance years after the original fix, as a canonical example of why capability minimization matters as much as patch cadence.
Remediation
- Patch the kernel. This is the definitive fix. Update to a distribution kernel build that incorporates the AF_PACKET correction — for RHEL/CentOS 7 and 8, Ubuntu LTS, Debian, and SUSE, apply the vendor kernel package version referenced in that distribution's advisory for CVE-2020-14386 (
yum update kernel,apt upgrade linux-image-*, or your image-build pipeline's kernel bump, depending on platform). Reboot or apply the update via a live-patching mechanism (kpatch, Ksplice, livepatch) if a reboot window isn't immediately available. - Inventory where
CAP_NET_RAWactually lives. Audit container images, KubernetesSecurityContext/PodSecurityPolicy/admission-controller configs, and systemd unitAmbientCapabilities/CapabilityBoundingSetsettings for anything grantingCAP_NET_RAWbeyond what's strictly required (ping, DHCP clients, packet-capture tooling, and specific monitoring agents are the usual legitimate consumers). - Drop the capability by default. Most container workloads never need raw sockets. Explicitly drop
NET_RAWin your base pod security standards / Docker--cap-drop=NET_RAWand only re-add it on the specific workloads that require it, with justification tracked in your image or manifest metadata. - Constrain user namespaces. Where unprivileged user namespaces aren't needed, disable them (
kernel.unprivileged_userns_clone=0on kernels that expose the sysctl, or the equivalent namespace-restriction control for your distro) to shrink the population of processes that can reach the vulnerable path with elevated-feeling but namespaced capabilities. - Add seccomp/AppArmor/SELinux coverage. Even with
CAP_NET_RAWgranted, a tightened seccomp profile or mandatory-access-control policy restrictingsocket(AF_PACKET, ...)and related syscalls for workloads that don't need raw packet I/O reduces the attack surface without waiting on a kernel roll-out. - Prefer stronger container isolation for untrusted or multi-tenant workloads. Runtimes with an additional syscall-interception layer (gVisor, Kata Containers) or dedicated microVMs reduce the blast radius of an unpatched kernel bug in exactly this class of scenario.
- Verify. Confirm the running kernel version matches or exceeds your distribution's fixed build, and re-scan hosts and images post-patch to close the loop rather than assuming the update job succeeded everywhere.
How Safeguard Helps
Kernel CVEs like this one are exactly where noisy, unprioritized vulnerability lists fail security teams — thousands of hosts might technically run an "affected" kernel version, but only a fraction expose the CAP_NET_RAW precondition that makes CVE-2020-14386 actually exploitable. Safeguard's reachability analysis correlates the vulnerable kernel/component against real runtime capability grants, container security contexts, and workload configuration so you can see which assets are genuinely at risk versus merely present in a scan report. Griffin AI, Safeguard's remediation engine, turns that prioritized finding into a concrete action plan — the specific patched kernel package for each distro, or a capability-drop and seccomp change where an immediate reboot isn't feasible — and can open an auto-fix PR against your Dockerfiles, Kubernetes manifests, or base-image pipeline to remove unnecessary NET_RAW grants before the next build ships. Continuous SBOM generation and ingest keeps kernel and base-image versions tracked across your fleet automatically, so newly disclosed kernel CVEs like this one are matched against your actual inventory the moment they're published, not weeks later during a manual audit.