In the Linux kernel, the following vulnerability has been resolved:
uprobe: avoid out-of-bounds memory access of fetching args
Uprobe needs to fetch args into a percpu buffer, and then copy to ring buffer to avoid non-atomic context problem.
Sometimes user-space strings, arrays can be very large, but the size of percpu buffer is only page size. And storetraceargs() won't check whether these data exceeds a single page or not, caused out-of-bounds memory access.
It could be reproduced by following steps: 1. build kernel with CONFIG_KASAN enabled 2. save follow program as test.c
\#include <stdio.h>
\#include <stdlib.h>
\#include <string.h>
// If string length large than MAX_STRING_SIZE, the fetch_store_strlen()
// will return 0, cause __get_data_size() return shorter size, and
// store_trace_args() will not trigger out-of-bounds access.
// So make string length less than 4096.
\#define STRLEN 4093
void generate_string(char *str, int n)
{
int i;
for (i = 0; i < n; ++i)
{
char c = i % 26 + 'a';
str[i] = c;
}
str[n-1] = '\0';
}
void print_string(char *str)
{
printf("%s\n", str);
}
int main()
{
char tmp[STRLEN];
generate_string(tmp, STRLEN);
print_string(tmp);
return 0;
}
3. compile program
gcc -o test test.c
get the offset of print_string()
objdump -t test | grep -w print_string
0000000000401199 g F .text 000000000000001b print_string
configure uprobe with offset 0x1199
off=0x1199
cd /sys/kernel/debug/tracing/
echo "p /root/test:${off} arg1=+0(%di):ustring arg2=\$comm arg3=+0(%di):ustring"
> uprobe_events
echo 1 > events/uprobes/enable
echo 1 > tracing_on
test, and kasan will report error.BUG: KASAN: use-after-free in strncpyfromuser+0x1d6/0x1f0 Write of size 8 at addr ffff88812311c004 by task test/499CPU: 0 UID: 0 PID: 499 Comm: test Not tainted 6.12.0-rc3+ #18 Hardware name: Red Hat KVM, BIOS 1.16.0-4.al8 04/01/2014 Call Trace: <TASK> dumpstacklvl+0x55/0x70 printaddressdescription.constprop.0+0x27/0x310 kasanreport+0x10f/0x120 ? strncpyfromuser+0x1d6/0x1f0 strncpyfromuser+0x1d6/0x1f0 ? rmqueue.constprop.0+0x70d/0x2ad0 processfetchinsn+0xb26/0x1470 ? pfxprocessfetchinsn+0x10/0x10 ? rawspinlock+0x85/0xe0 ? _pfxrawspinlock+0x10/0x10 ? pteoffsetmap+0x1f/0x2d0 ? unwindnextframe+0xc5f/0x1f80 ? archstackwalk+0x68/0xf0 ? isbpftextaddress+0x23/0x30 ? kerneltextaddress.part.0+0xbb/0xd0 ? _kerneltextaddress+0x66/0xb0 ? unwindgetreturnaddress+0x5e/0xa0 ? _pfxstacktraceconsumeentry+0x10/0x10 ? archstackwalk+0xa2/0xf0 ? rawspinlockirqsave+0x8b/0xf0 ? _pfxrawspinlockirqsave+0x10/0x10 ? depotallocstack+0x4c/0x1f0 ? rawspinunlockirqrestore+0xe/0x30 ? stackdepotsaveflags+0x35d/0x4f0 ? kasansavestack+0x34/0x50 ? kasansavestack+0x24/0x50 ? mutexlock+0x91/0xe0 ? _pfxmutexlock+0x10/0x10 prepareuprobebuffer.part.0+0x2cd/0x500 uprobedispatcher+0x2c3/0x6a0 ? _pfxuprobedispatcher+0x10/0x10 ? _kasanslaballoc+0x4d/0x90 handlerchain+0xdd/0x3e0 handleswbp+0x26e/0x3d0 ? _pfxhandleswbp+0x10/0x10 ? uprobepresstepnotifier+0x151/0x1b0 irqentryexittousermode+0xe2/0x1b0 asmexcint3+0x39/0x40 RIP: 0033:0x401199 Code: 01 c2 0f b6 45 fb 88 02 83 45 fc 01 8b 45 fc 3b 45 e4 7c b7 8b 45 e4 48 98 48 8d 50 ff 48 8b 45 e8 48 01 d0 ce RSP: 002b:00007ffdf00576a8 EFLAGS: 00000206 RAX: 00007ffdf00576b0 RBX: 0000000000000000 RCX: 0000000000000ff2 RDX: 0000000000000ffc RSI: 0000000000000ffd RDI: 00007ffdf00576b0 RBP: 00007ffdf00586b0 R08: 00007feb2f9c0d20 R09: 00007feb2f9c0d20 R10: 0000000000000001 R11: 0000000000000202 R12: 0000000000401040 R13: 00007ffdf0058780 R14: 0000000000000000 R15: 0000000000000000 </TASK>
This commit enforces the buffer's maxlen less than a page-size to avoid storetraceargs() out-of-memory access.
{
"cna_assigner": "Linux",
"osv_generated_from": "https://github.com/CVEProject/cvelistV5/tree/main/cves/2024/50xxx/CVE-2024-50067.json"
}"https://storage.googleapis.com/cve-osv-conversion/osv-output/CVE-2024-50067.json"
[
{
"signature_type": "Function",
"signature_version": "v1",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@537ad4a431f6dddbf15d40d19f24bb9ee12b55cb",
"digest": {
"function_hash": "27302323144367855271033363563375145789",
"length": 769.0
},
"id": "CVE-2024-50067-0116249b",
"deprecated": false,
"target": {
"file": "kernel/trace/trace_uprobe.c",
"function": "__uprobe_trace_func"
}
},
{
"signature_type": "Line",
"signature_version": "v1",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@537ad4a431f6dddbf15d40d19f24bb9ee12b55cb",
"digest": {
"line_hashes": [
"92111086946447022634393152575276438994",
"74383563922761751523850004868591208180",
"224979849509588407617076433106983621703",
"219607946923543716843843315411661021582",
"76849864170651057749405794620238366031",
"4360441700087789089619839391582184690",
"310880648556049005015979021636985330772",
"86473756322200325370578996454381465118",
"295057230181597726708757657823462156831",
"225773687411582221200009645635901411428",
"195384002515595507062049224485000767136",
"295691636132663805820677546360265904073"
],
"threshold": 0.9
},
"id": "CVE-2024-50067-01d82d7a",
"deprecated": false,
"target": {
"file": "kernel/trace/trace_uprobe.c"
}
},
{
"signature_type": "Function",
"signature_version": "v1",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@537ad4a431f6dddbf15d40d19f24bb9ee12b55cb",
"digest": {
"function_hash": "189724494263727528948143549144441385665",
"length": 392.0
},
"id": "CVE-2024-50067-079e8a92",
"deprecated": false,
"target": {
"file": "kernel/trace/trace_uprobe.c",
"function": "prepare_uprobe_buffer"
}
},
{
"signature_type": "Line",
"signature_version": "v1",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@373b9338c9722a368925d83bc622c596896b328e",
"digest": {
"line_hashes": [
"92111086946447022634393152575276438994",
"74383563922761751523850004868591208180",
"224979849509588407617076433106983621703",
"219607946923543716843843315411661021582",
"76849864170651057749405794620238366031",
"4360441700087789089619839391582184690",
"310880648556049005015979021636985330772",
"86473756322200325370578996454381465118",
"295057230181597726708757657823462156831",
"225773687411582221200009645635901411428",
"195384002515595507062049224485000767136",
"295691636132663805820677546360265904073"
],
"threshold": 0.9
},
"id": "CVE-2024-50067-0da107f6",
"deprecated": false,
"target": {
"file": "kernel/trace/trace_uprobe.c"
}
},
{
"signature_type": "Function",
"signature_version": "v1",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@0dc3ad9ad2188da7f090b3dbe4d2fcd9ae8ae64f",
"digest": {
"function_hash": "330020652946098944528964300653603481672",
"length": 312.0
},
"id": "CVE-2024-50067-40286203",
"deprecated": false,
"target": {
"file": "kernel/trace/trace_uprobe.c",
"function": "prepare_uprobe_buffer"
}
},
{
"signature_type": "Line",
"signature_version": "v1",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@0dc3ad9ad2188da7f090b3dbe4d2fcd9ae8ae64f",
"digest": {
"line_hashes": [
"92111086946447022634393152575276438994",
"74383563922761751523850004868591208180",
"224979849509588407617076433106983621703",
"219607946923543716843843315411661021582",
"305243177611035178269110676192179338957",
"58921715925234112491211832380941014456",
"214645549357418078969239788164047941782",
"86473756322200325370578996454381465118",
"295057230181597726708757657823462156831",
"225773687411582221200009645635901411428",
"195384002515595507062049224485000767136",
"295691636132663805820677546360265904073"
],
"threshold": 0.9
},
"id": "CVE-2024-50067-5efc19ba",
"deprecated": false,
"target": {
"file": "kernel/trace/trace_uprobe.c"
}
},
{
"signature_type": "Function",
"signature_version": "v1",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@373b9338c9722a368925d83bc622c596896b328e",
"digest": {
"function_hash": "189724494263727528948143549144441385665",
"length": 392.0
},
"id": "CVE-2024-50067-725b6f07",
"deprecated": false,
"target": {
"file": "kernel/trace/trace_uprobe.c",
"function": "prepare_uprobe_buffer"
}
},
{
"signature_type": "Function",
"signature_version": "v1",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@373b9338c9722a368925d83bc622c596896b328e",
"digest": {
"function_hash": "27302323144367855271033363563375145789",
"length": 769.0
},
"id": "CVE-2024-50067-762fc9a8",
"deprecated": false,
"target": {
"file": "kernel/trace/trace_uprobe.c",
"function": "__uprobe_trace_func"
}
},
{
"signature_type": "Line",
"signature_version": "v1",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@9e5f93788c9dd4309e75a56860a1ac44a8e117b9",
"digest": {
"line_hashes": [
"92111086946447022634393152575276438994",
"74383563922761751523850004868591208180",
"224979849509588407617076433106983621703",
"219607946923543716843843315411661021582",
"76849864170651057749405794620238366031",
"4360441700087789089619839391582184690",
"310880648556049005015979021636985330772",
"86473756322200325370578996454381465118",
"295057230181597726708757657823462156831",
"225773687411582221200009645635901411428",
"195384002515595507062049224485000767136",
"295691636132663805820677546360265904073"
],
"threshold": 0.9
},
"id": "CVE-2024-50067-992e8e4d",
"deprecated": false,
"target": {
"file": "kernel/trace/trace_uprobe.c"
}
},
{
"signature_type": "Function",
"signature_version": "v1",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@9e5f93788c9dd4309e75a56860a1ac44a8e117b9",
"digest": {
"function_hash": "189724494263727528948143549144441385665",
"length": 392.0
},
"id": "CVE-2024-50067-a3ce653f",
"deprecated": false,
"target": {
"file": "kernel/trace/trace_uprobe.c",
"function": "prepare_uprobe_buffer"
}
},
{
"signature_type": "Function",
"signature_version": "v1",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@9e5f93788c9dd4309e75a56860a1ac44a8e117b9",
"digest": {
"function_hash": "27302323144367855271033363563375145789",
"length": 769.0
},
"id": "CVE-2024-50067-d13ea9a0",
"deprecated": false,
"target": {
"file": "kernel/trace/trace_uprobe.c",
"function": "__uprobe_trace_func"
}
},
{
"signature_type": "Function",
"signature_version": "v1",
"source": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git@0dc3ad9ad2188da7f090b3dbe4d2fcd9ae8ae64f",
"digest": {
"function_hash": "27302323144367855271033363563375145789",
"length": 769.0
},
"id": "CVE-2024-50067-d7610c86",
"deprecated": false,
"target": {
"file": "kernel/trace/trace_uprobe.c",
"function": "__uprobe_trace_func"
}
}
]