]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
in-addr-util: fix undefined result for in4_addr_netmask_to_prefixlen(<0.0.0.0>)
authorThomas Haller <thaller@redhat.com>
Thu, 13 Dec 2018 18:59:46 +0000 (19:59 +0100)
committerLennart Poettering <lennart@poettering.net>
Fri, 14 Dec 2018 10:15:36 +0000 (11:15 +0100)
u32ctz() was undefined for zero due to __builtin_ctz() [1].
Explicitly check for zero to make the behavior defined.

Note that this issue only affected in4_addr_netmask_to_prefixlen()
which is the only caller.

It may seem slightly odd, to return 32 (bits) for utz(0). But that
is what in4_addr_netmask_to_prefixlen() needs, and it probably makes
the most sense here.

[1] https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html

Fixes: ba91431154ad7bac82ddf0a540ec1b40db62d782
src/basic/in-addr-util.c
src/basic/util.h

index 4bb7d9c5e0a6858be21a869ba5b387609f4318c3..411efb242b9abd49c0f2d4b2d52595e84b3b23f6 100644 (file)
@@ -362,7 +362,7 @@ int in_addr_ifindex_from_string_auto(const char *s, int *family, union in_addr_u
 unsigned char in4_addr_netmask_to_prefixlen(const struct in_addr *addr) {
         assert(addr);
 
-        return 32 - u32ctz(be32toh(addr->s_addr));
+        return 32U - u32ctz(be32toh(addr->s_addr));
 }
 
 struct in_addr* in4_addr_prefixlen_to_netmask(struct in_addr *addr, unsigned char prefixlen) {
index 01118bb895477bc1d6d2d69a892361a31f37e158..85a7a15843c8dc9009e661cd27030c0d22d8a847 100644 (file)
@@ -193,7 +193,7 @@ static inline unsigned u64log2(uint64_t n) {
 
 static inline unsigned u32ctz(uint32_t n) {
 #if __SIZEOF_INT__ == 4
-        return __builtin_ctz(n);
+        return n != 0 ? __builtin_ctz(n) : 32;
 #else
 #error "Wut?"
 #endif