CVE-2022-49961
Severity CVSS v4.0:
Pending analysis
Type:
CWE-125
Out-of-bounds Read
Publication date:
18/06/2025
Last modified:
14/11/2025
Description
In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
bpf: Do mark_chain_precision for ARG_CONST_ALLOC_SIZE_OR_ZERO<br />
<br />
Precision markers need to be propagated whenever we have an ARG_CONST_*<br />
style argument, as the verifier cannot consider imprecise scalars to be<br />
equivalent for the purposes of states_equal check when such arguments<br />
refine the return value (in this case, set mem_size for PTR_TO_MEM). The<br />
resultant mem_size for the R0 is derived from the constant value, and if<br />
the verifier incorrectly prunes states considering them equivalent where<br />
such arguments exist (by seeing that both registers have reg->precise as<br />
false in regsafe), we can end up with invalid programs passing the<br />
verifier which can do access beyond what should have been the correct<br />
mem_size in that explored state.<br />
<br />
To show a concrete example of the problem:<br />
<br />
0000000000000000 :<br />
0: r2 = *(u32 *)(r1 + 80)<br />
1: r1 = *(u32 *)(r1 + 76)<br />
2: r3 = r1<br />
3: r3 += 4<br />
4: if r3 > r2 goto +18 <br />
5: w2 = 0<br />
6: *(u32 *)(r1 + 0) = r2<br />
7: r1 = *(u32 *)(r1 + 0)<br />
8: r2 = 1<br />
9: if w1 == 0 goto +1 <br />
10: r2 = -1<br />
<br />
0000000000000058 :<br />
11: r1 = 0 ll<br />
13: r3 = 0<br />
14: call bpf_ringbuf_reserve<br />
15: if r0 == 0 goto +7 <br />
16: r1 = r0<br />
17: r1 += 16777215<br />
18: w2 = 0<br />
19: *(u8 *)(r1 + 0) = r2<br />
20: r1 = r0<br />
21: r2 = 0<br />
22: call bpf_ringbuf_submit<br />
<br />
00000000000000b8 :<br />
23: w0 = 0<br />
24: exit<br />
<br />
For the first case, the single line execution&#39;s exploration will prune<br />
the search at insn 14 for the branch insn 9&#39;s second leg as it will be<br />
verified first using r2 = -1 (UINT_MAX), while as w1 at insn 9 will<br />
always be 0 so at runtime we don&#39;t get error for being greater than<br />
UINT_MAX/4 from bpf_ringbuf_reserve. The verifier during regsafe just<br />
sees reg->precise as false for both r2 registers in both states, hence<br />
considers them equal for purposes of states_equal.<br />
<br />
If we propagated precise markers using the backtracking support, we<br />
would use the precise marking to then ensure that old r2 (UINT_MAX) was<br />
within the new r2 (1) and this would never be true, so the verification<br />
would rightfully fail.<br />
<br />
The end result is that the out of bounds access at instruction 19 would<br />
be permitted without this fix.<br />
<br />
Note that reg->precise is always set to true when user does not have<br />
CAP_BPF (or when subprog count is greater than 1 (i.e. use of any static<br />
or global functions)), hence this is only a problem when precision marks<br />
need to be explicitly propagated (i.e. privileged users with CAP_BPF).<br />
<br />
A simplified test case has been included in the next patch to prevent<br />
future regressions.
Impact
Base Score 3.x
7.10
Severity 3.x
HIGH
Vulnerable products and versions
| CPE | From | Up to |
|---|---|---|
| cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 5.8 (including) | 5.19.8 (excluding) |
| cpe:2.3:o:linux:linux_kernel:6.0:rc1:*:*:*:*:*:* | ||
| cpe:2.3:o:linux:linux_kernel:6.0:rc2:*:*:*:*:*:* | ||
| cpe:2.3:o:linux:linux_kernel:6.0:rc3:*:*:*:*:*:* |
To consult the complete list of CPE names with products and versions, see this page



