CVE-2026-93105 (GCVE-0-2026-93105)

Vulnerability from cvelistv5 – Published: 2026-09-17 16:11 – Updated: 2026-09-18 17:55
VLAI
Title
esp: do not unref managed frag pages in esp_ssg_unref()
Summary
In the Linux kernel, the following vulnerability has been resolved: esp: do not unref managed frag pages in esp_ssg_unref() esp_ssg_unref() releases the page references held on the source scatterlist after the AEAD operation completes. It calls skb_page_unref() on every frag page for an out-of-place transform (req->src != req->dst), and in the error path of esp_output_tail() (already_unref == true) on the request's own scatterlist. This is wrong when the skb carries managed frags (SKBFL_MANAGED_FRAG_REFS). Managed frags are owned by a zerocopy ubuf and the skb does not hold a per-frag page reference; io_uring SEND_ZC with a registered buffer attaches the bvec pages this way via io_sg_from_iter(). The rest of the stack honours this invariant: skb_release_data() skips the per-frag unref when SKBFL_MANAGED_FRAG_REFS is set, and skb_zcopy_managed() is the guard used at the other unref sites. esp_ssg_unref() is missing that guard, so for a managed-frag skb it drops a page reference the skb never acquired. This can underflow the page reference count and free a page that is still in use. Guard the function with skb_zcopy_managed() so both unref paths are skipped for managed-frag skbs, matching skb_release_data().
Impacted products
Vendor Product Version CPE status
Linux Linux Affected: cac2661c53f35cbe651bef9b07026a5a05ab8ce0 , < 26b6b14c7a0368e317a1e9fb5144ebe6f8d495cf (git)
Affected: cac2661c53f35cbe651bef9b07026a5a05ab8ce0 , < 21697720ff43b8dfa25b8e8d9ca7f56f4597fc80 (git)
guessed Create a notification for this product.
Linux Linux Affected: 4.11
Unaffected: 0 , < 4.11 (semver)
Unaffected: 7.2.6 , ≤ 7.2.* (semver)
Unaffected: 7.3-rc1 , ≤ * (original_commit_for_fix)
guessed 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": "26b6b14c7a0368e317a1e9fb5144ebe6f8d495cf",
              "status": "affected",
              "version": "cac2661c53f35cbe651bef9b07026a5a05ab8ce0",
              "versionType": "git"
            },
            {
              "lessThan": "21697720ff43b8dfa25b8e8d9ca7f56f4597fc80",
              "status": "affected",
              "version": "cac2661c53f35cbe651bef9b07026a5a05ab8ce0",
              "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": "4.11"
            },
            {
              "lessThan": "4.11",
              "status": "unaffected",
              "version": "0",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "7.2.*",
              "status": "unaffected",
              "version": "7.2.6",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "*",
              "status": "unaffected",
              "version": "7.3-rc1",
              "versionType": "original_commit_for_fix"
            }
          ]
        }
      ],
      "cpeApplicability": [
        {
          "nodes": [
            {
              "cpeMatch": [
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "7.2.6",
                  "versionStartIncluding": "4.11",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "7.3-rc1",
                  "versionStartIncluding": "4.11",
                  "vulnerable": true
                }
              ],
              "negate": false,
              "operator": "OR"
            }
          ]
        }
      ],
      "descriptions": [
        {
          "lang": "en",
          "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nesp: do not unref managed frag pages in esp_ssg_unref()\n\nesp_ssg_unref() releases the page references held on the source\nscatterlist after the AEAD operation completes.  It calls\nskb_page_unref() on every frag page for an out-of-place transform\n(req-\u003esrc != req-\u003edst), and in the error path of esp_output_tail()\n(already_unref == true) on the request\u0027s own scatterlist.\n\nThis is wrong when the skb carries managed frags\n(SKBFL_MANAGED_FRAG_REFS).  Managed frags are owned by a zerocopy ubuf\nand the skb does not hold a per-frag page reference; io_uring SEND_ZC\nwith a registered buffer attaches the bvec pages this way via\nio_sg_from_iter().  The rest of the stack honours this invariant:\nskb_release_data() skips the per-frag unref when SKBFL_MANAGED_FRAG_REFS\nis set, and skb_zcopy_managed() is the guard used at the other unref\nsites.\n\nesp_ssg_unref() is missing that guard, so for a managed-frag skb it\ndrops a page reference the skb never acquired.  This can underflow the\npage reference count and free a page that is still in use.\n\nGuard the function with skb_zcopy_managed() so both unref paths are\nskipped for managed-frag skbs, matching skb_release_data()."
        }
      ],
      "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 extra unref is reached from IORING_OP_SEND_ZC/SENDMSG_ZC with IORING_RECVSEND_FIXED_BUF: io_sendmsg_zc() -\u003e sock_sendmsg() -\u003e tcp_sendmsg_locked() -\u003e xfrm_output() -\u003e esp_output_tail() -\u003e esp_ssg_unref(). io_sg_from_iter() is the only site that sets SKBFL_MANAGED_FRAG_REFS; esp_input() never calls esp_ssg_unref(), so a remote ESP packet cannot supply the buggy skb.\nAC:L - tcp_stream_alloc_skb() allocates MAX_TCP_HEADER then skb_reserve()s all of it, so a SEND_ZC TCP skb has ~0 tailroom. esp_output_head() therefore takes inplace=false (tailen \u003e tailroom, nr_frags \u003c MAX_SKB_FRAGS, data_len+tailen \u003c= PAGE_SIZE), after which esp_output_tail() replaces the frags and esp_ssg_unref() always drops the managed pages. The attacker chooses the send size.\nPR:L - io_uring_setup() allows IORING_OP_SEND_ZC when sysctl_io_uring_disabled==0 (default); no capability is checked on that send path. An ESP SA is also required: the attacker can add one in a user+net namespace because xfrm_user_rcv_msg() only tests netlink_net_capable(CAP_NET_ADMIN) against the netns user_ns, or can send through an already-installed IPsec policy.\nUI:N - The attacker registers the buffer with IORING_REGISTER_BUFFERS, submits SEND_ZC, and if needed installs the XFRM state/policy; no other user must open a file, mount a volume, or otherwise act.\nS:U - esp_ssg_unref()\u0027s extra put_page() corrupts host kernel page refcounts. That is a conventional local privilege escalation inside the same kernel, not a KVM/Xen guest-to-host or IOMMU-scope change.\nC:H - After the out-of-place transform, esp_ssg_unref() calls skb_page_unref() on every source sg page past skb-\u003edata. Those pages were attached by io_sg_from_iter() without a per-frag get_page(), so the extra put underflows the refcount of still-mapped IORING_REGISTER_BUFFERS pages and frees memory the attacker can read.\nI:H - The same extra skb_page_unref() frees registered-buffer pages that remain in the io_uring bvec and the attacker\u0027s userspace mapping, so the page can be reallocated and overwritten, giving an arbitrary write and control-flow hijack.\nA:H - The extra put_page() on managed frag pages underflows the page refcount and frees a page still in use, which oopses with bad page state even when the use-after-free is not turned into a full memory-corruption exploit."
            }
          ]
        }
      ],
      "providerMetadata": {
        "dateUpdated": "2026-09-18T17:55:56.276Z",
        "orgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
        "shortName": "Linux"
      },
      "references": [
        {
          "url": "https://git.kernel.org/stable/c/26b6b14c7a0368e317a1e9fb5144ebe6f8d495cf"
        },
        {
          "url": "https://git.kernel.org/stable/c/21697720ff43b8dfa25b8e8d9ca7f56f4597fc80"
        }
      ],
      "title": "esp: do not unref managed frag pages in esp_ssg_unref()",
      "x_generator": {
        "engine": "bippy-1.2.0"
      }
    }
  },
  "cveMetadata": {
    "assignerOrgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
    "assignerShortName": "Linux",
    "cveId": "CVE-2026-93105",
    "datePublished": "2026-09-17T16:11:16.442Z",
    "dateReserved": "2026-09-17T16:02:15.085Z",
    "dateUpdated": "2026-09-18T17:55:56.276Z",
    "state": "PUBLISHED"
  },
  "dataType": "CVE_RECORD",
  "dataVersion": "5.2",
  "vulnerability-lookup:meta": {
    "epss": {
      "cve": "CVE-2026-93105",
      "date": "2026-09-29",
      "epss": "0.00165",
      "percentile": "0.05078"
    },
    "microsoft_vex": {
      "current_release_date": "2026-09-23T02:17:05.000Z",
      "cve": "CVE-2026-93105",
      "id": "msrc_CVE-2026-93105",
      "initial_release_date": "2026-09-19T01:16:23.000Z",
      "product_status:known_affected": "2",
      "source": "Microsoft CSAF VEX",
      "status": "final",
      "title": "esp: do not unref managed frag pages in esp_ssg_unref()",
      "url": "https://msrc.microsoft.com/csaf/vex/2026/msrc_cve-2026-93105.json",
      "version": "2"
    },
    "nvd": {
      "cve": {
        "affected": [
          {
            "affectedData": [
              {
                "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": "26b6b14c7a0368e317a1e9fb5144ebe6f8d495cf",
                    "status": "affected",
                    "version": "cac2661c53f35cbe651bef9b07026a5a05ab8ce0",
                    "versionType": "git"
                  },
                  {
                    "lessThan": "21697720ff43b8dfa25b8e8d9ca7f56f4597fc80",
                    "status": "affected",
                    "version": "cac2661c53f35cbe651bef9b07026a5a05ab8ce0",
                    "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": "4.11"
                  },
                  {
                    "lessThan": "4.11",
                    "status": "unaffected",
                    "version": "0",
                    "versionType": "semver"
                  },
                  {
                    "lessThanOrEqual": "7.2.*",
                    "status": "unaffected",
                    "version": "7.2.6",
                    "versionType": "semver"
                  },
                  {
                    "lessThanOrEqual": "*",
                    "status": "unaffected",
                    "version": "7.3-rc1",
                    "versionType": "original_commit_for_fix"
                  }
                ]
              }
            ],
            "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
          }
        ],
        "cveTags": [],
        "descriptions": [
          {
            "lang": "en",
            "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nesp: do not unref managed frag pages in esp_ssg_unref()\n\nesp_ssg_unref() releases the page references held on the source\nscatterlist after the AEAD operation completes.  It calls\nskb_page_unref() on every frag page for an out-of-place transform\n(req-\u003esrc != req-\u003edst), and in the error path of esp_output_tail()\n(already_unref == true) on the request\u0027s own scatterlist.\n\nThis is wrong when the skb carries managed frags\n(SKBFL_MANAGED_FRAG_REFS).  Managed frags are owned by a zerocopy ubuf\nand the skb does not hold a per-frag page reference; io_uring SEND_ZC\nwith a registered buffer attaches the bvec pages this way via\nio_sg_from_iter().  The rest of the stack honours this invariant:\nskb_release_data() skips the per-frag unref when SKBFL_MANAGED_FRAG_REFS\nis set, and skb_zcopy_managed() is the guard used at the other unref\nsites.\n\nesp_ssg_unref() is missing that guard, so for a managed-frag skb it\ndrops a page reference the skb never acquired.  This can underflow the\npage reference count and free a page that is still in use.\n\nGuard the function with skb_zcopy_managed() so both unref paths are\nskipped for managed-frag skbs, matching skb_release_data()."
          }
        ],
        "id": "CVE-2026-93105",
        "lastModified": "2026-09-18T18:18:20.667",
        "metrics": {
          "cvssMetricV31": [
            {
              "cvssData": {
                "attackComplexity": "LOW",
                "attackVector": "LOCAL",
                "availabilityImpact": "HIGH",
                "baseScore": 7.8,
                "baseSeverity": "HIGH",
                "confidentialityImpact": "HIGH",
                "integrityImpact": "HIGH",
                "privilegesRequired": "LOW",
                "scope": "UNCHANGED",
                "userInteraction": "NONE",
                "vectorString": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
                "version": "3.1"
              },
              "exploitabilityScore": 1.8,
              "impactScore": 5.9,
              "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
              "type": "Secondary"
            }
          ]
        },
        "published": "2026-09-17T17:18:04.847",
        "references": [
          {
            "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
            "url": "https://git.kernel.org/stable/c/21697720ff43b8dfa25b8e8d9ca7f56f4597fc80"
          },
          {
            "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
            "url": "https://git.kernel.org/stable/c/26b6b14c7a0368e317a1e9fb5144ebe6f8d495cf"
          }
        ],
        "sourceIdentifier": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
        "vulnStatus": "Received"
      }
    },
    "suse_vex": {
      "aggregate_severity": "important",
      "current_release_date": "2026-09-22T16:24:30Z",
      "cve": "CVE-2026-93105",
      "id": "CVE-2026-93105",
      "initial_release_date": "2026-09-18T00:11:59Z",
      "product_status:known_affected": "341",
      "product_status:known_not_affected": "6",
      "source": "SUSE CSAF VEX",
      "status": "interim",
      "title": "SUSE CVE CVE-2026-93105",
      "url": "https://ftp.suse.com/pub/projects/security/csaf-vex/cve-2026-93105.json",
      "version": "4"
    }
  }
}



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…

Loading…

Loading…

Related by attack behaviour

Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.


Loading…