]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
acl: Avoid undefined behaviour due to 32-bit shift.
authorAndre Noll <maan@tuebingen.mpg.de>
Thu, 16 Nov 2017 02:24:47 +0000 (03:24 +0100)
committerAndre Noll <maan@tuebingen.mpg.de>
Tue, 13 Mar 2018 02:28:10 +0000 (03:28 +0100)
On x86 a shift by 32-bits is a nop, but this is not backed by any
standard. Moreover, not shifting at all results in an effective netmask
of 32, which is unexpected for for v4_addr_match(), as the function
is supposed to answer the question "do the first zero bits of these
two addresses match?". This should always be true, regardless of the
two addresses.

Fix this, and change the return type of the function while at it.

acl.c

diff --git a/acl.c b/acl.c
index 10f56bf1bd90fd62e1bb129140365fbed3c2e136..75fdc55b12842890136afec74e70125f81b6318c 100644 (file)
--- a/acl.c
+++ b/acl.c
@@ -31,10 +31,12 @@ struct access_info {
 /**
  * Return true if addr_1 matches addr_2 in the first `netmask' bits.
  */
-static int v4_addr_match(uint32_t addr_1, uint32_t addr_2, uint8_t netmask)
+static bool v4_addr_match(uint32_t addr_1, uint32_t addr_2, uint8_t netmask)
 {
        uint32_t mask = ~0U;
 
+       if (netmask == 0) /* avoid 32-bit shift, which is undefined in C. */
+               return true;
        if (netmask < 32)
                mask <<= (32 - netmask);
        return (htonl(addr_1) & mask) == (htonl(addr_2) & mask);