Skip to content

Commit

Permalink
bpf: fix precision bit propagation for BPF_ST instructions
Browse files Browse the repository at this point in the history
When backtracking instructions to propagate precision bit for registers
and stack slots, one class of instructions (BPF_ST) weren't handled
causing extra stack slots to be propagated into parent state. Parent
state might not have that much stack allocated, though, which causes
warning on invalid stack slot usage.

This patch adds handling of BPF_ST instructions:

BPF_MEM | <size> | BPF_ST:   *(size *) (dst_reg + off) = imm32

Reported-by: [email protected]
Fixes: b5dc016 ("bpf: precise scalar_value tracking")
Cc: Alexei Starovoitov <[email protected]>
Signed-off-by: Andrii Nakryiko <[email protected]>
Signed-off-by: Daniel Borkmann <[email protected]>
  • Loading branch information
anakryiko authored and borkmann committed Jul 12, 2019
1 parent 327835f commit b3b50f0
Showing 1 changed file with 4 additions and 7 deletions.
11 changes: 4 additions & 7 deletions kernel/bpf/verifier.c
Original file line number Diff line number Diff line change
Expand Up @@ -1519,9 +1519,9 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx,
return -EFAULT;
}
*stack_mask |= 1ull << spi;
} else if (class == BPF_STX) {
} else if (class == BPF_STX || class == BPF_ST) {
if (*reg_mask & dreg)
/* stx shouldn't be using _scalar_ dst_reg
/* stx & st shouldn't be using _scalar_ dst_reg
* to access memory. It means backtracking
* encountered a case of pointer subtraction.
*/
Expand All @@ -1540,7 +1540,8 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx,
if (!(*stack_mask & (1ull << spi)))
return 0;
*stack_mask &= ~(1ull << spi);
*reg_mask |= sreg;
if (class == BPF_STX)
*reg_mask |= sreg;
} else if (class == BPF_JMP || class == BPF_JMP32) {
if (opcode == BPF_CALL) {
if (insn->src_reg == BPF_PSEUDO_CALL)
Expand Down Expand Up @@ -1569,10 +1570,6 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx,
if (mode == BPF_IND || mode == BPF_ABS)
/* to be analyzed */
return -ENOTSUPP;
} else if (class == BPF_ST) {
if (*reg_mask & dreg)
/* likely pointer subtraction */
return -ENOTSUPP;
}
return 0;
}
Expand Down

0 comments on commit b3b50f0

Please sign in to comment.