We already caught them in the code generator - but only if they were
between 31 and 2^31-1, but we weren't catching them when shifts by the X
register got optimized into shifts by a constant, so we need to:
1) catch it in the optimizer;
2) fix the check in the code generator.
(In the longer run, we need to clear up signed vs. unsigned stuff in the
code generator and optimizer.)
Credit to OSS-Fuzz for finding the optimizer issue (which was using a
shift constant that was "negative", thus pointing out the code generator
issue).
if (a1->s->s.code == (BPF_LD|BPF_IMM) && a1->s->s.k == 0)
bpf_error(cstate, "modulus by zero");
} else if (code == BPF_LSH || code == BPF_RSH) {
- if (a1->s->s.code == (BPF_LD|BPF_IMM) && a1->s->s.k > 31)
+ /*
+ * XXX - we need to make up our minds as to what integers
+ * are signed and what integers are unsigned in BPF programs
+ * and in our IR.
+ */
+ if (a1->s->s.code == (BPF_LD|BPF_IMM) &&
+ (a1->s->s.k < 0 || a1->s->s.k > 31))
bpf_error(cstate, "shift by more than 31 bits");
}
s0 = xfer_to_x(cstate, a1);
else {
s->code = BPF_ALU|BPF_K|op;
s->k = opt_state->vmap[val[X_ATOM]].const_val;
+ /*
+ * XXX - we need to make up our minds
+ * as to what integers are signed and
+ * what integers are unsigned in BPF
+ * programs and in our IR.
+ */
+ if ((op == BPF_LSH || op == BPF_RSH) &&
+ (s->k < 0 || s->k > 31))
+ opt_error(cstate, opt_state,
+ "shift by more than 31 bits");
opt_state->done = 0;
val[A_ATOM] =
F(opt_state, s->code, val[A_ATOM], K(s->k));