Security Vulnerability Report
中文
CVE-2026-31644 CVSS 7.8 HIGH

CVE-2026-31644

Published: 2026-04-24 15:16:44
Last Modified: 2026-04-27 20:19:22
Source: 416baaa9-dc9f-4396-8d5f-8c081fb06d67

Description

In the Linux kernel, the following vulnerability has been resolved: net: lan966x: fix use-after-free and leak in lan966x_fdma_reload() When lan966x_fdma_reload() fails to allocate new RX buffers, the restore path restarts DMA using old descriptors whose pages were already freed via lan966x_fdma_rx_free_pages(). Since page_pool_put_full_page() can release pages back to the buddy allocator, the hardware may DMA into memory now owned by other kernel subsystems. Additionally, on the restore path, the newly created page pool (if allocation partially succeeded) is overwritten without being destroyed, leaking it. Fix both issues by deferring the release of old pages until after the new allocation succeeds. Save the old page array before the allocation so old pages can be freed on the success path. On the failure path, the old descriptors, pages and page pool are all still valid, making the restore safe. Also ensure the restore path re-enables NAPI and wakes the netdev, matching the success path.

CVSS Details

CVSS Score
7.8
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/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:6.12:-:*:*:*:*:*:* - VULNERABLE
cpe:2.3:o:linux:linux_kernel:7.0:rc1:*:*:*:*:*:* - VULNERABLE
Linux Kernel (lan966x driver)

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
/* * Conceptual PoC for CVE-2026-31644 Logic Flow * This code demonstrates the vulnerable logic flow where resources are freed * before ensuring the new allocation succeeded, leading to UAF. */ #include <stdio.h> #include <stdlib.h> // Simulating kernel structures struct page { int data; }; struct dma_desc { struct page *pg; }; void simulated_vulnerable_function() { struct dma_desc *old_desc = malloc(sizeof(struct dma_desc)); old_desc->pg = malloc(sizeof(struct page)); printf("[+] Step 1: Initialized DMA descriptor and allocated page. "); // Simulate reload attempt struct page *new_page = NULL; // Simulate allocation failure (e.g., memory pressure) if (rand() % 2 == 0) { new_page = NULL; } else { new_page = malloc(sizeof(struct page)); } if (!new_page) { printf("[!] Step 2: Allocation of new page failed."); printf("\n[-] Step 3: Vulnerability - Freeing old page immediately."); free(old_desc->pg); // Equivalent to lan966x_fdma_rx_free_pages old_desc->pg = NULL; // Vulnerability: Hardware (DMA) might still be using old_desc printf("\n[-] Step 4: Restoring DMA using old descriptor (UAF Risk)."); printf("\n[!] Impact: Hardware writes to freed memory -> Kernel Panic/Exploit."); // Cleanup for simulation free(old_desc); } else { printf("[+] Allocation succeeded. Safe swap performed."); free(old_desc->pg); free(old_desc); free(new_page); } } int main() { simulated_vulnerable_function(); return 0; }

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-31644", "sourceIdentifier": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "published": "2026-04-24T15:16:43.770", "lastModified": "2026-04-27T20:19:21.583", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nnet: lan966x: fix use-after-free and leak in lan966x_fdma_reload()\n\nWhen lan966x_fdma_reload() fails to allocate new RX buffers, the restore\npath restarts DMA using old descriptors whose pages were already freed\nvia lan966x_fdma_rx_free_pages(). Since page_pool_put_full_page() can\nrelease pages back to the buddy allocator, the hardware may DMA into\nmemory now owned by other kernel subsystems.\n\nAdditionally, on the restore path, the newly created page pool (if\nallocation partially succeeded) is overwritten without being destroyed,\nleaking it.\n\nFix both issues by deferring the release of old pages until after the\nnew allocation succeeds. Save the old page array before the allocation\nso old pages can be freed on the success path. On the failure path, the\nold descriptors, pages and page pool are all still valid, making the\nrestore safe. Also ensure the restore path re-enables NAPI and wakes\nthe netdev, matching the success path."}], "metrics": {"cvssMetricV31": [{"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H", "baseScore": 7.8, "baseSeverity": "HIGH", "attackVector": "LOCAL", "attackComplexity": "LOW", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "HIGH"}, "exploitabilityScore": 1.8, "impactScore": 5.9}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-416"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*", "versionStartIncluding": "6.12.1", "versionEndExcluding": "6.12.82", "matchCriteriaId": "36D94B3B-76E2-4F07-B407-336CB238EB63"}, {"vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*", "versionStartIncluding": "6.13", "versionEndExcluding": "6.18.23", "matchCriteriaId": "E9E09FDD-9EE3-4A56-92E2-2B30AFD0072F"}, {"vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*", "versionStartIncluding": "6.19", "versionEndExcluding": "6.19.13", "matchCriteriaId": "1490EF9B-9080-481C-8D22-1306AAE664E4"}, {"vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:6.12:-:*:*:*:*:*:*", "matchCriteriaId": "0E698080-7669-4132-8817-4C674EEBCE54"}, {"vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:7.0:rc1:*:*:*:*:*:*", "matchCriteriaId": "F253B622-8837-4245-BCE5-A7BF8FC76A16"}, {"vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:7.0:rc2:*:*:*:*:*:*", "matchCriteriaId": "4AE85AD8-4641-4E7C-A2F4-305E2CD9EE64"}, {"vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:7.0:rc3:*:*:*:*:*:*", "matchCriteriaId": "F666C8D8-6538-46D4-B318-87610DE64C34"}, {"vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:7.0:rc4:*:*:*:*:*:*", "matchCriteriaId": "02259FDA-961B-47BC-AE7F-93D7EC6E90C2"}, {"vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:7.0:rc5:*:*:*:*:*:*", "matchCriteriaId": "58A9FEFF-C040-420D-8F0A-BFDAAA1DF258"}, {"vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:7.0:rc6:*:*:*:*:*:*", "matchCriteriaId": "1D2315C0-D46F-4F85-9754-F9E5E11374A6"}, {"vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:7.0:rc7:*:*:*:*:*:*", "matchCriteriaId": "512EE3A8-A590-4501-9A94-5D4B268D6138"}]}]}], "references": [{"url": "https://git.kernel.org/stable/c/59c3d55a946cacdb4181600723c20ac4f4c20c84", "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "tags": ["Patch"]}, {"url": "https://git.kernel.org/stable/c/691082c0b93c13a5e068c0905f673060bddc204e", "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "tags": ["Patch"]}, {"url": "https://git.kernel.org/stable/c/92a673019943770930e2a8bfd52e1aad47a1fc1f", "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "tags": ["Patch"]}, {"url": "https://git.kernel.org/stable/c/9950e9199b3dfdfbde0b8d96ba947d7b11243801", "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "tags": ["Patch"]}]}}