CVE-2026-98368 (GCVE-0-2026-98368)
Vulnerability from cvelistv5
Published
2026-10-06 08:46
Modified
2026-10-19 09:18
Summary
In the Linux kernel, the following vulnerability has been resolved: esp: downgrade zerocopy managed frags before mutating skb frags On the out-of-place output path (esp->inplace == false) ESP rewrites the skb frag array: esp_output_head() appends a trailer frag and esp_output_tail() replaces the frags with a destination page, both referenced with get_page(). When the skb carries zerocopy managed frags (SKBFL_MANAGED_FRAG_REFS) the payload frags are owned by the ubuf and must not be referenced or unreferenced individually, but ESP mutates the frag array without ever downgrading the skb. This breaks the managed-frag invariant two ways: - esp_ssg_unref() walks the source scatterlist and drops a page reference for every frag, including the ubuf-owned payload frags, pushing their refcount below the GUP pin bias while the pages are still pinned, i.e. a use-after-free of the zerocopy pages; - esp_output_tail() installs its destination page as frag 0 with get_page() but leaves SKBFL_MANAGED_FRAG_REFS set, so skb_release_data() takes the skip_unref branch and never drops that reference, leaking the x->xfrag page at packet rate. Fix this the way every other frag-mutating site does (__ip_append_data(), __ip6_append_data(), tcp_sendmsg_locked()) and call skb_zcopy_downgrade_managed() before ESP touches the frag array: it takes a real reference on each existing frag and clears SKBFL_MANAGED_FRAG_REFS, so the per-frag unref in esp_ssg_unref() and the frag release in skb_release_data() are both balanced and no mixed-ownership frag array is left behind.
Impacted products
Vendor Product Version
Linux Linux Version: 753f1ca4e1e50248a1b760c9774d6d6b354562cc
Version: 753f1ca4e1e50248a1b760c9774d6d6b354562cc
Version: 753f1ca4e1e50248a1b760c9774d6d6b354562cc
Version: 753f1ca4e1e50248a1b760c9774d6d6b354562cc
Version: 753f1ca4e1e50248a1b760c9774d6d6b354562cc
Version: 753f1ca4e1e50248a1b760c9774d6d6b354562cc
Create a notification for this product.
Show details on NVD website


