Skip to content

bpf: Fix abs(INT_MIN) undefined behavior in interpreter sdiv/smod#11343

Closed
kernel-patches-daemon-bpf[bot] wants to merge 2 commits intobpf-next_basefrom
series/1063949=>bpf-next
Closed

bpf: Fix abs(INT_MIN) undefined behavior in interpreter sdiv/smod#11343
kernel-patches-daemon-bpf[bot] wants to merge 2 commits intobpf-next_basefrom
series/1063949=>bpf-next

Conversation

@kernel-patches-daemon-bpf
Copy link

Pull request for series with
subject: bpf: Fix abs(INT_MIN) undefined behavior in interpreter sdiv/smod
version: 4
url: https://patchwork.kernel.org/project/netdevbpf/list/?series=1063949

@kernel-patches-daemon-bpf
Copy link
Author

Upstream branch: bd2e02e
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=1063949
version: 4

@kernel-patches-daemon-bpf
Copy link
Author

Upstream branch: bd2e02e
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=1063949
version: 4

@kernel-patches-daemon-bpf
Copy link
Author

Upstream branch: bd2e02e
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=1063949
version: 4

@kernel-patches-daemon-bpf
Copy link
Author

Upstream branch: bd2e02e
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=1063949
version: 4

@kernel-patches-daemon-bpf
Copy link
Author

Upstream branch: bd2e02e
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=1063949
version: 4

@kernel-patches-daemon-bpf
Copy link
Author

Upstream branch: 0c55d48
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=1063949
version: 4

Jenny Guanni Qu added 2 commits March 10, 2026 11:58
The BPF interpreter's signed 32-bit division and modulo handlers use
the kernel abs() macro on s32 operands. The abs() macro documentation
(include/linux/math.h) explicitly states the result is undefined when
the input is the type minimum. When DST contains S32_MIN (0x80000000),
abs((s32)DST) triggers undefined behavior and returns S32_MIN unchanged
on arm64/x86. This value is then sign-extended to u64 as
0xFFFFFFFF80000000, causing do_div() to compute the wrong result.

The verifier's abstract interpretation (scalar32_min_max_sdiv) computes
the mathematically correct result for range tracking, creating a
verifier/interpreter mismatch that can be exploited for out-of-bounds
map value access.

Introduce __safe_abs32() which handles S32_MIN correctly by casting
to u32 before negating, avoiding signed overflow entirely. Replace
all 8 abs((s32)...) call sites in the interpreter's sdiv32/smod32
handlers.

Fixes: ec0e2da ("bpf: Support new signed div/mod instructions.")
Acked-by: Yonghong Song <yonghong.song@linux.dev>
Signed-off-by: Jenny Guanni Qu <qguanni@gmail.com>
Acked-by: Mykyta Yatsenko <yatsenko@meta.com>
Add tests to verify that signed 32-bit division and modulo operations
produce correct results when the dividend is INT_MIN (0x80000000).

The bug fixed in the previous commit only affects the BPF interpreter
path. When JIT is enabled (the default on most architectures), the
native CPU division instruction produces the correct result and these
tests pass regardless. With bpf_jit_enable=0, the interpreter is used
and without the previous fix, INT_MIN / 2 incorrectly returns
0x40000000 instead of 0xC0000000 due to abs(S32_MIN) undefined
behavior, causing these tests to fail.

Test cases:
  - SDIV32 INT_MIN / 2 = -1073741824 (imm and reg divisor)
  - SMOD32 INT_MIN % 2 = 0 (positive and negative divisor)

Signed-off-by: Jenny Guanni Qu <qguanni@gmail.com>
Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Acked-by: Yonghong Song <yonghong.song@linux.dev>
@kernel-patches-daemon-bpf
Copy link
Author

At least one diff in series https://patchwork.kernel.org/project/netdevbpf/list/?series=1063949 expired. Closing PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants