diff options
author | Guy Harris <guy@alum.mit.edu> | 2018-07-12 13:59:18 -0700 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2018-07-12 13:59:33 -0700 |
commit | b5c22d454a3144ebf434d688b3b6d97573aa4c12 (patch) | |
tree | 2e8ac79e973a5123cd0595cef627bd0c7bb3caf9 /optimize.c | |
parent | 89f9d9d5b7d24ef244317acc24ddc0aa3665cbb6 (diff) |
Cast the LHS if bit shifts to bpf_u_int32 to avoid undefined behavior.
To quote C99 6.5.7 "Bitwise shift operators":
The integer promotions are performed on each of the operands.
The type of the result is that of the promoted left operand.
The result of E1 << E2 is E1 left-shifted E2 bit positions;
vacated bits are filled with zeros. If E1 has an unsigned type,
the value of the result is E1*2^E2, reduced modulo one more than
the maximum value representable in the result type. If E1 has a
signed type and nonnegative value, and E1*2^E2 is representable
in the result type, then that is the resulting value; otherwise,
the behavior is undefined.
This means that, in 1 << x, an int value, i.e. a signed value, is being
shifted, and 2^31 isn't representable as a 32-bit int.
The bits we're setting/clearing/testing are from a bpf_u_int32, so cast
1 to bpf_u_int32 before shifting.
Diffstat (limited to 'optimize.c')
-rw-r--r-- | optimize.c | 8 |
1 files changed, 4 insertions, 4 deletions
@@ -252,19 +252,19 @@ typedef struct { * True if a is in uset {p} */ #define SET_MEMBER(p, a) \ -((p)[(unsigned)(a) / BITS_PER_WORD] & (1 << ((unsigned)(a) % BITS_PER_WORD))) +((p)[(unsigned)(a) / BITS_PER_WORD] & ((bpf_u_int32)1 << ((unsigned)(a) % BITS_PER_WORD))) /* * Add 'a' to uset p. */ #define SET_INSERT(p, a) \ -(p)[(unsigned)(a) / BITS_PER_WORD] |= (1 << ((unsigned)(a) % BITS_PER_WORD)) +(p)[(unsigned)(a) / BITS_PER_WORD] |= ((bpf_u_int32)1 << ((unsigned)(a) % BITS_PER_WORD)) /* * Delete 'a' from uset p. */ #define SET_DELETE(p, a) \ -(p)[(unsigned)(a) / BITS_PER_WORD] &= ~(1 << ((unsigned)(a) % BITS_PER_WORD)) +(p)[(unsigned)(a) / BITS_PER_WORD] &= ~((bpf_u_int32)1 << ((unsigned)(a) % BITS_PER_WORD)) /* * a := a intersect b @@ -1480,7 +1480,7 @@ opt_j(opt_state_t *opt_state, struct edge *ep) while (x != 0) { k = lowest_set_bit(x); - x &=~ (1 << k); + x &=~ ((bpf_u_int32)1 << k); k += i * BITS_PER_WORD; target = fold_edge(ep->succ, opt_state->edges[k]); |