aboutsummaryrefslogtreecommitdiff
path: root/optimize.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2018-07-12 13:59:18 -0700
committerGuy Harris <guy@alum.mit.edu>2018-07-12 13:59:33 -0700
commitb5c22d454a3144ebf434d688b3b6d97573aa4c12 (patch)
tree2e8ac79e973a5123cd0595cef627bd0c7bb3caf9 /optimize.c
parent89f9d9d5b7d24ef244317acc24ddc0aa3665cbb6 (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.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/optimize.c b/optimize.c
index 7c6424b0..947a3993 100644
--- a/optimize.c
+++ b/optimize.c
@@ -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]);