{
  "affected": [
    {
      "ecosystem_specific": {
        "urgency": "not yet assigned"
      },
      "package": {
        "ecosystem": "Debian:12",
        "name": "linux"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "ecosystem_specific": {
        "urgency": "not yet assigned"
      },
      "package": {
        "ecosystem": "Debian:13",
        "name": "linux"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "6.12.111-1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "ecosystem_specific": {
        "urgency": "not yet assigned"
      },
      "package": {
        "ecosystem": "Debian:14",
        "name": "linux"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "details": "In the Linux kernel, the following vulnerability has been resolved:  net/sched: cls_u32: fix duplicate handle when node ID pool is exhausted  gen_new_kid() falls back to returning max (htid | 0xFFF) when both idr_alloc_u32() ranges are full, instead of reporting an error. u32_change() trusts that value and inserts a new knode with a handle that is already live in the hash table, breaking handle uniqueness within the table's node ID space.  The handle was never reserved in ht-\u003ehandle_idr, so every later error path that does idr_remove(\u0026ht-\u003ehandle_idr, handle) removes the reservation of a different, live knode, which is then reused — one failed add compounds into further duplicates.  The 4095 limit is per (table, bucket) — ht-\u003ehandle_idr is per hash table and the range is derived from htid (bucketid), so a table with divisor 256 can legitimately hold 256*4095 knodes.  The sibling helper gen_new_htid() has the same silent in-band failure: it returns 0 when the tp_c handle pool (1..0x7FF) is full, and u32_init() publishes the root hash table with handle 0 without checking.  Two root tables with handle 0 alias in u32_lookup_ht(), allowing cross-tcf_proto knode add/lookup/delete.  Add the same exhaustion check that the divisor path already has.  Return an error so u32_change() fails with ENOSPC/ENOMEM when the node ID space is exhausted, and so u32_init() fails with -ENOMEM when the hash table ID space is exhausted.  The extack message distinguishes pool exhaustion (-ENOSPC) from a transient allocation failure (-ENOMEM).  Conditions to recreate the bug: - CONFIG_NET_SCHED=y, CONFIG_CLS_U32=y (or =m with module loaded) - Create a clsact qdisc on a device, then add 4095 u32 filters with   auto-generated handles to fill the node ID space for the root hash   table (single bucket). The 4096th auto-handle filter add triggers   the duplicate handle (fh 800::fff reused). Reachable at Level 2   (unshare -Urn, namespace-local CAP_NET_ADMIN). - For gen_new_htid: create 2047 u32 proto entries on the same block   to fill the tp_c handle pool, then create one more. The root table   gets handle 0 and aliases with other handle-0 root tables.",
  "id": "DEBIAN-CVE-2026-98104",
  "modified": "2026-09-29T10:47:30.893717800Z",
  "published": "2026-09-25T11:17:40.793Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://security-tracker.debian.org/tracker/CVE-2026-98104"
    }
  ],
  "upstream": [
    "CVE-2026-98104"
  ]
}