|
@@ -2190,20 +2190,22 @@ static int adjust_scalar_min_max_vals(struct bpf_verifier_env *env,
|
|
|
mark_reg_unknown(env, regs, insn->dst_reg);
|
|
|
break;
|
|
|
}
|
|
|
- /* BPF_RSH is an unsigned shift, so make the appropriate casts */
|
|
|
- if (dst_reg->smin_value < 0) {
|
|
|
- if (umin_val) {
|
|
|
- /* Sign bit will be cleared */
|
|
|
- dst_reg->smin_value = 0;
|
|
|
- } else {
|
|
|
- /* Lost sign bit information */
|
|
|
- dst_reg->smin_value = S64_MIN;
|
|
|
- dst_reg->smax_value = S64_MAX;
|
|
|
- }
|
|
|
- } else {
|
|
|
- dst_reg->smin_value =
|
|
|
- (u64)(dst_reg->smin_value) >> umax_val;
|
|
|
- }
|
|
|
+ /* BPF_RSH is an unsigned shift. If the value in dst_reg might
|
|
|
+ * be negative, then either:
|
|
|
+ * 1) src_reg might be zero, so the sign bit of the result is
|
|
|
+ * unknown, so we lose our signed bounds
|
|
|
+ * 2) it's known negative, thus the unsigned bounds capture the
|
|
|
+ * signed bounds
|
|
|
+ * 3) the signed bounds cross zero, so they tell us nothing
|
|
|
+ * about the result
|
|
|
+ * If the value in dst_reg is known nonnegative, then again the
|
|
|
+ * unsigned bounts capture the signed bounds.
|
|
|
+ * Thus, in all cases it suffices to blow away our signed bounds
|
|
|
+ * and rely on inferring new ones from the unsigned bounds and
|
|
|
+ * var_off of the result.
|
|
|
+ */
|
|
|
+ dst_reg->smin_value = S64_MIN;
|
|
|
+ dst_reg->smax_value = S64_MAX;
|
|
|
if (src_known)
|
|
|
dst_reg->var_off = tnum_rshift(dst_reg->var_off,
|
|
|
umin_val);
|