{"id":29258,"date":"2026-09-25T20:32:16","date_gmt":"2026-09-25T12:32:16","guid":{"rendered":"https:\/\/www.54iter.cn\/?vuln=cve-2026-98104"},"modified":"2026-09-25T20:32:16","modified_gmt":"2026-09-25T12:32:16","slug":"cve-2026-98104","status":"publish","type":"vuln","link":"https:\/\/www.54iter.cn\/?vuln=cve-2026-98104","title":{"rendered":"CVE-2026-98104 &#8211; In the Linux kernel, the following vulnerability has been resolved:\n\nnet\/sched: cls_u32: f"},"content":{"rendered":"<p>In the Linux kernel, the following vulnerability has been resolved:<\/p>\n<p>net\/sched: cls_u32: fix duplicate handle when node ID pool is exhausted<\/p>\n<p>gen_new_kid() falls back to returning max (htid | 0xFFF) when both<br \/>\nidr_alloc_u32() ranges are full, instead of reporting an error.<br \/>\nu32_change() trusts that value and inserts a new knode with a handle<br \/>\nthat is already live in the hash table, breaking handle uniqueness<br \/>\nwithin the table&#8217;s node ID space.<\/p>\n<p>The handle was never reserved in ht-&gt;handle_idr, so every later error<br \/>\npath that does idr_remove(&amp;ht-&gt;handle_idr, handle) removes the<br \/>\nreservation of a different, live knode, which is then reused \u2014 one<br \/>\nfailed add compounds into further duplicates.<\/p>\n<p>The 4095 limit is per (table, bucket) \u2014 ht-&gt;handle_idr is per hash<br \/>\ntable and the range is derived from htid (bucketid), so a table with<br \/>\ndivisor 256 can legitimately hold 256*4095 knodes.<\/p>\n<p>The sibling helper gen_new_htid() has the same silent in-band failure:<br \/>\nit returns 0 when the tp_c handle pool (1..0x7FF) is full, and<br \/>\nu32_init() publishes the root hash table with handle 0 without<br \/>\nchecking.  Two root tables with handle 0 alias in u32_lookup_ht(),<br \/>\nallowing cross-tcf_proto knode add\/lookup\/delete.  Add the same<br \/>\nexhaustion check that the divisor path already has.<\/p>\n<p>Return an error so u32_change() fails with ENOSPC\/ENOMEM when the<br \/>\nnode ID space is exhausted, and so u32_init() fails with -ENOMEM<br \/>\nwhen the hash table ID space is exhausted.  The extack message<br \/>\ndistinguishes pool exhaustion (-ENOSPC) from a transient allocation<br \/>\nfailure (-ENOMEM).<\/p>\n<p>Conditions to recreate the bug:<br \/>\n&#8211; CONFIG_NET_SCHED=y, CONFIG_CLS_U32=y (or =m with module loaded)<br \/>\n&#8211; Create a clsact qdisc on a device, then add 4095 u32 filters with<br \/>\n  auto-generated handles to fill the node ID space for the root hash<br \/>\n  table (single bucket). The 4096th auto-handle filter add triggers<br \/>\n  the duplicate handle (fh 800::fff reused). Reachable at Level 2<br \/>\n  (unshare -Urn, namespace-local CAP_NET_ADMIN).<br \/>\n&#8211; For gen_new_htid: create 2047 u32 proto entries on the same block<br \/>\n  to fill the tp_c handle pool, then create one more. The root table<br \/>\n  gets handle 0 and aliases with other handle-0 root tables.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the Linux kernel, the following vulnerability has been resolved:<\/p>\n<p>net\/sched: cls_u32: fix duplicate handle when node ID pool is exhausted<\/p>\n<p>gen_new_kid() falls back to returning max (htid | 0xFFF) w<\/p>\n","protected":false},"template":"","meta":[],"categories":[],"tags":[],"class_list":["post-29258","vuln","type-vuln","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/vuln\/29258","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/vuln"}],"about":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/types\/vuln"}],"wp:attachment":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=29258"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=29258"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=29258"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}