{ "dataType": "CVE_RECORD", "dataVersion": "5.2", "cveMetadata": { "cveId": "CVE-2025-21778", "assignerOrgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "state": "PUBLISHED", "assignerShortName": "Linux", "dateReserved": "2024-12-29T08:45:45.763Z", "datePublished": "2025-02-27T02:18:22.506Z", "dateUpdated": "2026-08-05T11:54:21.703Z" }, "containers": { "cna": { "providerMetadata": { "orgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "shortName": "Linux", "dateUpdated": "2026-08-05T11:54:21.703Z" }, "descriptions": [ { "lang": "en", "value": "In the Linux kernel, the following vulnerability has been resolved:\n\ntracing: Do not allow mmap() of persistent ring buffer\n\nWhen trying to mmap a trace instance buffer that is attached to\nreserve_mem, it would crash:\n\n BUG: unable to handle page fault for address: ffffe97bd00025c8\n #PF: supervisor read access in kernel mode\n #PF: error_code(0x0000) - not-present page\n PGD 2862f3067 P4D 2862f3067 PUD 0\n Oops: Oops: 0000 [#1] PREEMPT_RT SMP PTI\n CPU: 4 UID: 0 PID: 981 Comm: mmap-rb Not tainted 6.14.0-rc2-test-00003-g7f1a5e3fbf9e-dirty #233\n Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014\n RIP: 0010:validate_page_before_insert+0x5/0xb0\n Code: e2 01 89 d0 c3 cc cc cc cc 66 66 2e 0f 1f 84 00 00 00 00 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 0f 1f 44 00 00 <48> 8b 46 08 a8 01 75 67 66 90 48 89 f0 8b 50 34 85 d2 74 76 48 89\n RSP: 0018:ffffb148c2f3f968 EFLAGS: 00010246\n RAX: ffff9fa5d3322000 RBX: ffff9fa5ccff9c08 RCX: 00000000b879ed29\n RDX: ffffe97bd00025c0 RSI: ffffe97bd00025c0 RDI: ffff9fa5ccff9c08\n RBP: ffffb148c2f3f9f0 R08: 0000000000000004 R09: 0000000000000004\n R10: 0000000000000000 R11: 0000000000000200 R12: 0000000000000000\n R13: 00007f16a18d5000 R14: ffff9fa5c48db6a8 R15: 0000000000000000\n FS: 00007f16a1b54740(0000) GS:ffff9fa73df00000(0000) knlGS:0000000000000000\n CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033\n CR2: ffffe97bd00025c8 CR3: 00000001048c6006 CR4: 0000000000172ef0\n Call Trace:\n \n ? __die_body.cold+0x19/0x1f\n ? __die+0x2e/0x40\n ? page_fault_oops+0x157/0x2b0\n ? search_module_extables+0x53/0x80\n ? validate_page_before_insert+0x5/0xb0\n ? kernelmode_fixup_or_oops.isra.0+0x5f/0x70\n ? __bad_area_nosemaphore+0x16e/0x1b0\n ? bad_area_nosemaphore+0x16/0x20\n ? do_kern_addr_fault+0x77/0x90\n ? exc_page_fault+0x22b/0x230\n ? asm_exc_page_fault+0x2b/0x30\n ? validate_page_before_insert+0x5/0xb0\n ? vm_insert_pages+0x151/0x400\n __rb_map_vma+0x21f/0x3f0\n ring_buffer_map+0x21b/0x2f0\n tracing_buffers_mmap+0x70/0xd0\n __mmap_region+0x6f0/0xbd0\n mmap_region+0x7f/0x130\n do_mmap+0x475/0x610\n vm_mmap_pgoff+0xf2/0x1d0\n ksys_mmap_pgoff+0x166/0x200\n __x64_sys_mmap+0x37/0x50\n x64_sys_call+0x1670/0x1d70\n do_syscall_64+0xbb/0x1d0\n entry_SYSCALL_64_after_hwframe+0x77/0x7f\n\nThe reason was that the code that maps the ring buffer pages to user space\nhas:\n\n\tpage = virt_to_page((void *)cpu_buffer->subbuf_ids[s]);\n\nAnd uses that in:\n\n\tvm_insert_pages(vma, vma->vm_start, pages, &nr_pages);\n\nBut virt_to_page() does not work with vmap()'d memory which is what the\npersistent ring buffer has. It is rather trivial to allow this, but for\nnow just disable mmap() of instances that have their ring buffer from the\nreserve_mem option.\n\nIf an mmap() is performed on a persistent buffer it will return -ENODEV\njust like it would if the .mmap field wasn't defined in the\nfile_operations structure." } ], "metrics": [ { "cvssV3_1": { "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" }, "scenarios": [ { "lang": "en", "value": "AV:L - The vulnerability is reached purely through the mmap() syscall on a local tracefs file (/sys/kernel/tracing/instances//per_cpu/cpuN/trace_pipe_raw); no network or adjacent-network component is involved.\nAC:L - A single PROT_READ|MAP_SHARED mmap() of a boot-mapped instance's trace_pipe_raw deterministically drives virt_to_page() over a vmap address on the very first attempt — there is no race, no timing window, and no memory-layout luck required to trigger it.\nPR:L - tracing_buffers_open() enforces no capability check at all — only tracefs DAC (0440 files under 0750 dirs) and lockdown, which is off by default — and tracefs is routinely delegated via its gid= mount option to a non-root tracing group on Android/Perfetto and embedded systems, which are exactly the deployments that enable reserve_mem persistent tracing.\nUI:N - The attacker performs the open() and mmap() entirely on their own; no administrator or other user needs to take any action once the persistent instance exists.\nS:U - The wild struct page dereference, page-table insertion and fault all occur within the kernel's own security authority; no hypervisor, IOMMU or sandbox boundary is crossed.\nC:H - virt_to_page() on a vmap address produces a struct page for an unrelated physical frame, and where that frame is backed (e.g. 32-bit ARM, where __pa() of the vmalloc range lands squarely in real RAM on the embedded boards this feature targets) vm_insert_pages() maps arbitrary kernel and other-process memory read-only into the attacker's address space — an arbitrary memory read primitive.\nI:H - insert_page_into_pte_locked() executes folio_get(), inc_mm_counter() and folio_add_file_rmap_pte() against the attacker-reachable bogus struct page, inflating the refcount and corrupting the rmap/mapcount state of a folio owned by an unrelated subsystem — memory corruption that seeds later use-after-free and control-flow hijacking.\nA:H - The commit demonstrates an unhandled kernel page fault (\"Oops: 0000 [#1] PREEMPT_RT\") in validate_page_before_insert(), and it occurs with cpu_buffer->mapping_lock, buffer->mutex and mmap_write_lock held, so the dying task leaves them permanently locked — wedging the tracing subsystem, or panicking outright under panic_on_oops." } ] } ], "affected": [ { "product": "Linux", "vendor": "Linux", "defaultStatus": "unaffected", "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git", "programFiles": [ "kernel/trace/trace.c" ], "versions": [ { "version": "9b7bdf6f6ece6ea888cc7d2f02c00b403b66a119", "lessThan": "e8dff5f73912513fc9b52ab992d861517c9a9975", "status": "affected", "versionType": "git" }, { "version": "9b7bdf6f6ece6ea888cc7d2f02c00b403b66a119", "lessThan": "cf5aa560e5c7628b57c928741d7e6a9a0f6f0e67", "status": "affected", "versionType": "git" }, { "version": "9b7bdf6f6ece6ea888cc7d2f02c00b403b66a119", "lessThan": "129fe718819cc5e24ea2f489db9ccd4371f0c6f6", "status": "affected", "versionType": "git" } ] }, { "product": "Linux", "vendor": "Linux", "defaultStatus": "affected", "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git", "programFiles": [ "kernel/trace/trace.c" ], "versions": [ { "version": "6.12", "status": "affected" }, { "version": "0", "lessThan": "6.12", "status": "unaffected", "versionType": "semver" }, { "version": "6.12.16", "lessThanOrEqual": "6.12.*", "status": "unaffected", "versionType": "semver" }, { "version": "6.13.4", "lessThanOrEqual": "6.13.*", "status": "unaffected", "versionType": "semver" }, { "version": "6.14", "lessThanOrEqual": "*", "status": "unaffected", "versionType": "original_commit_for_fix" } ] } ], "cpeApplicability": [ { "nodes": [ { "operator": "OR", "negate": false, "cpeMatch": [ { "vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*", "versionStartIncluding": "6.12", "versionEndExcluding": "6.12.16" }, { "vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*", "versionStartIncluding": "6.12", "versionEndExcluding": "6.13.4" }, { "vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*", "versionStartIncluding": "6.12", "versionEndExcluding": "6.14" } ] } ] } ], "references": [ { "url": "https://git.kernel.org/stable/c/e8dff5f73912513fc9b52ab992d861517c9a9975" }, { "url": "https://git.kernel.org/stable/c/cf5aa560e5c7628b57c928741d7e6a9a0f6f0e67" }, { "url": "https://git.kernel.org/stable/c/129fe718819cc5e24ea2f489db9ccd4371f0c6f6" } ], "title": "tracing: Do not allow mmap() of persistent ring buffer", "x_generator": { "engine": "bippy-1.2.0" } } } }