
Script to check if system are vulnable to cve-2026-23111
CVE-2026-23111 is a Linux kernel vulnerability in nf_tables that can be exploited for local privilege escalation by an unprivileged user on systems where user namespaces and nftables are available.[1][2] Public vendor and government advisories describe it as a local issue affecting Linux distributions and emphasize patching as the primary fix.[3][4]
This repository contains a defensive validation script designed to help assess whether a host exposes the technical conditions associated with this CVE without delivering a privilege-escalation exploit. It checks for relevant kernel and runtime conditions, optionally loads the nf_tables module for full functional testing, attempts a controlled non-privileged validation path using unshare and nft, collects local diagnostic traces, and classifies the host into operational verdicts such as likely safe, blocked by local policy, or exposed path available.[1][5]
According to the NVD, CVE-2026-23111 is a Linux kernel nf_tables vulnerability resolved as a logic bug fix in netfilter and is exploitable for local privilege escalation from an unprivileged user through user namespaces and nftables on affected configurations.[1] Ubuntu’s security notice describes the same high-level exploitation path and tracks affected and fixed package states by release.[2]
Red Hat states that a local low-privileged user may exploit the issue to cause denial of service or potentially achieve privilege escalation, and it documents a mitigation path based on preventing the nf_tables module from loading when that is operationally acceptable.[3] National-level guidance from the Canadian Centre for Cyber Security also points affected organizations to vendor updates and mentions initramfs regeneration when module-blocking mitigations are used.[4]
The script is intended for defensive exposure assessment, not exploitation. It is designed to:
CONFIG_USER_NS and CONFIG_NF_TABLES appear to be present.[1]kernel.unprivileged_userns_clone and user.max_user_namespaces to estimate whether unprivileged user namespaces are available.install nf_tables /bin/false) or a weak blacklist is in place for the nf_tables module./proc/kallsyms for the vulnerable symbol (nft_map_catchall_activate) vs. the post-patch symbol (nft_catchall_set_activate) before any module interaction.nf_tables via modprobe when --allow-load-module is specified (see below), and unload it automatically at exit.unshare -U -n --map-root-user + nft validation step when the module is loaded, and record stdout, stderr, and recent kernel logs.unshare --user actually creates a namespace and that CAP_NET_ADMIN is functional inside it, to confirm whether AppArmor or SELinux restrictions are truly effective.The script stores logs in a child directory of the script directory and removes them by default unless --keep-logs is used.
By default the script never loads nf_tables. If the module is not already loaded when the script starts, all functional nft tests are skipped and the verdict is derived solely from kernel version, kallsyms fingerprint, modprobe configuration, RPM changelog, and sysctl/LSM policy evidence.
This conservative default avoids unintentionally expanding the attack surface on production hosts. To enable full functional testing on a controlled or instrumented system, use --allow-load-module as root (see below).
# Default — no module loading, policy-evidence-only verdict
./check_cve_2026_23111.sh
./check_cve_2026_23111.sh --color
./check_cve_2026_23111.sh --keep-logs
./check_cve_2026_23111.sh --color --keep-logs
# Full functional test — loads (and unloads) nf_tables, requires root
sudo ./check_cve_2026_23111.sh --allow-load-module
sudo ./check_cve_2026_23111.sh --allow-load-module --color --keep-logs
| Option | Description |
|---|---|
--allow-load-module | Authorize the script to load nf_tables via modprobe if the module is not already loaded. Enables the full nft catchall path exerciser and the CAP_NET_ADMIN effectiveness test. The module is unloaded automatically at exit. Requires root. Refused if a hard modprobe deny is already in place. Only use on non-production or instrumented systems. |
--color | Enable colorized stdout output when the terminal supports it. |
--keep-logs | Keep logs and traces under the script directory instead of deleting them at exit. |
--help | Print usage information and exit. |
--allow-load-moduleUse --allow-load-module when you need the highest-confidence verdict on an isolated, non-production, or purpose-built test VM. Typical scenarios:
Do not use --allow-load-module on production hosts where nf_tables is intentionally blocked or where loading it would violate a hardening policy.
--allow-load-moduleBefore attempting to load the module, the script enforces the following checks and exits with an error if any of them fail:
install nf_tables /bin/false) must not be present in /etc/modprobe.d/.modprobe must be available on the system.root (uid 0).If the module is successfully loaded by the script, modprobe -r nf_tables is called at exit via the cleanup() trap, regardless of how the script terminates (success, error, or CTRL+C).
The script uses operational verdicts rather than exploit outcomes:
| Verdict | Meaning |
|---|---|
not-affected | Kernel version is below 5.13; the catchall element feature was not yet introduced and the vulnerable code path is absent. |
likely-patched-vendor-confirmed | CVE-2026-23111 was found in the vendor kernel RPM changelog, confirming a backported fix regardless of upstream version. |
likely-patched-upstream-confirmed | Kernel version is in the patched upstream range and the functional nft test returned non-zero with no kernel signal — strongest static + dynamic evidence of a safe state. |
likely-patched-upstream | Kernel version is in a patched upstream range but functional test was not run (module absent, or inconclusive). Vendor advisory status should still be checked. |
likely-safe-or-patched | No exploitable path was confirmed by the script; cause is ambiguous between a patched kernel, absent vulnerable code, or implicit local block. |
blocked-by-local-policy | The tested path appears blocked by AppArmor, SELinux, user namespace restrictions, or a modprobe deny.[6] Policy blocks are not a substitute for the vendor fix. |
exposed-path-available | The host exposes a userns + nftables path compatible with the documented exploitation prerequisites.[1][5] |
strong-signal-lab-confirmation | A kernel log signal consistent with nf_tables-related memory corruption was observed. Confirm only in a disposable, instrumented lab. |
prerequisites-missing | Required diagnostic tools (unshare, nft) are missing; no meaningful runtime validation was completed. |