{
  "containers": {
    "cna": {
      "affected": [
        {
          "defaultStatus": "unaffected",
          "product": "Linux",
          "programFiles": [
            "net/ipv4/esp4.c",
            "net/ipv6/esp6.c"
          ],
          "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
          "vendor": "Linux",
          "versions": [
            {
              "lessThan": "2359264f377cdbdef2d95868cc8fb572949e48d3",
              "status": "affected",
              "version": "753f1ca4e1e50248a1b760c9774d6d6b354562cc",
              "versionType": "git"
            },
            {
              "lessThan": "69a768c12398cada8528080332c822623fa7064d",
              "status": "affected",
              "version": "753f1ca4e1e50248a1b760c9774d6d6b354562cc",
              "versionType": "git"
            },
            {
              "lessThan": "6508304ac2c8cdafca2f4ab915df8c707893e134",
              "status": "affected",
              "version": "753f1ca4e1e50248a1b760c9774d6d6b354562cc",
              "versionType": "git"
            },
            {
              "lessThan": "6cab554f2c0f28773f712ed3a5479103f42ce844",
              "status": "affected",
              "version": "753f1ca4e1e50248a1b760c9774d6d6b354562cc",
              "versionType": "git"
            },
            {
              "lessThan": "0d0845ee61c5df47cc68bc446501f48f71e8dcc6",
              "status": "affected",
              "version": "753f1ca4e1e50248a1b760c9774d6d6b354562cc",
              "versionType": "git"
            },
            {
              "lessThan": "f89416eb3db151170a6f3c6dfc5239d26cdce4d2",
              "status": "affected",
              "version": "753f1ca4e1e50248a1b760c9774d6d6b354562cc",
              "versionType": "git"
            }
          ]
        },
        {
          "defaultStatus": "affected",
          "product": "Linux",
          "programFiles": [
            "net/ipv4/esp4.c",
            "net/ipv6/esp6.c"
          ],
          "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
          "vendor": "Linux",
          "versions": [
            {
              "status": "affected",
              "version": "6.0"
            },
            {
              "lessThan": "6.0",
              "status": "unaffected",
              "version": "0",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "6.1.*",
              "status": "unaffected",
              "version": "6.1.189",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "6.6.*",
              "status": "unaffected",
              "version": "6.6.158",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "6.12.*",
              "status": "unaffected",
              "version": "6.12.112",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "6.18.*",
              "status": "unaffected",
              "version": "6.18.54",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "7.2.*",
              "status": "unaffected",
              "version": "7.2.8",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "*",
              "status": "unaffected",
              "version": "7.3",
              "versionType": "original_commit_for_fix"
            }
          ]
        }
      ],
      "cpeApplicability": [
        {
          "nodes": [
            {
              "cpeMatch": [
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "6.1.189",
                  "versionStartIncluding": "6.0",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "6.6.158",
                  "versionStartIncluding": "6.0",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "6.12.112",
                  "versionStartIncluding": "6.0",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "6.18.54",
                  "versionStartIncluding": "6.0",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "7.2.8",
                  "versionStartIncluding": "6.0",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "7.3",
                  "versionStartIncluding": "6.0",
                  "vulnerable": true
                }
              ],
              "negate": false,
              "operator": "OR"
            }
          ]
        }
      ],
      "descriptions": [
        {
          "lang": "en",
          "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nesp: downgrade zerocopy managed frags before mutating skb frags\n\nOn the out-of-place output path (esp-\u003einplace == false) ESP rewrites the\nskb frag array: esp_output_head() appends a trailer frag and\nesp_output_tail() replaces the frags with a destination page, both\nreferenced with get_page().\n\nWhen the skb carries zerocopy managed frags (SKBFL_MANAGED_FRAG_REFS) the\npayload frags are owned by the ubuf and must not be referenced or\nunreferenced individually, but ESP mutates the frag array without ever\ndowngrading the skb.  This breaks the managed-frag invariant two ways:\n\n  - esp_ssg_unref() walks the source scatterlist and drops a page\n    reference for every frag, including the ubuf-owned payload frags,\n    pushing their refcount below the GUP pin bias while the pages are\n    still pinned, i.e. a use-after-free of the zerocopy pages;\n\n  - esp_output_tail() installs its destination page as frag 0 with\n    get_page() but leaves SKBFL_MANAGED_FRAG_REFS set, so\n    skb_release_data() takes the skip_unref branch and never drops that\n    reference, leaking the x-\u003exfrag page at packet rate.\n\nFix this the way every other frag-mutating site does (__ip_append_data(),\n__ip6_append_data(), tcp_sendmsg_locked()) and call\nskb_zcopy_downgrade_managed() before ESP touches the frag array: it takes\na real reference on each existing frag and clears SKBFL_MANAGED_FRAG_REFS,\nso the per-frag unref in esp_ssg_unref() and the frag release in\nskb_release_data() are both balanced and no mixed-ownership frag array is\nleft behind."
        }
      ],
      "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 - Managed frags are set only by io_uring\u0027s io_sg_from_iter() for IORING_OP_SEND_ZC/SENDMSG_ZC with IORING_RECVSEND_FIXED_BUF, so a local process must submit the zerocopy send that esp_output_head()/esp6_output_head() then mutates; a remote peer cannot produce a SKBFL_MANAGED_FRAG_REFS skb.\nAC:L - The attacker picks every input: an uncloned UDP skb whose data_len+tailen fits in a page and lacks tailroom reliably takes the esp-\u003einplace=false branch, then esp_ssg_unref() drops refs on the ubuf-owned frags. No race or outside state is needed.\nPR:L - io_uring zerocopy send needs no privilege. The ESP SA/policy can be added inside an unprivileged user+net namespace because xfrm_user_rcv_msg only checks netlink_net_capable(CAP_NET_ADMIN); on a host with IPsec already set up, any local user\u0027s traffic hits it.\nUI:N - The attacker does everything with their own io_uring ring, registered buffer, socket and (namespaced) xfrm state; no other user has to act.\nS:U - The page refcount underflow and the freed page stay inside the kernel\u0027s own authority, so this is a normal local privilege escalation with no VM or sandbox boundary crossed.\nC:H - esp_ssg_unref() pushes the pinned registered-buffer pages\u0027 refcount below the GUP pin bias, so the page is freed while io_uring still has it mapped; once reallocated (e.g. as page tables or slab) the attacker can read kernel memory through the stale buffer.\nI:H - Writing through the still-registered fixed buffer into the freed and reallocated page is a page-level use-after-free write primitive (Dirty-Pagetable style), enough for arbitrary kernel memory corruption and privilege escalation.\nA:H - The page UAF leads to bad-page/refcount oopses, and the missing put_page on the x-\u003exfrag page installed by esp_output_tail() leaks memory at packet rate; both can take the system down."
            }
          ]
        }
      ],
      "providerMetadata": {
        "dateUpdated": "2026-10-19T09:18:20.253Z",
        "orgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
        "shortName": "Linux"
      },
      "references": [
        {
          "url": "https://git.kernel.org/stable/c/2359264f377cdbdef2d95868cc8fb572949e48d3"
        },
        {
          "url": "https://git.kernel.org/stable/c/69a768c12398cada8528080332c822623fa7064d"
        },
        {
          "url": "https://git.kernel.org/stable/c/6508304ac2c8cdafca2f4ab915df8c707893e134"
        },
        {
          "url": "https://git.kernel.org/stable/c/6cab554f2c0f28773f712ed3a5479103f42ce844"
        },
        {
          "url": "https://git.kernel.org/stable/c/0d0845ee61c5df47cc68bc446501f48f71e8dcc6"
        },
        {
          "url": "https://git.kernel.org/stable/c/f89416eb3db151170a6f3c6dfc5239d26cdce4d2"
        }
      ],
      "title": "esp: downgrade zerocopy managed frags before mutating skb frags",
      "x_generator": {
        "engine": "bippy-1.2.0"
      }
    }
  },
  "cveMetadata": {
    "assignerOrgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
    "assignerShortName": "Linux",
    "cveId": "CVE-2026-98368",
    "datePublished": "2026-10-06T08:46:53.292Z",
    "dateReserved": "2026-09-25T10:25:14.344Z",
    "dateUpdated": "2026-10-19T09:18:20.253Z",
    "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…