aboutsummaryrefslogtreecommitdiff
path: root/optimize.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2018-10-16 15:57:06 -0700
committerGuy Harris <guy@alum.mit.edu>2018-10-16 15:57:06 -0700
commitf3dd3f4680d43b6c857a3fbe38c445d28fa62e14 (patch)
tree47843370fc9fba7477f5c842a06d33c64f1c8600 /optimize.c
parenta7f69da5b4939ad107f773eedca07838b05b4fab (diff)
Don't shift by more than 31 bit positions.
That's undefined in C, and there are currently-used processors on which a shift of 32 bits, for example, shifts all the bits out and processors on which it does no shift (i.e., the shift count is, or isn't, taken modulo 32). We'll treat it as shifting all the bits out. Note that the BPF interpreter doesn't do this test, so the BPF machine's behavior mirrors the behavior of the processor on which it's running. We suggest you not write filter expressions, or BPF programs, that rely on any particular behavior from shifts of more than 31 bits. Credit to OSS-Fuzz for finding this issue.
Diffstat (limited to 'optimize.c')
-rw-r--r--optimize.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/optimize.c b/optimize.c
index fa8e0ac1..0d2fcca2 100644
--- a/optimize.c
+++ b/optimize.c
@@ -745,11 +745,39 @@ fold_op(compiler_state_t *cstate, opt_state_t *opt_state,
break;
case BPF_LSH:
- a <<= b;
+ /*
+ * A left shift of more than the width of the type
+ * is undefined in C; we'll just treat it as shifting
+ * all the bits out.
+ *
+ * XXX - the BPF interpreter doesn't check for this,
+ * so its behavior is dependent on the behavior of
+ * the processor on which it's running. There are
+ * processors on which it shifts all the bits out
+ * and processors on which it does no shift.
+ */
+ if (b < 32)
+ a <<= b;
+ else
+ a = 0;
break;
case BPF_RSH:
- a >>= b;
+ /*
+ * A right shift of more than the width of the type
+ * is undefined in C; we'll just treat it as shifting
+ * all the bits out.
+ *
+ * XXX - the BPF interpreter doesn't check for this,
+ * so its behavior is dependent on the behavior of
+ * the processor on which it's running. There are
+ * processors on which it shifts all the bits out
+ * and processors on which it does no shift.
+ */
+ if (b < 32)
+ a >>= b;
+ else
+ a = 0;
break;
default: