Files
vuln-cve/data/2025/22xxx/CVE-2025-22069.json
T

165 lines
12 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"dataType": "CVE_RECORD",
"dataVersion": "5.2",
"cveMetadata": {
"cveId": "CVE-2025-22069",
"assignerOrgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"state": "PUBLISHED",
"assignerShortName": "Linux",
"dateReserved": "2024-12-29T08:45:45.814Z",
"datePublished": "2025-04-16T14:12:22.357Z",
"dateUpdated": "2026-08-05T11:56:30.349Z"
},
"containers": {
"cna": {
"providerMetadata": {
"orgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"shortName": "Linux",
"dateUpdated": "2026-08-05T11:56:30.349Z"
},
"descriptions": [
{
"lang": "en",
"value": "In the Linux kernel, the following vulnerability has been resolved:\n\nriscv: fgraph: Fix stack layout to match __arch_ftrace_regs argument of ftrace_return_to_handler\n\nNaresh Kamboju reported a \"Bad frame pointer\" kernel warning while\nrunning LTP trace ftrace_stress_test.sh in riscv. We can reproduce the\nsame issue with the following command:\n\n```\n$ cd /sys/kernel/debug/tracing\n$ echo 'f:myprobe do_nanosleep%return args1=$retval' > dynamic_events\n$ echo 1 > events/fprobes/enable\n$ echo 1 > tracing_on\n$ sleep 1\n```\n\nAnd we can get the following kernel warning:\n\n[ 127.692888] ------------[ cut here ]------------\n[ 127.693755] Bad frame pointer: expected ff2000000065be50, received ba34c141e9594000\n[ 127.693755] from func do_nanosleep return to ffffffff800ccb16\n[ 127.698699] WARNING: CPU: 1 PID: 129 at kernel/trace/fgraph.c:755 ftrace_return_to_handler+0x1b2/0x1be\n[ 127.699894] Modules linked in:\n[ 127.700908] CPU: 1 UID: 0 PID: 129 Comm: sleep Not tainted 6.14.0-rc3-g0ab191c74642 #32\n[ 127.701453] Hardware name: riscv-virtio,qemu (DT)\n[ 127.701859] epc : ftrace_return_to_handler+0x1b2/0x1be\n[ 127.702032] ra : ftrace_return_to_handler+0x1b2/0x1be\n[ 127.702151] epc : ffffffff8013b5e0 ra : ffffffff8013b5e0 sp : ff2000000065bd10\n[ 127.702221] gp : ffffffff819c12f8 tp : ff60000080853100 t0 : 6e00000000000000\n[ 127.702284] t1 : 0000000000000020 t2 : 6e7566206d6f7266 s0 : ff2000000065bd80\n[ 127.702346] s1 : ff60000081262000 a0 : 000000000000007b a1 : ffffffff81894f20\n[ 127.702408] a2 : 0000000000000010 a3 : fffffffffffffffe a4 : 0000000000000000\n[ 127.702470] a5 : 0000000000000000 a6 : 0000000000000008 a7 : 0000000000000038\n[ 127.702530] s2 : ba34c141e9594000 s3 : 0000000000000000 s4 : ff2000000065bdd0\n[ 127.702591] s5 : 00007fff8adcf400 s6 : 000055556dc1d8c0 s7 : 0000000000000068\n[ 127.702651] s8 : 00007fff8adf5d10 s9 : 000000000000006d s10: 0000000000000001\n[ 127.702710] s11: 00005555737377c8 t3 : ffffffff819d899e t4 : ffffffff819d899e\n[ 127.702769] t5 : ffffffff819d89a0 t6 : ff2000000065bb18\n[ 127.702826] status: 0000000200000120 badaddr: 0000000000000000 cause: 0000000000000003\n[ 127.703292] [<ffffffff8013b5e0>] ftrace_return_to_handler+0x1b2/0x1be\n[ 127.703760] [<ffffffff80017bce>] return_to_handler+0x16/0x26\n[ 127.704009] [<ffffffff80017bb8>] return_to_handler+0x0/0x26\n[ 127.704057] [<ffffffff800d3352>] common_nsleep+0x42/0x54\n[ 127.704117] [<ffffffff800d44a2>] __riscv_sys_clock_nanosleep+0xba/0x10a\n[ 127.704176] [<ffffffff80901c56>] do_trap_ecall_u+0x188/0x218\n[ 127.704295] [<ffffffff8090cc3e>] handle_exception+0x14a/0x156\n[ 127.705436] ---[ end trace 0000000000000000 ]---\n\nThe reason is that the stack layout for constructing argument for the\nftrace_return_to_handler in the return_to_handler does not match the\n__arch_ftrace_regs structure of riscv, leading to unexpected results."
}
],
"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 vulnerable trampoline is armed only by writing to tracefs (`current_tracer`, `dynamic_events`, `events/*/enable`) and fires on ordinary syscall execution, both of which require local access to the machine. There is no network-facing consumer of `arch/riscv/kernel/mcount.S`.\nAC:L - The mismatch is a fixed compile-time stack layout error, not a race or a memory-layout gamble: the very first return of any traced function reads `s0` from `sp+24` instead of `sp+64` and writes `a0`/`a1` past the 80-byte frame, so the commit's four-command reproducer fails deterministically on the first `sleep 1`.\nPR:L - Reaching the trampoline requires only write access to tracefs, which is enforced by file permissions rather than any `capable()` check and is routinely delegated to an unprivileged tracing group via tracefs's `gid=` mount option (as Android and ChromeOS do for `atrace`). A non-root member of that group can arm `function_graph` or an fprobe and trigger the corruption.\nUI:N - The same local user both arms the tracer and triggers it by making any traced function return in their own process; no action by an administrator or other victim is needed.\nS:U - The out-of-bounds writes and reads all land in the kernel stack of the running task, within the kernel's own security authority — no VM, IOMMU, or sandbox boundary is crossed.\nC:H - The C side treats `sp..sp+103` as `__arch_ftrace_regs` while only 80 bytes were allocated, so `a5`/`a6`/`a7` and the 64-byte `ftrace_partial_regs()` `memcpy` read 24 bytes past the frame into the caller's live stack, and `s0`/`t1`/`a0`–`a4` are read from uninitialized stack — these stale kernel stack values (pointers, saved registers) are handed to fprobe/BPF callbacks as `$retval`/`$argN` and dumped into the trace buffer and the WARN register dump.\nI:H - `REG_S a0, 80(sp)` / `REG_S a1, 88(sp)` after `addi sp, sp, -80` is an unconditional 16-byte out-of-bounds stack write into the live frame of the traced function's caller, with `a0` holding an often user-influenceable return value; the same overhang lets a retfunc callback's writes to `args[5..7]` corrupt the caller's frame and even substitute the value `RESTORE_RET_ABI_STATE` reloads into `a0`, giving control over saved state and potentially return addresses further up the stack.\nA:H - With `HAVE_FUNCTION_GRAPH_FP_TEST` — effectively always enabled on riscv given `ARCH_WANT_FRAME_POINTERS` and `select FRAME_POINTER if PERF_EVENTS` — the garbage frame pointer makes `ftrace_pop_return_trace()` set `*ret = (unsigned long)panic`, so `return_to_handler`'s `jalr a2` jumps directly into `panic()`, in addition to the WARN and `ftrace_graph_stop()` seen in the reported LTP failure."
}
]
}
],
"affected": [
{
"product": "Linux",
"vendor": "Linux",
"defaultStatus": "unaffected",
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
"programFiles": [
"arch/riscv/kernel/mcount.S"
],
"versions": [
{
"version": "33d4e904e24d14ff0fbc528b657ddc7c7b636e6a",
"lessThan": "7ed384db061a264bd806898f7ccab9b98b591488",
"status": "affected",
"versionType": "git"
},
{
"version": "a3ed4157b7d89800a0008de0c9e46a438a5c3745",
"lessThan": "78b39c587b8f6c69140177108f9c08a75b1c7c37",
"status": "affected",
"versionType": "git"
},
{
"version": "a3ed4157b7d89800a0008de0c9e46a438a5c3745",
"lessThan": "67a5ba8f742f247bc83e46dd2313c142b1383276",
"status": "affected",
"versionType": "git"
},
{
"version": "6.12.75",
"lessThan": "6.12.92",
"status": "affected",
"versionType": "semver"
}
]
},
{
"product": "Linux",
"vendor": "Linux",
"defaultStatus": "affected",
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
"programFiles": [
"arch/riscv/kernel/mcount.S"
],
"versions": [
{
"version": "6.14",
"status": "affected"
},
{
"version": "0",
"lessThan": "6.14",
"status": "unaffected",
"versionType": "semver"
},
{
"version": "6.12.92",
"lessThanOrEqual": "6.12.*",
"status": "unaffected",
"versionType": "semver"
},
{
"version": "6.14.2",
"lessThanOrEqual": "6.14.*",
"status": "unaffected",
"versionType": "semver"
},
{
"version": "6.15",
"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.75",
"versionEndExcluding": "6.12.92"
},
{
"vulnerable": true,
"criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
"versionStartIncluding": "6.14",
"versionEndExcluding": "6.14.2"
},
{
"vulnerable": true,
"criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
"versionStartIncluding": "6.14",
"versionEndExcluding": "6.15"
}
]
}
]
}
],
"references": [
{
"url": "https://git.kernel.org/stable/c/7ed384db061a264bd806898f7ccab9b98b591488"
},
{
"url": "https://git.kernel.org/stable/c/78b39c587b8f6c69140177108f9c08a75b1c7c37"
},
{
"url": "https://git.kernel.org/stable/c/67a5ba8f742f247bc83e46dd2313c142b1383276"
}
],
"title": "riscv: fgraph: Fix stack layout to match __arch_ftrace_regs argument of ftrace_return_to_handler",
"x_generator": {
"engine": "bippy-1.2.0"
}
}
}
}