FlawOpen

flawopen.com/Teardowns/cve-2024-1086-linux-netfilter-nftables-uaf

● CVE-2024-1086 · CVSS 7.8 · High
FlawOpen Security Research

CVE-2024-1086: Linux nf_tables Use-After-Free

CVE-2024-1086: Linux nf_tables use-after-free from invalid DROP parameters. Install your distribution’s fixed kernel; package versions vary.

💡 Plain English Explainer (ELI5)

Imagine a form where a clerk must choose exactly one approved outcome: “accept” or “drop.” The form also has a small field for a drop error code, where only zero or a negative error belongs. The vulnerable validator let a positive “accept” value slip into that error field, so later packet-handling code interpreted the same verdict inconsistently. The kernel patch closes the boundary by accepting only the exact supported verdict values.

Core Concepts & Subsystem Terms

nf_tables
The Linux kernel subsystem used by nftables to configure packet filtering and related network rules.
Netfilter verdict
A result returned while the kernel evaluates a packet rule, such as NF_ACCEPT or NF_DROP. A DROP verdict may carry an error value, which the hook code expects to be zero or a valid negative errno.
Use-after-free (CWE-416)
A memory-safety flaw where code accesses an object after its lifetime has ended. In this case, NVD records a local kernel privilege-escalation vulnerability.
User namespace
A Linux namespace that maps identities and capabilities for processes. Whether an unprivileged user can create one depends on kernel and distribution policy; namespace access is a precondition in some reported attack paths, not a guarantee of host escape.

Framework mappings

Root Cause Analysis

In net/netfilter/nf_tables_api.c, nft_verdict_init() previously masked verdict values with NF_VERDICT_MASK and allowed parameters for NF_DROP or NF_QUEUE. The netfilter hook expects the upper bits of an NF_DROP verdict to encode zero or a valid negative errno. The upstream fix notes that a positive value such as NF_ACCEPT could therefore produce a use-after-free. The patch removes the permissive masked-value path and accepts only the exact supported verdicts; invalid values return -EINVAL. CVE/NVD describes local privilege escalation. Reachability depends on the running kernel, available capabilities, and distribution policy; do not assume every container configuration is affected in the same way.

Step-by-Step Attack Flow

Step 1

Local rule-management capability

The documented attack is local. The process must be able to reach the vulnerable nf_tables verdict-validation path; the required capabilities and whether unprivileged user namespaces are enabled depend on the host configuration.

Step 2

Invalid verdict parameter reaches validation

Before the fix, nft_verdict_init() accepted certain parameterized verdict values after masking them with NF_VERDICT_MASK, including a positive value such as NF_ACCEPT in the parameter bits.

Step 3

Hook handling reaches the use-after-free

The netfilter hook interprets NF_DROP parameters as zero or a valid negative errno. The upstream report states that the accepted positive value can cause a use-after-free during packet processing; the patch does not document a universal exploit primitive or guaranteed container escape.

Step 4

Install the distribution’s fixed kernel

The upstream change rejects unsupported verdict parameters. Install and boot the vendor-provided fixed kernel, because distributions backport fixes and package version mappings differ.

Source Code: Flaw vs. Secure Implementation

The vulnerable code masks the verdict value and falls through, allowing parameterized values such as a positive NF_ACCEPT in an NF_DROP error field. The fix admits only the exact verdict constants and returns -EINVAL for every other value. These are focused excerpts from the upstream patch, not standalone compilable functions.

Source excerpt: net/netfilter/nf_tables_api.c

UNPATCHED FLAW
/* Excerpt from nft_verdict_init() in net/netfilter/nf_tables_api.c, before f342de4e2f33.
 * The masked-value path accepted parameterized verdicts. */
switch (data->verdict.code) {
default:
    switch (data->verdict.code & NF_VERDICT_MASK) {
    case NF_ACCEPT:
    case NF_DROP:
    case NF_QUEUE:
        break;
    default:
        return -EINVAL;
    }
    fallthrough;
case NFT_CONTINUE:
case NFT_BREAK:
case NFT_RETURN:
    /* Other existing verdict handling follows. */
    break;
}
HARDENED SECURE PATCH
/* Excerpt from nft_verdict_init() in net/netfilter/nf_tables_api.c,
 * as changed by f342de4e2f33. */
switch (data->verdict.code) {
case NF_ACCEPT:
case NF_DROP:
case NF_QUEUE:
    break;
case NFT_CONTINUE:
case NFT_BREAK:
case NFT_RETURN:
    /* Other existing verdict handling follows. */
    break;
default:
    return -EINVAL;
}

Engineering & System Hardening Checklist

Sources