From: Thomas Haller Date: Thu, 13 Dec 2018 18:59:46 +0000 (+0100) Subject: in-addr-util: fix undefined result for in4_addr_netmask_to_prefixlen(<0.0.0.0>) X-Git-Tag: v240~61 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1a359852641119db951da03bf9c67f9dc34d6257;p=thirdparty%2Fsystemd.git in-addr-util: fix undefined result for in4_addr_netmask_to_prefixlen(<0.0.0.0>) 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 --- diff --git a/src/basic/in-addr-util.c b/src/basic/in-addr-util.c index 4bb7d9c5e0a..411efb242b9 100644 --- a/src/basic/in-addr-util.c +++ b/src/basic/in-addr-util.c @@ -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) { diff --git a/src/basic/util.h b/src/basic/util.h index 01118bb8954..85a7a15843c 100644 --- a/src/basic/util.h +++ b/src/basic/util.h @@ -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