]> The Tcpdump Group git mirrors - libpcap/commitdiff
gencode: Fix an undefined behavior in gen_mcode()
authorFrancois-Xavier Le Bail <[email protected]>
Mon, 16 Dec 2024 13:28:26 +0000 (14:28 +0100)
committerfxlb <[email protected]>
Tue, 17 Dec 2024 18:57:35 +0000 (18:57 +0000)
Use a temporary 64-bit variable for the shift result.

Netmask length 0 is no longer a special case.

The error was:

$ testprogs/filtertest EN10MB net 192.168.0.0/16
gencode.c:7446:19: runtime error: left shift of 4294967295 by 16 places
  cannot be represented in type 'unsigned int'

SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior gencode.c:7446:19

$ testprogs/filtertest EN10MB net 10.0.1.0/24
gencode.c:7446:19: runtime error: left shift of 4294967295 by 8 places
  cannot be represented in type 'unsigned int'

SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior gencode.c:7446:19

gencode.c

index 0c6af6a2134b916802d92d2c48129df162ebd322..cdfc738e191f45d394a109ec323e38298c7c53ea 100644 (file)
--- a/gencode.c
+++ b/gencode.c
@@ -7409,6 +7409,7 @@ gen_mcode(compiler_state_t *cstate, const char *s1, const char *s2,
 {
        register int nlen, mlen;
        bpf_u_int32 n, m;
+       uint64_t m64;
 
        /*
         * Catch errors reported by us and routines below us, and return NULL
@@ -7436,14 +7437,8 @@ gen_mcode(compiler_state_t *cstate, const char *s1, const char *s2,
                /* Convert mask len to mask */
                if (masklen > 32)
                        bpf_error(cstate, "mask length must be <= 32");
-               if (masklen == 0) {
-                       /*
-                        * X << 32 is not guaranteed by C to be 0; it's
-                        * undefined.
-                        */
-                       m = 0;
-               } else
-                       m = 0xffffffff << (32 - masklen);
+               m64 = UINT64_C(0xffffffff) << (32 - masklen);
+               m = (bpf_u_int32)m64;
                if ((n & ~m) != 0)
                        bpf_error(cstate, "non-network bits set in \"%s/%d\"",
                            s1, masklen);