Overview
CVE-2013-2094 is a local privilege escalation vulnerability in the Linux kernel's performance monitoring subsystem (perf_event). The perf_event_open syscall accepts a 64-bit attr.config field specifying which software performance event to monitor, but the kernel fails to validate the upper 32 bits before using the value as an array index into perf_swevent_enabled[]. An unprivileged user can supply a crafted attr.config value to read or decrement arbitrary kernel memory, enabling reliable root privilege escalation.
The vulnerability is significant both as a historical example of a high-impact kernel exploit with no privilege requirement, and as the canonical justification for the kernel.perf_event_paranoid = 3 hardening control: the attack is entirely blocked by restricting perf_event_open to privileged callers. A working exploit — "vnik" by Vitaly Nikolenko — was released publicly at the time of disclosure and became widely referenced in the security community.
What Is the Linux Kernel perf_event Subsystem?
The Linux perf_event subsystem exposes hardware and software performance counters to userspace via the perf_event_open(2) syscall. It is used by profiling tools (perf, oprofile, application profilers) to measure CPU cycles, cache misses, context switches, and other kernel software events. By default, unprivileged users can call perf_event_open — a design choice that enables user-level profiling without root, but which also makes the perf_event code surface directly reachable by any local attacker.
Affected Versions
The vulnerability affects all Linux kernels in the 3.x series prior to the fix. Kernels in the 2.6.x series may also be affected depending on when the vulnerable code path was introduced.
| Kernel Branch | Vulnerable Range | Fixed Version |
|---|---|---|
| 3.8.x | All prior | 3.8.9 |
| 3.4.x | All prior | 3.4.44 |
| 3.2.x | All prior | 3.2.44 |
| 2.6.x | Various | Backport patches available |
Affected distributions (at time of disclosure, May 2013): Any Linux distribution shipping an unpatched 3.x kernel — including RHEL 6, Ubuntu 12.04 LTS, Debian 7, and their derivatives. The vulnerability predates all major cloud providers' "hardened" kernel offerings.
Technical Details
Root Cause: Unchecked 64-Bit Index into a Bounded Array
perf_event_open accepts a struct perf_event_attr from userspace, which includes a type field and a config field. When type is PERF_TYPE_SOFTWARE, config specifies which software counter to use (e.g., context switches, page faults). Internally, sw_perf_event_destroy() decrements perf_swevent_enabled[config] — an array of fixed size PERF_COUNT_SW_MAX (9 entries, covering the defined software event types).
The kernel's bounds check only examined the lower 32 bits of attr.config. An attacker could set the high 32 bits to any non-zero value, producing an out-of-range index that bypasses the check. With an appropriately crafted attr.config, the decrement in sw_perf_event_destroy lands at an attacker-controlled offset outside perf_swevent_enabled[], writing into arbitrary kernel memory.
/* Simplified vulnerable code */
u64 config = attr.config;
if (config >= PERF_COUNT_SW_MAX) /* Only 32-bit comparison — upper bits ignored */
return -EINVAL;
perf_swevent_enabled[config]--; /* Out-of-bounds if upper bits were set */
The fix (commit 8176cced706b) adds a proper check that rejects any attr.config value with non-zero upper bits or a lower value exceeding PERF_COUNT_SW_MAX.
The "Decrement Arbitrary Kernel Memory" Primitive
The -- decrement operation at an arbitrary kernel address provides a powerful exploitation primitive:
- Decrement a function pointer in a kernel data structure to redirect it to attacker-controlled code.
- Decrement the
uid/gidfields in the kernel'scredstructure for the current process from1000(typical user UID) toward0(root), across multiple exploit invocations. - Decrement a reference count or permission mask to enable a secondary exploitation path.
The "vnik" exploit by Vitaly Nikolenko used a series of crafted perf_event_open calls to systematically decrement the UID in the process's kernel credential structure to zero, obtaining a root shell without overwriting code or requiring ROP chains — an unusually clean primitive for 2013.
Why No Privileges Were Required
perf_event_open was accessible to any local user by default in 2013-era kernels. The kernel.perf_event_paranoid sysctl controls this:
| Value | Behavior |
|---|---|
-1 |
All users, no restrictions |
0 |
All users can use perf_event_open |
1 |
Unprivileged users can use perf_event_open for non-kernel events |
2 |
Requires CAP_SYS_ADMIN (or CAP_PERFMON on newer kernels) |
3 |
Requires CAP_SYS_ADMIN — blocks this CVE entirely |
Most distributions shipped with perf_event_paranoid = 1 or lower in 2013, leaving perf_event_open fully reachable by unprivileged attackers. This is why the CVSS score shows PR: None — no privileges were required.
Attack Characteristics
| Attribute | Detail |
|---|---|
| Attack Vector | Local — requires code execution on the target system |
| Privileges Required | None — perf_event_open was accessible to all users by default |
| Race Condition Required | No — deterministic |
| Mitigated by perf_event_paranoid=3 | Yes — completely blocks the syscall for unprivileged users |
| Exploit Reliability | High — "vnik" provides a clean, reliable UID-decrement primitive |
Discovery
The vulnerability was disclosed publicly on the oss-security mailing list on May 13, 2013, simultaneously with a working exploit. Vitaly Nikolenko (known as "vnik," github: vnik5287) published the exploit and provided technical analysis. The fix commit 8176cced706b was merged the same day. The rapid simultaneous disclosure-with-exploit left distributions scrambling to push emergency kernel updates.
Exploitation Context
- Public exploit: Released at time of disclosure; the "vnik" exploit became a widely-cited reference implementation for kernel credential-structure manipulation
- No prerequisites: Any local shell access on an unpatched system was sufficient; no module loading, no special kernel configuration required
- Historical significance: CVE-2013-2094 is frequently cited in KSPP discussions as the archetypal example of why
kernel.perf_event_paranoidmust be restricted — a default-open API exposing a bounded-array indexing flaw to all local users - CISA KEV added: September 15, 2022 — nearly a decade after disclosure — confirming that unpatched systems running old kernels remained actively exploited targets long after patches were available
Remediation
Immediate Mitigation: Restrict perf_event_open Access
Set kernel.perf_event_paranoid to 3 to require CAP_SYS_ADMIN for all perf_event_open calls:
sysctl -w kernel.perf_event_paranoid=3
echo "kernel.perf_event_paranoid = 3" >> /etc/sysctl.d/99-hardening.conf
This completely blocks unprivileged access to perf_event_open and eliminates the attack vector for CVE-2013-2094 and any future perf_event vulnerabilities that require unprivileged access. The impact on legitimate workloads is limited to user-space profiling tools (perf stat, application profilers running as non-root) — server workloads and container environments typically have no legitimate need for unprivileged perf access.
Recommended Actions
-
Update the kernel to a fixed version (3.8.9, 3.4.44, 3.2.44, or any later release). Systems running kernels this old should treat the hardware as end-of-life and prioritize migration.
-
Apply the
perf_event_paranoidsysctl immediately — this is the most impactful single control for this vulnerability class and remains a recommended hardening setting even on fully patched kernels. -
Audit other perf_event exposure: Even on patched kernels,
perf_eventhas been involved in multiple subsequent kernel LPEs. Restricting access toCAP_SYS_ADMINreduces the attack surface across the entire class. -
Harden the kernel baseline: The
kernel.perf_event_paranoid = 3control is one of several runtime sysctls in the KSPP hardening baseline that restrict high-risk interfaces. CVE-2013-2094 is the canonical historical example of why this control exists.
Key Details
| Property | Value |
|---|---|
| CVE ID | CVE-2013-2094 |
| Vendor / Product | Linux — Kernel |
| NVD Published | 2013-05-14 |
| NVD Last Modified | 2025-10-22 |
| CVSS 3.1 Score | 8.4 |
| CVSS 3.1 Vector | CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| Severity | HIGH |
| CWE | CWE-189 — Numeric Errors |
| CISA KEV Added | 2022-09-15 |
| CISA KEV Deadline | 2022-10-06 |
| Known Ransomware Use | No |
CVSS 3.1 Breakdown
Required Action
Timeline
| Date | Event |
|---|---|
| 2013-05-13 | Vulnerability disclosed on oss-security mailing list with working exploit |
| 2013-05-14 | CVE-2013-2094 published; kernel fix commit 8176cced merged |
| 2013-05-14 | Fixed kernel versions released: 3.8.9, 3.4.44, 3.2.44 |
| 2022-09-15 | Added to CISA Known Exploited Vulnerabilities catalog |
| 2022-10-06 | CISA BOD 22-01 remediation deadline |
References
| Resource | Type |
|---|---|
| NVD — CVE-2013-2094 | Vulnerability Database |
| CISA KEV Catalog Entry | US Government |
| Linux Kernel Fix Commit 8176cced — perf: fix perf_swevent_enabled bounds checking | Patch / Source Code |
| vnik CVE-2013-2094 Exploit — Vitaly Nikolenko | Security Research |
| oss-security: Linux kernel perf_swevent_enabled vulnerability disclosure | Security Research |
| Red Hat Security Advisory — CVE-2013-2094 | Vendor Advisory |
| CWE-189 — Numeric Errors | Weakness Classification |