]> git.ipfire.org Git - location/libloc.git/commitdiff
address: Prevent under/overflow when incrementing/decrementing
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 7 Mar 2022 14:47:12 +0000 (14:47 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 7 Mar 2022 14:47:12 +0000 (14:47 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libloc/address.h

index 363a1c11160f4ea4fac4e89a0052d805168d5322..754387e97b7a21cad596cc5b574d1d31558e6afd 100644 (file)
@@ -75,6 +75,31 @@ static inline int loc_address_cmp(const struct in6_addr* a1, const struct in6_ad
        return 0;
 }
 
+#define foreach_octet_in_address(octet, address) \
+       for (octet = (IN6_IS_ADDR_V4MAPPED(address) ? 12 : 0); octet <= 15; octet++)
+
+static inline int loc_address_all_zeroes(const struct in6_addr* address) {
+       int octet = 0;
+
+       foreach_octet_in_address(octet, address) {
+               if (address->s6_addr[octet])
+                       return 0;
+       }
+
+       return 1;
+}
+
+static inline int loc_address_all_ones(const struct in6_addr* address) {
+       int octet = 0;
+
+       foreach_octet_in_address(octet, address) {
+               if (address->s6_addr[octet] < 255)
+                       return 0;
+       }
+
+       return 1;
+}
+
 static inline int loc_address_get_bit(const struct in6_addr* address, unsigned int i) {
        return ((address->s6_addr[i / 8] >> (7 - (i % 8))) & 1);
 }
@@ -258,6 +283,10 @@ static inline int loc_address_sub(struct in6_addr* result,
 }
 
 static inline void loc_address_increment(struct in6_addr* address) {
+       // Prevent overflow when everything is ones
+       if (loc_address_all_ones(address))
+               return;
+
        for (int octet = 15; octet >= 0; octet--) {
                if (address->s6_addr[octet] < 255) {
                        address->s6_addr[octet]++;
@@ -269,6 +298,10 @@ static inline void loc_address_increment(struct in6_addr* address) {
 }
 
 static inline void loc_address_decrement(struct in6_addr* address) {
+       // Prevent underflow when everything is ones
+       if (loc_address_all_zeroes(address))
+               return;
+
        for (int octet = 15; octet >= 0; octet--) {
                if (address->s6_addr[octet] > 0) {
                        address->s6_addr[octet]--;
@@ -277,21 +310,6 @@ static inline void loc_address_decrement(struct in6_addr* address) {
        }
 }
 
-static inline int loc_address_all_zeroes(const struct in6_addr* address) {
-       struct in6_addr all_zeroes = IN6ADDR_ANY_INIT;
-
-       const int family = loc_address_family(address);
-
-       int r = loc_address_reset(&all_zeroes, family);
-       if (r)
-               return r;
-
-       if (loc_address_cmp(address, &all_zeroes) == 0)
-               return 1;
-
-       return 0;
-}
-
 static inline int loc_address_count_trailing_zero_bits(const struct in6_addr* address) {
        int zeroes = 0;