mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
Merge branch 'bpf-fix-missed-var_off-related-to-movsx-in-verifier'
Yonghong Song says: ==================== bpf: Fix missed var_off related to movsx in verifier Zac reported a verification issue ([1]) where verification unexpectedly succeeded. This is due to missing proper var_off setting in verifier related to movsx insn. I found another similar issue as well. This patch set fixed both problems and added three inline asm tests to test these fixes. [1] https://lore.kernel.org/bpf/CAADnVQLPU0Shz7dWV4bn2BgtGdxN3uFHPeobGBA72tpg5Xoykw@mail.gmail.com/ ==================== Acked-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://lore.kernel.org/r/20240615174621.3994321-1-yonghong.song@linux.dev Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
commit
bfbcb2c9d2
@ -6236,6 +6236,7 @@ static void set_sext32_default_val(struct bpf_reg_state *reg, int size)
|
||||
}
|
||||
reg->u32_min_value = 0;
|
||||
reg->u32_max_value = U32_MAX;
|
||||
reg->var_off = tnum_subreg(tnum_unknown);
|
||||
}
|
||||
|
||||
static void coerce_subreg_to_size_sx(struct bpf_reg_state *reg, int size)
|
||||
@ -6280,6 +6281,7 @@ static void coerce_subreg_to_size_sx(struct bpf_reg_state *reg, int size)
|
||||
reg->s32_max_value = s32_max;
|
||||
reg->u32_min_value = (u32)s32_min;
|
||||
reg->u32_max_value = (u32)s32_max;
|
||||
reg->var_off = tnum_subreg(tnum_range(s32_min, s32_max));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -224,6 +224,69 @@ l0_%=: \
|
||||
: __clobber_all);
|
||||
}
|
||||
|
||||
SEC("socket")
|
||||
__description("MOV32SX, S8, var_off u32_max")
|
||||
__failure __msg("infinite loop detected")
|
||||
__failure_unpriv __msg_unpriv("back-edge from insn 2 to 0")
|
||||
__naked void mov64sx_s32_varoff_1(void)
|
||||
{
|
||||
asm volatile (" \
|
||||
l0_%=: \
|
||||
r3 = *(u8 *)(r10 -387); \
|
||||
w7 = (s8)w3; \
|
||||
if w7 >= 0x2533823b goto l0_%=; \
|
||||
w0 = 0; \
|
||||
exit; \
|
||||
" :
|
||||
:
|
||||
: __clobber_all);
|
||||
}
|
||||
|
||||
SEC("socket")
|
||||
__description("MOV32SX, S8, var_off not u32_max, positive after s8 extension")
|
||||
__success __retval(0)
|
||||
__failure_unpriv __msg_unpriv("frame pointer is read only")
|
||||
__naked void mov64sx_s32_varoff_2(void)
|
||||
{
|
||||
asm volatile (" \
|
||||
call %[bpf_get_prandom_u32]; \
|
||||
r3 = r0; \
|
||||
r3 &= 0xf; \
|
||||
w7 = (s8)w3; \
|
||||
if w7 s>= 16 goto l0_%=; \
|
||||
w0 = 0; \
|
||||
exit; \
|
||||
l0_%=: \
|
||||
r10 = 1; \
|
||||
exit; \
|
||||
" :
|
||||
: __imm(bpf_get_prandom_u32)
|
||||
: __clobber_all);
|
||||
}
|
||||
|
||||
SEC("socket")
|
||||
__description("MOV32SX, S8, var_off not u32_max, negative after s8 extension")
|
||||
__success __retval(0)
|
||||
__failure_unpriv __msg_unpriv("frame pointer is read only")
|
||||
__naked void mov64sx_s32_varoff_3(void)
|
||||
{
|
||||
asm volatile (" \
|
||||
call %[bpf_get_prandom_u32]; \
|
||||
r3 = r0; \
|
||||
r3 &= 0xf; \
|
||||
r3 |= 0x80; \
|
||||
w7 = (s8)w3; \
|
||||
if w7 s>= -5 goto l0_%=; \
|
||||
w0 = 0; \
|
||||
exit; \
|
||||
l0_%=: \
|
||||
r10 = 1; \
|
||||
exit; \
|
||||
" :
|
||||
: __imm(bpf_get_prandom_u32)
|
||||
: __clobber_all);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
SEC("socket")
|
||||
|
Loading…
Reference in New Issue
Block a user