From b98481167269b96bb60c4795dba04940202dbde3 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Fri, 22 Jan 2021 16:00:56 +0100 Subject: [PATCH] bpf: Fix buggy rsh min/max bounds tracking [ no upstream commit ] Fix incorrect bounds tracking for RSH opcode. Commit f23cc643f9ba ("bpf: fix range arithmetic for bpf map access") had a wrong assumption about min/max bounds. The new dst_reg->min_value needs to be derived by right shifting the max_val bounds, not min_val, and likewise new dst_reg->max_value needs to be derived by right shifting the min_val bounds, not max_val. Later stable kernels than 4.9 are not affected since bounds tracking was overall reworked and they already track this similarly as in the fix. Fixes: f23cc643f9ba ("bpf: fix range arithmetic for bpf map access") Reported-by: Ryota Shiga (Flatt Security) Signed-off-by: Daniel Borkmann Reviewed-by: John Fastabend Cc: Josef Bacik Signed-off-by: Greg Kroah-Hartman --- kernel/bpf/verifier.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 335c00209f74..78bdfbefd996 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -1732,12 +1732,11 @@ static void adjust_reg_min_max_vals(struct bpf_verifier_env *env, * unsigned shift, so make the appropriate casts. */ if (min_val < 0 || dst_reg->min_value < 0) - dst_reg->min_value = BPF_REGISTER_MIN_RANGE; + reset_reg_range_values(regs, insn->dst_reg); else - dst_reg->min_value = - (u64)(dst_reg->min_value) >> min_val; + dst_reg->min_value = (u64)(dst_reg->min_value) >> max_val; if (dst_reg->max_value != BPF_REGISTER_MAX_RANGE) - dst_reg->max_value >>= max_val; + dst_reg->max_value >>= min_val; break; default: reset_reg_range_values(regs, insn->dst_reg);