mirror of
https://github.com/torvalds/linux.git
synced 2026-09-21 04:10:02 +02:00
bpf, arm64: Fix exception table metadata for arena load-acquire
Same problem as on x86-64: add_exception_handler() decides whether an
instruction is a load by its class, and a load-acquire is of BPF_STX
class even though it reads from src_reg into dst_reg. As a result ...
if (BPF_CLASS(insn->code) != BPF_LDX)
dst_reg = DONT_CLEAR;
... drops the register to clear, and ...
if (BPF_CLASS(insn->code) == BPF_LDX)
arena_reg = bpf2a64[insn->src_reg];
else
arena_reg = bpf2a64[insn->dst_reg];
... hands ex_handler_bpf() the value register instead of the address
register. A load-acquire from an arena pointer that faults on an
unmapped page is therefore reported as a WRITE at a bogus address,
and dst_reg keeps its previous value instead of being cleared to 0.
Note that emit_atomic_ld_st() already picks src_reg as the address
for BPF_LOAD_ACQ, so only the exception table metadata was out of sync
with the emitted access.
Same as on x86-64, use bpf_atomic_is_load_acq() so a load-acquire takes
the load path.
Fixes: 9bb12368d5 ("bpf, arm64: Support load-acquire and store-release instructions")
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Reviewed-by: Puranjay Mohan <puranjay@kernel.org>
Link: https://lore.kernel.org/bpf/20260806201047.333389-4-daniel@iogearbox.net
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
This commit is contained in:
parent
4cf8def58b
commit
af22d273aa
|
|
@ -1178,7 +1178,12 @@ static int add_exception_handler(const struct bpf_insn *insn,
|
|||
|
||||
ex->insn = ins_offset;
|
||||
|
||||
if (BPF_CLASS(insn->code) != BPF_LDX)
|
||||
/*
|
||||
* A load-acquire is of BPF_STX class, but reads from src_reg into
|
||||
* dst_reg like a BPF_LDX does, hence it must not be treated as a store
|
||||
* here.
|
||||
*/
|
||||
if (BPF_CLASS(insn->code) != BPF_LDX && !bpf_atomic_is_load_acq(insn))
|
||||
dst_reg = DONT_CLEAR;
|
||||
|
||||
ex->fixup = FIELD_PREP(BPF_FIXUP_REG_MASK, dst_reg);
|
||||
|
|
@ -1193,7 +1198,7 @@ static int add_exception_handler(const struct bpf_insn *insn,
|
|||
* memory access. Pass the reg holding the unmodified 32-bit address to
|
||||
* ex_handler_bpf.
|
||||
*/
|
||||
if (BPF_CLASS(insn->code) == BPF_LDX)
|
||||
if (BPF_CLASS(insn->code) == BPF_LDX || bpf_atomic_is_load_acq(insn))
|
||||
arena_reg = bpf2a64[insn->src_reg];
|
||||
else
|
||||
arena_reg = bpf2a64[insn->dst_reg];
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user