CVE-2026-46116 (GCVE-0-2026-46116)

Vulnerability from cvelistv5 – Published: 2026-05-28 09:35 – Updated: 2026-05-28 09:35
VLAI
Title
xfrm: defensively unhash xfrm_state lists in __xfrm_state_delete
Summary
In the Linux kernel, the following vulnerability has been resolved: xfrm: defensively unhash xfrm_state lists in __xfrm_state_delete KASAN reproduces a slab-use-after-free in __xfrm_state_delete()'s hlist_del_rcu calls under syzkaller load on linux-6.12.y stable (reproduced on 6.12.47, also reachable via the same code path on torvalds/master and on the ipsec tree). Nine unique signatures cluster in the xfrm_state lifecycle, the load-bearing one being: BUG: KASAN: slab-use-after-free in __hlist_del include/linux/list.h:990 [inline] BUG: KASAN: slab-use-after-free in hlist_del_rcu include/linux/rculist.h:516 [inline] BUG: KASAN: slab-use-after-free in __xfrm_state_delete net/xfrm/xfrm_state.c Write of size 8 at addr ffff8881198bcb70 by task kworker/u8:9/435 Workqueue: netns cleanup_net Call Trace: __hlist_del / hlist_del_rcu __xfrm_state_delete xfrm_state_delete xfrm_state_flush xfrm_state_fini ops_exit_list cleanup_net The other observed signatures hit the same slab object from __xfrm_state_lookup, xfrm_alloc_spi, __xfrm_state_insert and an OOB write variant of __xfrm_state_delete, all on the byseq/byspi hash chains. __xfrm_state_delete() guards its byseq and byspi unhashes with value-based predicates: if (x->km.seq) hlist_del_rcu(&x->byseq); if (x->id.spi) hlist_del_rcu(&x->byspi); while everywhere else in the file (e.g. state_cache, state_cache_input) the safer hlist_unhashed() check is used. xfrm_alloc_spi() sets x->id.spi = newspi inside xfrm_state_lock and then immediately inserts into byspi, but a path that observes x->id.spi != 0 outside of xfrm_state_lock can still skip-or-hit the byspi unhash inconsistently with whether x is actually on the list. The same holds for x->km.seq versus byseq, and the bydst/bysrc unhashes have no predicate at all, so a second __xfrm_state_delete() on the same object writes through LIST_POISON pprev. The defensive change here: - Use hlist_del_init_rcu() instead of hlist_del_rcu() on bydst, bysrc, byseq and byspi so a second deletion is a no-op rather than a write through LIST_POISON pprev. The byseq/byspi nodes are already initialised in xfrm_state_alloc(). - Test hlist_unhashed() rather than the value predicate for byseq/byspi, so the unhash decision tracks list state rather than mutable scalar fields. Empirical verification: applied this patch on top of v6.12.47, rebuilt, and re-ran the same syzkaller harness for 1h16m on a previously-crashy configuration that produced ~100 hits each of slab-use-after-free Read in xfrm_alloc_spi / Read in __xfrm_state_lookup / Write in __xfrm_state_delete. After the patch, 7.1M execs across 32 VMs at ~1550 exec/sec produced zero xfrm_state UAF/OOB hits. /proc/slabinfo confirms the xfrm_state slab is actively allocated and freed during the run (~143 KiB resident), so the fuzzer is still exercising those code paths -- they just no longer crash. Reproduction: - Linux 6.12.47 x86_64 + KASAN_GENERIC + KASAN_INLINE + KCOV - syzkaller @ 746545b8b1e4c3a128db8652b340d3df90ce61db - 32 QEMU/KVM VMs x 2 vCPU on AWS c5.metal bare metal - 9 unique signatures collected in ~9h, all within xfrm_state lifecycle
Severity
No CVSS data available.
Assigner
Impacted products
Vendor Product Version
Linux Linux Affected: 7b4dc3600e4877178ba94c7fbf7e520421378aa6 , < b4a53add2fa8f1b5aa17d4c5686c320785fab182 (git)
Affected: 7b4dc3600e4877178ba94c7fbf7e520421378aa6 , < 26edb0a3c99f9d958c212be68b21f1221614dcf0 (git)
Affected: 7b4dc3600e4877178ba94c7fbf7e520421378aa6 , < 4980162de555cb838f1a189ce7d2cbf5d2e7b050 (git)
Affected: 7b4dc3600e4877178ba94c7fbf7e520421378aa6 , < a2e2d08fb070fab4947447171f1c4e3ca5a188e5 (git)
Affected: 7b4dc3600e4877178ba94c7fbf7e520421378aa6 , < 14acf9652e5690de3c7486c6db5fb8dafd0a32a3 (git)
Create a notification for this product.
Linux Linux Affected: 2.6.19
Unaffected: 0 , < 2.6.19 (semver)
Unaffected: 6.6.140 , ≤ 6.6.* (semver)
Unaffected: 6.12.88 , ≤ 6.12.* (semver)
Unaffected: 6.18.30 , ≤ 6.18.* (semver)
Unaffected: 7.0.7 , ≤ 7.0.* (semver)
Unaffected: 7.1-rc3 , ≤ * (original_commit_for_fix)
Create a notification for this product.
Show details on NVD website

