GHSA-JH9M-9MR6-3GHC
Vulnerability from github – Published: 2026-02-13 15:30 – Updated: 2026-02-13 15:30In the Linux kernel, the following vulnerability has been resolved:
netfilter: nf_tables: fix inverted genmask check in nft_map_catchall_activate()
nft_map_catchall_activate() has an inverted element activity check compared to its non-catchall counterpart nft_mapelem_activate() and compared to what is logically required.
nft_map_catchall_activate() is called from the abort path to re-activate catchall map elements that were deactivated during a failed transaction. It should skip elements that are already active (they don't need re-activation) and process elements that are inactive (they need to be restored). Instead, the current code does the opposite: it skips inactive elements and processes active ones.
Compare the non-catchall activate callback, which is correct:
nft_mapelem_activate(): if (nft_set_elem_active(ext, iter->genmask)) return 0; / skip active, process inactive /
With the buggy catchall version:
nft_map_catchall_activate(): if (!nft_set_elem_active(ext, genmask)) continue; / skip inactive, process active /
The consequence is that when a DELSET operation is aborted, nft_setelem_data_activate() is never called for the catchall element. For NFT_GOTO verdict elements, this means nft_data_hold() is never called to restore the chain->use reference count. Each abort cycle permanently decrements chain->use. Once chain->use reaches zero, DELCHAIN succeeds and frees the chain while catchall verdict elements still reference it, resulting in a use-after-free.
This is exploitable for local privilege escalation from an unprivileged user via user namespaces + nftables on distributions that enable CONFIG_USER_NS and CONFIG_NF_TABLES.
Fix by removing the negation so the check matches nft_mapelem_activate(): skip active elements, process inactive ones.
{
"affected": [],
"aliases": [
"CVE-2026-23111"
],
"database_specific": {
"cwe_ids": [],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-02-13T14:16:10Z",
"severity": null
},
"details": "In the Linux kernel, the following vulnerability has been resolved:\n\nnetfilter: nf_tables: fix inverted genmask check in nft_map_catchall_activate()\n\nnft_map_catchall_activate() has an inverted element activity check\ncompared to its non-catchall counterpart nft_mapelem_activate() and\ncompared to what is logically required.\n\nnft_map_catchall_activate() is called from the abort path to re-activate\ncatchall map elements that were deactivated during a failed transaction.\nIt should skip elements that are already active (they don\u0027t need\nre-activation) and process elements that are inactive (they need to be\nrestored). Instead, the current code does the opposite: it skips inactive\nelements and processes active ones.\n\nCompare the non-catchall activate callback, which is correct:\n\n nft_mapelem_activate():\n if (nft_set_elem_active(ext, iter-\u003egenmask))\n return 0; /* skip active, process inactive */\n\nWith the buggy catchall version:\n\n nft_map_catchall_activate():\n if (!nft_set_elem_active(ext, genmask))\n continue; /* skip inactive, process active */\n\nThe consequence is that when a DELSET operation is aborted,\nnft_setelem_data_activate() is never called for the catchall element.\nFor NFT_GOTO verdict elements, this means nft_data_hold() is never\ncalled to restore the chain-\u003euse reference count. Each abort cycle\npermanently decrements chain-\u003euse. Once chain-\u003euse reaches zero,\nDELCHAIN succeeds and frees the chain while catchall verdict elements\nstill reference it, resulting in a use-after-free.\n\nThis is exploitable for local privilege escalation from an unprivileged\nuser via user namespaces + nftables on distributions that enable\nCONFIG_USER_NS and CONFIG_NF_TABLES.\n\nFix by removing the negation so the check matches nft_mapelem_activate():\nskip active elements, process inactive ones.",
"id": "GHSA-jh9m-9mr6-3ghc",
"modified": "2026-02-13T15:30:26Z",
"published": "2026-02-13T15:30:26Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-23111"
},
{
"type": "WEB",
"url": "https://git.kernel.org/stable/c/1444ff890b4653add12f734ffeffc173d42862dd"
},
{
"type": "WEB",
"url": "https://git.kernel.org/stable/c/42c574c1504aa089a0a142e4c13859327570473d"
},
{
"type": "WEB",
"url": "https://git.kernel.org/stable/c/8b68a45f9722f2babe9e7bad00aa74638addf081"
},
{
"type": "WEB",
"url": "https://git.kernel.org/stable/c/8c760ba4e36c750379d13569f23f5a6e185333f5"
},
{
"type": "WEB",
"url": "https://git.kernel.org/stable/c/b9b6573421de51829f7ec1cce76d85f5f6fbbd7f"
},
{
"type": "WEB",
"url": "https://git.kernel.org/stable/c/f41c5d151078c5348271ffaf8e7410d96f2d82f8"
}
],
"schema_version": "1.4.0",
"severity": []
}
Sightings
| Author | Source | Type | Date |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.