Skip to content

Commit c87ef24

Browse files
borkmanngregkh
authored andcommitted
bpf: Fix mask direction swap upon off reg sign change
commit bb01a1b upstream. Masking direction as indicated via mask_to_left is considered to be calculated once and then used to derive pointer limits. Thus, this needs to be placed into bpf_sanitize_info instead so we can pass it to sanitize_ptr_alu() call after the pointer move. Piotr noticed a corner case where the off reg causes masking direction change which then results in an incorrect final aux->alu_limit. Fixes: 7fedb63 ("bpf: Tighten speculative pointer arithmetic mask") Reported-by: Piotr Krysiuk <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]> Reviewed-by: Piotr Krysiuk <[email protected]> Acked-by: Alexei Starovoitov <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 4e2c7b2 commit c87ef24

File tree

1 file changed

+12
-10
lines changed

1 file changed

+12
-10
lines changed

kernel/bpf/verifier.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5666,18 +5666,10 @@ enum {
56665666
};
56675667

56685668
static int retrieve_ptr_limit(const struct bpf_reg_state *ptr_reg,
5669-
const struct bpf_reg_state *off_reg,
5670-
u32 *alu_limit, u8 opcode)
5669+
u32 *alu_limit, bool mask_to_left)
56715670
{
5672-
bool off_is_neg = off_reg->smin_value < 0;
5673-
bool mask_to_left = (opcode == BPF_ADD && off_is_neg) ||
5674-
(opcode == BPF_SUB && !off_is_neg);
56755671
u32 max = 0, ptr_limit = 0;
56765672

5677-
if (!tnum_is_const(off_reg->var_off) &&
5678-
(off_reg->smin_value < 0) != (off_reg->smax_value < 0))
5679-
return REASON_BOUNDS;
5680-
56815673
switch (ptr_reg->type) {
56825674
case PTR_TO_STACK:
56835675
/* Offset 0 is out-of-bounds, but acceptable start for the
@@ -5745,6 +5737,7 @@ static bool sanitize_needed(u8 opcode)
57455737

57465738
struct bpf_sanitize_info {
57475739
struct bpf_insn_aux_data aux;
5740+
bool mask_to_left;
57485741
};
57495742

57505743
static int sanitize_ptr_alu(struct bpf_verifier_env *env,
@@ -5776,7 +5769,16 @@ static int sanitize_ptr_alu(struct bpf_verifier_env *env,
57765769
if (vstate->speculative)
57775770
goto do_sim;
57785771

5779-
err = retrieve_ptr_limit(ptr_reg, off_reg, &alu_limit, opcode);
5772+
if (!commit_window) {
5773+
if (!tnum_is_const(off_reg->var_off) &&
5774+
(off_reg->smin_value < 0) != (off_reg->smax_value < 0))
5775+
return REASON_BOUNDS;
5776+
5777+
info->mask_to_left = (opcode == BPF_ADD && off_is_neg) ||
5778+
(opcode == BPF_SUB && !off_is_neg);
5779+
}
5780+
5781+
err = retrieve_ptr_limit(ptr_reg, &alu_limit, info->mask_to_left);
57805782
if (err < 0)
57815783
return err;
57825784

0 commit comments

Comments
 (0)