{
  "containers": {
    "cna": {
      "affected": [
        {
          "defaultStatus": "unaffected",
          "product": "Linux",
          "programFiles": [
            "net/xfrm/xfrm_state.c"
          ],
          "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
          "vendor": "Linux",
          "versions": [
            {
              "lessThan": "b4a53add2fa8f1b5aa17d4c5686c320785fab182",
              "status": "affected",
              "version": "7b4dc3600e4877178ba94c7fbf7e520421378aa6",
              "versionType": "git"
            },
            {
              "lessThan": "26edb0a3c99f9d958c212be68b21f1221614dcf0",
              "status": "affected",
              "version": "7b4dc3600e4877178ba94c7fbf7e520421378aa6",
              "versionType": "git"
            },
            {
              "lessThan": "4980162de555cb838f1a189ce7d2cbf5d2e7b050",
              "status": "affected",
              "version": "7b4dc3600e4877178ba94c7fbf7e520421378aa6",
              "versionType": "git"
            },
            {
              "lessThan": "a2e2d08fb070fab4947447171f1c4e3ca5a188e5",
              "status": "affected",
              "version": "7b4dc3600e4877178ba94c7fbf7e520421378aa6",
              "versionType": "git"
            },
            {
              "lessThan": "14acf9652e5690de3c7486c6db5fb8dafd0a32a3",
              "status": "affected",
              "version": "7b4dc3600e4877178ba94c7fbf7e520421378aa6",
              "versionType": "git"
            }
          ]
        },
        {
          "defaultStatus": "affected",
          "product": "Linux",
          "programFiles": [
            "net/xfrm/xfrm_state.c"
          ],
          "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
          "vendor": "Linux",
          "versions": [
            {
              "status": "affected",
              "version": "2.6.19"
            },
            {
              "lessThan": "2.6.19",
              "status": "unaffected",
              "version": "0",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "6.6.*",
              "status": "unaffected",
              "version": "6.6.140",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "6.12.*",
              "status": "unaffected",
              "version": "6.12.88",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "6.18.*",
              "status": "unaffected",
              "version": "6.18.30",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "7.0.*",
              "status": "unaffected",
              "version": "7.0.7",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "*",
              "status": "unaffected",
              "version": "7.1-rc3",
              "versionType": "original_commit_for_fix"
            }
          ]
        }
      ],
      "cpeApplicability": [
        {
          "nodes": [
            {
              "cpeMatch": [
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "6.6.140",
                  "versionStartIncluding": "2.6.19",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "6.12.88",
                  "versionStartIncluding": "2.6.19",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "6.18.30",
                  "versionStartIncluding": "2.6.19",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "7.0.7",
                  "versionStartIncluding": "2.6.19",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "7.1-rc3",
                  "versionStartIncluding": "2.6.19",
                  "vulnerable": true
                }
              ],
              "negate": false,
              "operator": "OR"
            }
          ]
        }
      ],
      "descriptions": [
        {
          "lang": "en",
          "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nxfrm: defensively unhash xfrm_state lists in __xfrm_state_delete\n\nKASAN reproduces a slab-use-after-free in __xfrm_state_delete()\u0027s\nhlist_del_rcu calls under syzkaller load on linux-6.12.y stable\n(reproduced on 6.12.47, also reachable via the same code path on\ntorvalds/master and on the ipsec tree). Nine unique signatures cluster\nin the xfrm_state lifecycle, the load-bearing one being:\n\n  BUG: KASAN: slab-use-after-free in __hlist_del include/linux/list.h:990 [inline]\n  BUG: KASAN: slab-use-after-free in hlist_del_rcu include/linux/rculist.h:516 [inline]\n  BUG: KASAN: slab-use-after-free in __xfrm_state_delete net/xfrm/xfrm_state.c\n  Write of size 8 at addr ffff8881198bcb70 by task kworker/u8:9/435\n\n  Workqueue: netns cleanup_net\n  Call Trace:\n   __hlist_del / hlist_del_rcu\n   __xfrm_state_delete\n   xfrm_state_delete\n   xfrm_state_flush\n   xfrm_state_fini\n   ops_exit_list\n   cleanup_net\n\nThe other observed signatures hit the same slab object from\n__xfrm_state_lookup, xfrm_alloc_spi, __xfrm_state_insert and an OOB\nwrite variant of __xfrm_state_delete, all on the byseq/byspi\nhash chains.\n\n__xfrm_state_delete() guards its byseq and byspi unhashes with\nvalue-based predicates:\n\n\tif (x-\u003ekm.seq)\n\t\thlist_del_rcu(\u0026x-\u003ebyseq);\n\tif (x-\u003eid.spi)\n\t\thlist_del_rcu(\u0026x-\u003ebyspi);\n\nwhile everywhere else in the file (e.g. state_cache, state_cache_input)\nthe safer hlist_unhashed() check is used. xfrm_alloc_spi() sets\nx-\u003eid.spi = newspi inside xfrm_state_lock and then immediately inserts\ninto byspi, but a path that observes x-\u003eid.spi != 0 outside of\nxfrm_state_lock can still skip-or-hit the byspi unhash inconsistently\nwith whether x is actually on the list. The same holds for x-\u003ekm.seq\nversus byseq, and the bydst/bysrc unhashes have no predicate at all,\nso a second __xfrm_state_delete() on the same object writes through\nLIST_POISON pprev.\n\nThe defensive change here:\n\n  - Use hlist_del_init_rcu() instead of hlist_del_rcu() on bydst,\n    bysrc, byseq and byspi so a second deletion is a no-op rather\n    than a write through LIST_POISON pprev. The byseq/byspi nodes\n    are already initialised in xfrm_state_alloc().\n  - Test hlist_unhashed() rather than the value predicate for\n    byseq/byspi, so the unhash decision tracks list state rather than\n    mutable scalar fields.\n\nEmpirical verification: applied this patch on top of v6.12.47, rebuilt,\nand re-ran the same syzkaller harness for 1h16m on a previously-crashy\nconfiguration that produced ~100 hits each of slab-use-after-free\nRead in xfrm_alloc_spi / Read in __xfrm_state_lookup / Write in\n__xfrm_state_delete. After the patch, 7.1M execs across 32 VMs at\n~1550 exec/sec produced zero xfrm_state UAF/OOB hits. /proc/slabinfo\nconfirms the xfrm_state slab is actively allocated and freed during\nthe run (~143 KiB resident), so the fuzzer is still exercising those\ncode paths -- they just no longer crash.\n\nReproduction:\n\n  - Linux 6.12.47 x86_64 + KASAN_GENERIC + KASAN_INLINE + KCOV\n  - syzkaller @ 746545b8b1e4c3a128db8652b340d3df90ce61db\n  - 32 QEMU/KVM VMs x 2 vCPU on AWS c5.metal bare metal\n  - 9 unique signatures collected in ~9h, all within xfrm_state\n    lifecycle"
        }
      ],
      "providerMetadata": {
        "dateUpdated": "2026-05-28T09:35:30.689Z",
        "orgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
        "shortName": "Linux"
      },
      "references": [
        {
          "url": "https://git.kernel.org/stable/c/b4a53add2fa8f1b5aa17d4c5686c320785fab182"
        },
        {
          "url": "https://git.kernel.org/stable/c/26edb0a3c99f9d958c212be68b21f1221614dcf0"
        },
        {
          "url": "https://git.kernel.org/stable/c/4980162de555cb838f1a189ce7d2cbf5d2e7b050"
        },
        {
          "url": "https://git.kernel.org/stable/c/a2e2d08fb070fab4947447171f1c4e3ca5a188e5"
        },
        {
          "url": "https://git.kernel.org/stable/c/14acf9652e5690de3c7486c6db5fb8dafd0a32a3"
        }
      ],
      "title": "xfrm: defensively unhash xfrm_state lists in __xfrm_state_delete",
      "x_generator": {
        "engine": "bippy-1.2.0"
      }
    }
  },
  "cveMetadata": {
    "assignerOrgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
    "assignerShortName": "Linux",
    "cveId": "CVE-2026-46116",
    "datePublished": "2026-05-28T09:35:30.689Z",
    "dateReserved": "2026-05-13T15:03:33.098Z",
    "dateUpdated": "2026-05-28T09:35:30.689Z",
    "state": "PUBLISHED"
  },
  "dataType": "CVE_RECORD",
  "dataVersion": "5.2",
  "vulnerability-lookup:meta": {
    "epss": {
      "cve": "CVE-2026-46116",
      "date": "2026-05-29",
      "epss": "0.00018",
      "percentile": "0.05164"
    },
    "nvd": "{\"cve\":{\"id\":\"CVE-2026-46116\",\"sourceIdentifier\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\",\"published\":\"2026-05-28T10:16:27.080\",\"lastModified\":\"2026-05-28T13:44:01.663\",\"vulnStatus\":\"Awaiting Analysis\",\"cveTags\":[],\"descriptions\":[{\"lang\":\"en\",\"value\":\"In the Linux kernel, the following vulnerability has been resolved:\\n\\nxfrm: defensively unhash xfrm_state lists in __xfrm_state_delete\\n\\nKASAN reproduces a slab-use-after-free in __xfrm_state_delete()\u0027s\\nhlist_del_rcu calls under syzkaller load on linux-6.12.y stable\\n(reproduced on 6.12.47, also reachable via the same code path on\\ntorvalds/master and on the ipsec tree). Nine unique signatures cluster\\nin the xfrm_state lifecycle, the load-bearing one being:\\n\\n  BUG: KASAN: slab-use-after-free in __hlist_del include/linux/list.h:990 [inline]\\n  BUG: KASAN: slab-use-after-free in hlist_del_rcu include/linux/rculist.h:516 [inline]\\n  BUG: KASAN: slab-use-after-free in __xfrm_state_delete net/xfrm/xfrm_state.c\\n  Write of size 8 at addr ffff8881198bcb70 by task kworker/u8:9/435\\n\\n  Workqueue: netns cleanup_net\\n  Call Trace:\\n   __hlist_del / hlist_del_rcu\\n   __xfrm_state_delete\\n   xfrm_state_delete\\n   xfrm_state_flush\\n   xfrm_state_fini\\n   ops_exit_list\\n   cleanup_net\\n\\nThe other observed signatures hit the same slab object from\\n__xfrm_state_lookup, xfrm_alloc_spi, __xfrm_state_insert and an OOB\\nwrite variant of __xfrm_state_delete, all on the byseq/byspi\\nhash chains.\\n\\n__xfrm_state_delete() guards its byseq and byspi unhashes with\\nvalue-based predicates:\\n\\n\\tif (x-\u003ekm.seq)\\n\\t\\thlist_del_rcu(\u0026x-\u003ebyseq);\\n\\tif (x-\u003eid.spi)\\n\\t\\thlist_del_rcu(\u0026x-\u003ebyspi);\\n\\nwhile everywhere else in the file (e.g. state_cache, state_cache_input)\\nthe safer hlist_unhashed() check is used. xfrm_alloc_spi() sets\\nx-\u003eid.spi = newspi inside xfrm_state_lock and then immediately inserts\\ninto byspi, but a path that observes x-\u003eid.spi != 0 outside of\\nxfrm_state_lock can still skip-or-hit the byspi unhash inconsistently\\nwith whether x is actually on the list. The same holds for x-\u003ekm.seq\\nversus byseq, and the bydst/bysrc unhashes have no predicate at all,\\nso a second __xfrm_state_delete() on the same object writes through\\nLIST_POISON pprev.\\n\\nThe defensive change here:\\n\\n  - Use hlist_del_init_rcu() instead of hlist_del_rcu() on bydst,\\n    bysrc, byseq and byspi so a second deletion is a no-op rather\\n    than a write through LIST_POISON pprev. The byseq/byspi nodes\\n    are already initialised in xfrm_state_alloc().\\n  - Test hlist_unhashed() rather than the value predicate for\\n    byseq/byspi, so the unhash decision tracks list state rather than\\n    mutable scalar fields.\\n\\nEmpirical verification: applied this patch on top of v6.12.47, rebuilt,\\nand re-ran the same syzkaller harness for 1h16m on a previously-crashy\\nconfiguration that produced ~100 hits each of slab-use-after-free\\nRead in xfrm_alloc_spi / Read in __xfrm_state_lookup / Write in\\n__xfrm_state_delete. After the patch, 7.1M execs across 32 VMs at\\n~1550 exec/sec produced zero xfrm_state UAF/OOB hits. /proc/slabinfo\\nconfirms the xfrm_state slab is actively allocated and freed during\\nthe run (~143 KiB resident), so the fuzzer is still exercising those\\ncode paths -- they just no longer crash.\\n\\nReproduction:\\n\\n  - Linux 6.12.47 x86_64 + KASAN_GENERIC + KASAN_INLINE + KCOV\\n  - syzkaller @ 746545b8b1e4c3a128db8652b340d3df90ce61db\\n  - 32 QEMU/KVM VMs x 2 vCPU on AWS c5.metal bare metal\\n  - 9 unique signatures collected in ~9h, all within xfrm_state\\n    lifecycle\"}],\"metrics\":{},\"references\":[{\"url\":\"https://git.kernel.org/stable/c/14acf9652e5690de3c7486c6db5fb8dafd0a32a3\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\"},{\"url\":\"https://git.kernel.org/stable/c/26edb0a3c99f9d958c212be68b21f1221614dcf0\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\"},{\"url\":\"https://git.kernel.org/stable/c/4980162de555cb838f1a189ce7d2cbf5d2e7b050\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\"},{\"url\":\"https://git.kernel.org/stable/c/a2e2d08fb070fab4947447171f1c4e3ca5a188e5\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\"},{\"url\":\"https://git.kernel.org/stable/c/b4a53add2fa8f1b5aa17d4c5686c320785fab182\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\"}]}}"
  }
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

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.

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…