CVE-2025-38675 (GCVE-0-2025-38675)
Vulnerability from cvelistv5
Published
2025-08-22 16:04
Modified
2026-08-05 12:03
Summary
In the Linux kernel, the following vulnerability has been resolved: xfrm: state: initialize state_ptrs earlier in xfrm_state_find In case of preemption, xfrm_state_look_at will find a different pcpu_id and look up states for that other CPU. If we matched a state for CPU2 in the state_cache while the lookup started on CPU1, we will jump to "found", but the "best" state that we got will be ignored and we will enter the "acquire" block. This block uses state_ptrs, which isn't initialized at this point. Let's initialize state_ptrs just after taking rcu_read_lock. This will also prevent a possible misuse in the future, if someone adjusts this function.
Impacted products
Vendor Product Version
Linux Linux Version: a16871c7832ea6435abb6e0b58289ae7dcb7e4fc
Version: e952837f3ddb0ff726d5b582aa1aad9aa38d024d
Version: e952837f3ddb0ff726d5b582aa1aad9aa38d024d
Version: b86dc510308d7a8955f3f47a4fea4bef887653e4
Version: dd4c2a174994238d55ab54da2545543d36f4e0d0
Version: 6.12.13   
Version: 6.6.120   
Version: 6.13.2   
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": "6bf2daafc51bcb9272c0fdff2afd38217337d0d3",
              "status": "affected",
              "version": "a16871c7832ea6435abb6e0b58289ae7dcb7e4fc",
              "versionType": "git"
            },
            {
              "lessThan": "463562f9591742be62ddde3b426a0533ed496955",
              "status": "affected",
              "version": "e952837f3ddb0ff726d5b582aa1aad9aa38d024d",
              "versionType": "git"
            },
            {
              "lessThan": "94d077c331730510d5611b438640a292097341f0",
              "status": "affected",
              "version": "e952837f3ddb0ff726d5b582aa1aad9aa38d024d",
              "versionType": "git"
            },
            {
              "status": "affected",
              "version": "b86dc510308d7a8955f3f47a4fea4bef887653e4",
              "versionType": "git"
            },
            {
              "status": "affected",
              "version": "dd4c2a174994238d55ab54da2545543d36f4e0d0",
              "versionType": "git"
            },
            {
              "lessThan": "6.12.41",
              "status": "affected",
              "version": "6.12.13",
              "versionType": "semver"
            },
            {
              "lessThan": "6.7",
              "status": "affected",
              "version": "6.6.120",
              "versionType": "semver"
            },
            {
              "lessThan": "6.14",
              "status": "affected",
              "version": "6.13.2",
              "versionType": "semver"
            }
          ]
        },
        {
          "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": "6.14"
            },
            {
              "lessThan": "6.14",
              "status": "unaffected",
              "version": "0",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "6.12.*",
              "status": "unaffected",
              "version": "6.12.41",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "6.15.*",
              "status": "unaffected",
              "version": "6.15.9",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "*",
              "status": "unaffected",
              "version": "6.16",
              "versionType": "original_commit_for_fix"
            }
          ]
        }
      ],
      "cpeApplicability": [
        {
          "nodes": [
            {
              "cpeMatch": [
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "6.12.41",
                  "versionStartIncluding": "6.12.13",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "6.15.9",
                  "versionStartIncluding": "6.14",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "6.16",
                  "versionStartIncluding": "6.14",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionStartIncluding": "6.6.120",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionStartIncluding": "6.13.2",
                  "vulnerable": true
                }
              ],
              "negate": false,
              "operator": "OR"
            }
          ]
        }
      ],
      "descriptions": [
        {
          "lang": "en",
          "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nxfrm: state: initialize state_ptrs earlier in xfrm_state_find\n\nIn case of preemption, xfrm_state_look_at will find a different\npcpu_id and look up states for that other CPU. If we matched a state\nfor CPU2 in the state_cache while the lookup started on CPU1, we will\njump to \"found\", but the \"best\" state that we got will be ignored and\nwe will enter the \"acquire\" block. This block uses state_ptrs, which\nisn\u0027t initialized at this point.\n\nLet\u0027s initialize state_ptrs just after taking rcu_read_lock. This will\nalso prevent a possible misuse in the future, if someone adjusts this\nfunction."
        }
      ],
      "metrics": [
        {
          "cvssV3_1": {
            "baseScore": 7.8,
            "baseSeverity": "HIGH",
            "vectorString": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
            "version": "3.1"
          },
          "scenarios": [
            {
              "lang": "en",
              "value": "AV:L - The vulnerable code is the IPsec transmit path (`xfrm_lookup` \u2192 `xfrm_tmpl_resolve_one` \u2192 `xfrm_state_find`), reached by a local task sending packets plus xfrm netlink configuration of the policy/SAs. The remote forwarding path also calls this function but executes with preemption disabled in softirq, so the CPU-migration window required to skip `xfrm_hash_ptrs_get()` is only reachable from local, preemptible process context.\nAC:L - The attacker controls both sides of the race: it installs the `XFRM_POLICY_CPU_ACQUIRE` policy and the per-CPU SAs that populate `state_cache_list`, then re-triggers the lookup unboundedly by sending packets from many threads while driving scheduler churn (load, `sched_setaffinity`) to force the migration between the two `get_cpu()` reads. syzbot hit it by fuzzing alone, showing no attacker-uncontrollable precondition is involved.\nPR:L - Installing the per-CPU-acquire policy and SAs goes through `xfrm_user_rcv_msg()`, guarded by `netlink_net_capable(skb, CAP_NET_ADMIN)`, which resolves to `ns_capable()` against the netns\u0027s user namespace \u2014 so an unprivileged user obtains it with `unshare -Urn` and then sends the triggering traffic in their own netns.\nUI:N - The attacker performs every step itself \u2014 netlink policy/SA setup and packet transmission \u2014 with no action by any other user or administrator.\nS:U - The uninitialized-pointer dereference and any resulting corruption stay within the kernel\u0027s own security authority; no VM, IOMMU, or sandbox boundary is crossed.\nC:H - `__xfrm_state_lookup_all()` dereferences the uninitialized `state_ptrs-\u003ebyspi` at an offset masked by an uninitialized `hmask` (up to ~2^32 entries), producing an unbounded read of arbitrary kernel memory that is then interpreted as a `struct xfrm_state`; the read result observably steers control flow (`-EEXIST` vs. new acquire), and the stack residue can be groomed to point at attacker-chosen kernel objects.\nI:H - On a field match the wild \"state\" is passed to `xfrm_state_hold_rcu()` (`refcount_inc_not_zero`) and then `xfrm_state_put()` (`refcount_dec_and_test` \u2192 `__xfrm_state_destroy`), giving increment/decrement writes at an uncontrolled kernel address and linking a fabricated object onto the global GC list where `___xfrm_state_destroy()` later invokes its destructor pointers and frees it \u2014 a control-flow-hijack-capable corruption primitive.\nA:H - In the overwhelmingly common case the garbage `byspi` pointer plus huge `hmask`-derived offset lands on unmapped memory, causing an immediate oops/GPF (or KASAN wild-memory-access) in the IPsec output path, which is exactly what syzbot reported."
            }
          ]
        }
      ],
      "providerMetadata": {
        "dateUpdated": "2026-08-05T12:03:52.536Z",
        "orgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
        "shortName": "Linux"
      },
      "references": [
        {
          "url": "https://git.kernel.org/stable/c/6bf2daafc51bcb9272c0fdff2afd38217337d0d3"
        },
        {
          "url": "https://git.kernel.org/stable/c/463562f9591742be62ddde3b426a0533ed496955"
        },
        {
          "url": "https://git.kernel.org/stable/c/94d077c331730510d5611b438640a292097341f0"
        }
      ],
      "title": "xfrm: state: initialize state_ptrs earlier in xfrm_state_find",
      "x_generator": {
        "engine": "bippy-1.2.0"
      }
    }
  },
  "cveMetadata": {
    "assignerOrgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
    "assignerShortName": "Linux",
    "cveId": "CVE-2025-38675",
    "datePublished": "2025-08-22T16:04:12.688Z",
    "dateReserved": "2025-04-16T04:51:24.031Z",
    "dateUpdated": "2026-08-05T12:03:52.536Z",
    "state": "PUBLISHED"
  },
  "dataType": "CVE_RECORD",
  "dataVersion": "5.2"
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Sightings

Author Source Type Date

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or seen somewhere by the user.
  • Confirmed: The vulnerability is confirmed from an analyst perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: This vulnerability was exploited and seen by the user reporting the sighting.
  • Patched: This vulnerability was successfully patched by the user reporting the sighting.
  • Not exploited: This vulnerability was not exploited or seen by the user reporting the sighting.
  • Not confirmed: The user expresses doubt about the veracity of the vulnerability.
  • Not patched: This vulnerability was not successfully patched by the user reporting the sighting.


Loading…

Loading…