diff options
| author | Eduard Zingerman <eddyz87@gmail.com> | 2026-04-26 01:48:23 +0300 |
|---|---|---|
| committer | Alexei Starovoitov <ast@kernel.org> | 2026-04-27 19:56:38 +0300 |
| commit | cd5b460ed1eca9e48f3eb07db1ee0a522c0eaa23 (patch) | |
| tree | 155f0c1bb57a4b0796e019a47ceab9249762197a /include/uapi | |
| parent | 7c8d208d816d0504aa916138ae097d9cb4ed4e56 (diff) | |
| download | linux-cd5b460ed1eca9e48f3eb07db1ee0a522c0eaa23.tar.xz | |
bpf: range_within() must check cnum ranges instead of min/max pairs
states.c:range_within() must be updated to properly check if
cnum-based range in an old state is a superset of a range in the cur
state. Currently it makes the decision using min/max accessors:
reg_umin(old) <= reg_umin(cur) <= reg_umax(old)
This is wrong for cnums that cross both UT_MAX/0 and ST_MAX/ST_MIN
boundaries. Consider cnum32{base=0x7FFFFFF0, size=0x80000020},
which represents values [0x7FFFFFF0, ..., U32_MAX, 0, ..., 0x10].
Its projections are u32_min/max=0/U32_MAX, s32_min/max=S32_MIN/MAX.
A register with range [0x100, 0x200] (which lies entirely in the gap
of the wrapping range) would pass the min/max check despite having no
overlap with the actual cnum arc.
This commit replaces min/max comparison with cnum{32,64}_is_subset()
operation. The operation implementation is verified using cbmc model
checker in [1].
[1] https://github.com/eddyz87/cnum-verif/
Fixes: bbc631085503 ("bpf: replace min/max fields with struct cnum{32,64}")
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20260425-cnum-range-within-v1-1-2fdca70cb09d@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'include/uapi')
0 files changed, 0 insertions, 0 deletions
