{
  "schemaVersion": 1,
  "attribution": [
    {
      "source": "CISA Known Exploited Vulnerabilities",
      "url": "https://www.cisa.gov/known-exploited-vulnerabilities-catalog",
      "licence": "US government work"
    },
    {
      "source": "GitHub Advisory Database",
      "url": "https://github.com/advisories",
      "licence": "CC BY 4.0"
    },
    {
      "source": "Have I Been Pwned",
      "url": "https://haveibeenpwned.com/",
      "licence": "CC BY 4.0"
    },
    {
      "source": "CVE Program (CVE records)",
      "url": "https://www.cve.org/Legal/TermsOfUse",
      "licence": "CVE Terms of Use",
      "notice": "Copyright © 1999-2026, The MITRE Corporation. CVE is a trademark and the CVE logo is a registered trademark of The MITRE Corporation.",
      "terms": "CVE Usage: MITRE hereby grants you a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute Common Vulnerabilities and Exposures (CVE™). Any copy you make for such purposes is authorized provided that you reproduce MITRE's copyright designation and this license in any such copy."
    },
    {
      "source": "FIRST EPSS",
      "url": "https://www.first.org/epss/",
      "licence": "free to use; FIRST requests attribution"
    }
  ],
  "record": {
    "id": "CVE-2026-98797",
    "sourceURL": "https://www.cve.org/CVERecord?id=CVE-2026-98797",
    "idYear": 2026,
    "status": "PUBLISHED",
    "publishedAt": "2026-10-18T15:48:41.613Z",
    "updatedAt": "2026-10-19T09:25:49.920Z",
    "importedAt": "2026-10-24T01:58:41.756Z",
    "snapshot": {
      "id": "cve_2026-10-24_midnight_baseline",
      "at": "2026-10-24T00:00:00.000Z",
      "source": "https://github.com/CVEProject/cvelistV5/releases/tag/cve_2026-10-24_0100Z"
    },
    "facts": {
      "title": "net: cap skb->queue_mapping when the tx queue is picked",
      "summary": "In the Linux kernel, the following vulnerability has been resolved:\n\nnet: cap skb->queue_mapping when the tx queue is picked\n\nskbedit can set skb->queue_mapping and raise the per-CPU skip_txqueue\nflag so __dev_queue_xmit() honours the mapping. __dev_queue_xmit()\ncleared the flag before sch_handle_egress() and only read it afterwards,\nso the flag was not confined to the xmit that set it: a nested xmit\n(mirred redirect or mirror, or a drop after skbedit) could set the flag\nand the outer xmit would consume it for an skb that never went through\nskbedit.\n\nA forwarded packet still carries the ingress NIC's rx_queue + 1 in\nskb->queue_mapping, so the outer device then indexes its tx queue state\nwith that stale value. Taprio's child array q->qdiscs[] is sized to the\ndevice's queue count, so taprio_enqueue() indexes past its allocation\nand dereferences the result as a struct Qdisc *.\n\nWe (ab)use the skb->nf_skip_egress which means \"skip netfilter egress\nfor this packet\" to tag to \"am I in tc egress?\". Despite the overload\nI dont see it as a conflict since the marker is set only around the\nsingle sch_handle_egress() call and ingress path is guarded by\ntc_at_ingress.\nI will send a followup(net-next) patch once this hits net-next to\nrename the skb->nf_skip_egress bit/flag to skb->skip_egress\n\nArm the flag only from the egress classifier that can use it: raise\nskip_txqueue from tcf_skbedit_act() only when it runs inside\nsch_handle_egress(), thanks to skb->nf_skip_egress. An egress qdisc\nclassifier runs in q->enqueue(), after the tx queue has been picked,\nso a mapping it sets cannot affect the current packet; arming the flag\nthere only pollutes it for a later xmit. Then own the flag for the xmit\nframe the egress hook runs in: save the incoming value and clear it just\nbefore sch_handle_egress(), and restore it after the hook - on the\nconsumed (drop) path, or, in the same call that reads it, on the\nsurviving path. The save and the restores stay inside the\negress_needed_key static branch, so a packet pays for them only when\negress hooks are active (2f1e85b1aee4).\n\nStore the value netdev_cap_txqueue() selected back into skb->queue_mapping\nin netdev_tx_queue_mapping(), as netdev_core_pick_tx() already does, so\nthe skip_txqueue path never hands a later reader on the xmit path a\nmapping the device cannot serve. A store made still later in the same\nframe, by a tc BPF program attached to a transmit qdisc, is outside this\npath and is not re-capped; a separate followup will resolve that path.\n\nnetdev_xmit_skip_txqueue() returns the previous flag value so the\nsave-and-clear is one call, and a no-op stub is provided when\nCONFIG_NET_EGRESS is disabled. skb->nf_skip_egress is compiled under\nCONFIG_NET_EGRESS rather than CONFIG_NETFILTER_SKIP_EGRESS, so\nskb_at_tc_egress() is valid whenever the egress path is built.\n\nA local user in a network namespace can redirect a packet from a device\nwith more TX queues to one with fewer after setting a mapping valid only\non the larger device. That reaches these reads and, under KASAN, faults\nwith \"slab-out-of-bounds in taprio_enqueue\".\n\nConditions to recreate the bug: the report's own trigger is a local user\nwith CAP_NET_ADMIN in a network namespace, so no eBPF program is needed.\nWith CONFIG_NET_SCH_TAPRIO=y, CONFIG_NET_ACT_SKBEDIT=y,\nCONFIG_NET_ACT_MIRRED=y, CONFIG_NET_CLS_MATCHALL=y,\nCONFIG_NET_SCH_PRIO=y and KASAN enabled, create qa (3 queues), qb\n(2 queues) and qc (1 queue) as dummy devices; put a taprio root on qb\n(num_tc 1, queues 2@0) and clsact on all three; then add an egress\nmatchall filter on every device. On qa: \"action skbedit queue_mapping 2\npipe action mirred egress redirect dev qb\". On qb: \"action mirred egress\nmirror dev qc\". On qc: \"action skbedit queue_mapping 0 pipe\". Send one\npacket out qa. qc's skbedit sets the flag while qb's outer xmit is in\nflight; without the fix qb consumes it and reads its two-entry taprio\nchild array with the forwarded packet's stale mapping. A qc whose\nskb\n---truncated---",
      "affected": [
        {
          "vendor": "Linux",
          "product": "Linux",
          "defaultStatus": "unaffected",
          "versions": [
            {
              "version": "2f1e85b1aee459b7d0fd981839042c6a38ffaf0c",
              "status": "affected",
              "versionType": "git",
              "lessThan": "c6ec35c8267c84c2094cb485db20c06384fc2bcc"
            },
            {
              "version": "2f1e85b1aee459b7d0fd981839042c6a38ffaf0c",
              "status": "affected",
              "versionType": "git",
              "lessThan": "2f581814e4e3ea6a5e98f49813dc4c68444a0c4a"
            },
            {
              "version": "2f1e85b1aee459b7d0fd981839042c6a38ffaf0c",
              "status": "affected",
              "versionType": "git",
              "lessThan": "f99de42f5c6f8d088063817dad82c3334e87c570"
            },
            {
              "version": "2f1e85b1aee459b7d0fd981839042c6a38ffaf0c",
              "status": "affected",
              "versionType": "git",
              "lessThan": "ea4d4b5dddb5121e64f56fd8e0720bd8b447b63d"
            }
          ]
        },
        {
          "vendor": "Linux",
          "product": "Linux",
          "defaultStatus": "affected",
          "versions": [
            {
              "version": "5.19",
              "status": "affected"
            },
            {
              "version": "0",
              "status": "unaffected",
              "versionType": "semver",
              "lessThan": "5.19"
            },
            {
              "version": "6.12.113",
              "status": "unaffected",
              "versionType": "semver",
              "lessThanOrEqual": "6.12.*"
            },
            {
              "version": "6.18.56",
              "status": "unaffected",
              "versionType": "semver",
              "lessThanOrEqual": "6.18.*"
            },
            {
              "version": "7.2.10",
              "status": "unaffected",
              "versionType": "semver",
              "lessThanOrEqual": "7.2.*"
            },
            {
              "version": "7.3",
              "status": "unaffected",
              "versionType": "original_commit_for_fix",
              "lessThanOrEqual": "*"
            }
          ]
        }
      ]
    }
  }
}