{ "dataType": "CVE_RECORD", "dataVersion": "5.2", "cveMetadata": { "cveId": "CVE-2024-41003", "assignerOrgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "state": "PUBLISHED", "assignerShortName": "Linux", "dateReserved": "2024-07-12T12:17:45.609Z", "datePublished": "2024-07-12T12:44:39.110Z", "dateUpdated": "2026-08-05T11:34:32.452Z" }, "containers": { "cna": { "providerMetadata": { "orgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "shortName": "Linux", "dateUpdated": "2026-08-05T11:34:32.452Z" }, "descriptions": [ { "lang": "en", "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nbpf: Fix reg_set_min_max corruption of fake_reg\n\nJuan reported that after doing some changes to buzzer [0] and implementing\na new fuzzing strategy guided by coverage, they noticed the following in\none of the probes:\n\n [...]\n 13: (79) r6 = *(u64 *)(r0 +0) ; R0=map_value(ks=4,vs=8) R6_w=scalar()\n 14: (b7) r0 = 0 ; R0_w=0\n 15: (b4) w0 = -1 ; R0_w=0xffffffff\n 16: (74) w0 >>= 1 ; R0_w=0x7fffffff\n 17: (5c) w6 &= w0 ; R0_w=0x7fffffff R6_w=scalar(smin=smin32=0,smax=umax=umax32=0x7fffffff,var_off=(0x0; 0x7fffffff))\n 18: (44) w6 |= 2 ; R6_w=scalar(smin=umin=smin32=umin32=2,smax=umax=umax32=0x7fffffff,var_off=(0x2; 0x7ffffffd))\n 19: (56) if w6 != 0x7ffffffd goto pc+1\n REG INVARIANTS VIOLATION (true_reg2): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0)\n REG INVARIANTS VIOLATION (false_reg1): range bounds violation u64=[0x7fffffff, 0x7ffffffd] s64=[0x7fffffff, 0x7ffffffd] u32=[0x7fffffff, 0x7ffffffd] s32=[0x7fffffff, 0x7ffffffd] var_off=(0x7fffffff, 0x0)\n REG INVARIANTS VIOLATION (false_reg2): const tnum out of sync with range bounds u64=[0x0, 0xffffffffffffffff] s64=[0x8000000000000000, 0x7fffffffffffffff] u32=[0x0, 0xffffffff] s32=[0x80000000, 0x7fffffff] var_off=(0x7fffffff, 0x0)\n 19: R6_w=0x7fffffff\n 20: (95) exit\n\n from 19 to 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm\n 21: R0=0x7fffffff R6=scalar(smin=umin=smin32=umin32=2,smax=umax=smax32=umax32=0x7ffffffe,var_off=(0x2; 0x7ffffffd)) R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm\n 21: (14) w6 -= 2147483632 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=14,var_off=(0x2; 0xfffffffd))\n 22: (76) if w6 s>= 0xe goto pc+1 ; R6_w=scalar(smin=umin=umin32=2,smax=umax=0xffffffff,smin32=0x80000012,smax32=13,var_off=(0x2; 0xfffffffd))\n 23: (95) exit\n\n from 22 to 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm\n 24: R0=0x7fffffff R6_w=14 R7=map_ptr(ks=4,vs=8) R9=ctx() R10=fp0 fp-24=map_ptr(ks=4,vs=8) fp-40=mmmmmmmm\n 24: (14) w6 -= 14 ; R6_w=0\n [...]\n\nWhat can be seen here is a register invariant violation on line 19. After\nthe binary-or in line 18, the verifier knows that bit 2 is set but knows\nnothing about the rest of the content which was loaded from a map value,\nmeaning, range is [2,0x7fffffff] with var_off=(0x2; 0x7ffffffd). When in\nline 19 the verifier analyzes the branch, it splits the register states\nin reg_set_min_max() into the registers of the true branch (true_reg1,\ntrue_reg2) and the registers of the false branch (false_reg1, false_reg2).\n\nSince the test is w6 != 0x7ffffffd, the src_reg is a known constant.\nInternally, the verifier creates a \"fake\" register initialized as scalar\nto the value of 0x7ffffffd, and then passes it onto reg_set_min_max(). Now,\nfor line 19, it is mathematically impossible to take the false branch of\nthis program, yet the verifier analyzes it. It is impossible because the\nsecond bit of r6 will be set due to the prior or operation and the\nconstant in the condition has that bit unset (hex(fd) == binary(1111 1101).\n\nWhen the verifier first analyzes the false / fall-through branch, it will\ncompute an intersection between the var_off of r6 and of the constant. This\nis because the verifier creates a \"fake\" register initialized to the value\nof the constant. The intersection result later refines both registers in\nregs_refine_cond_op():\n\n [...]\n t = tnum_intersect(tnum_subreg(reg1->var_off), tnum_subreg(reg2->var_off));\n reg1->var_o\n---truncated---" } ], "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 only through the `bpf(BPF_PROG_LOAD)` syscall, which requires local access to the system; the verifier corruption occurs entirely during local program verification. No remote or adjacent network input reaches `check_cond_jmp_op()`.\nAC:L - The attacker fully authors the BPF instruction sequence that triggers the aliasing (a `JMP32|JNE|K` on a register with a known bit pattern), so the trigger is deterministic and 100% reproducible with no race, timing, or memory-layout dependency.\nPR:L - Any local unprivileged user can load `BPF_PROG_TYPE_SOCKET_FILTER`/`CGROUP_SKB` programs with zero capabilities when `kernel.unprivileged_bpf_disabled=0`, and otherwise `bpf_token_capable(CAP_BPF)` reduces to `ns_capable()` in a delegated user namespace.\nUI:N - The attacker loads and triggers their own BPF program end to end; no victim action, mount, or file open is required.\nS:U - The corrupted verifier state and the resulting memory corruption are both within the kernel's own security authority — standard local privilege escalation with no VM, IOMMU, or sandbox boundary crossed.\nC:H - The verifier/runtime scalar divergence can be amplified into an out-of-bounds read off a map_value or stack pointer, yielding an arbitrary kernel-memory read primitive that discloses arbitrary kernel data and defeats KASLR.\nI:H - The same divergence produces an unmasked out-of-bounds write — via an `ARG_CONST_SIZE` helper such as `bpf_skb_load_bytes()`, or via unsanitized pointer ALU on `bpf_capable()` loads — giving attacker-controlled kernel memory corruption and full privilege escalation.\nA:H - Out-of-bounds kernel reads and writes from a mis-verified program readily corrupt adjacent heap or stack objects, causing oops or panic even in a failed exploitation attempt." } ] } ], "affected": [ { "product": "Linux", "vendor": "Linux", "defaultStatus": "unaffected", "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git", "programFiles": [ "include/linux/bpf_verifier.h", "kernel/bpf/verifier.c" ], "versions": [ { "version": "67420501e8681ae18f9f0ea0a69cd2f432100e70", "lessThan": "41e8ab428a9964df378fa45760a660208712145b", "status": "affected", "versionType": "git" }, { "version": "67420501e8681ae18f9f0ea0a69cd2f432100e70", "lessThan": "92424801261d1564a0bb759da3cf3ccd69fdf5a2", "status": "affected", "versionType": "git" } ] }, { "product": "Linux", "vendor": "Linux", "defaultStatus": "affected", "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git", "programFiles": [ "include/linux/bpf_verifier.h", "kernel/bpf/verifier.c" ], "versions": [ { "version": "6.8", "status": "affected" }, { "version": "0", "lessThan": "6.8", "status": "unaffected", "versionType": "semver" }, { "version": "6.9.7", "lessThanOrEqual": "6.9.*", "status": "unaffected", "versionType": "semver" }, { "version": "6.10", "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.8", "versionEndExcluding": "6.9.7" }, { "vulnerable": true, "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*", "versionStartIncluding": "6.8", "versionEndExcluding": "6.10" } ] } ] } ], "references": [ { "url": "https://git.kernel.org/stable/c/41e8ab428a9964df378fa45760a660208712145b" }, { "url": "https://git.kernel.org/stable/c/92424801261d1564a0bb759da3cf3ccd69fdf5a2" } ], "title": "bpf: Fix reg_set_min_max corruption of fake_reg", "x_generator": { "engine": "bippy-1.2.0" } }, "adp": [ { "providerMetadata": { "orgId": "af854a3a-2127-422b-91ae-364da2661108", "shortName": "CVE", "dateUpdated": "2024-08-02T04:39:56.068Z" }, "title": "CVE Program Container", "references": [ { "url": "https://git.kernel.org/stable/c/41e8ab428a9964df378fa45760a660208712145b", "tags": [ "x_transferred" ] }, { "url": "https://git.kernel.org/stable/c/92424801261d1564a0bb759da3cf3ccd69fdf5a2", "tags": [ "x_transferred" ] } ] }, { "metrics": [ { "other": { "type": "ssvc", "content": { "id": "CVE-2024-41003", "role": "CISA Coordinator", "options": [ { "Exploitation": "none" }, { "Automatable": "no" }, { "Technical Impact": "partial" } ], "version": "2.0.3", "timestamp": "2024-09-10T17:01:08.608294Z" } } } ], "title": "CISA ADP Vulnrichment", "providerMetadata": { "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "shortName": "CISA-ADP", "dateUpdated": "2024-09-11T17:34:18.907Z" } } ] } }