From: Jo-Philipp Wich Date: Thu, 18 Sep 2014 10:09:12 +0000 (+0200) Subject: utils: rework fw3_bitlen2netmask() IPv6 mask calculation X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=8ea29822ce53c36c91c7b67c6a99b2c50f2c373f;p=oweals%2Ffirewall3.git utils: rework fw3_bitlen2netmask() IPv6 mask calculation The previous code wrote beyound the end of the destination buffer under certain circumstances, causing possible heap corruptions. Rewrite the IPv6 mask calculation code to use a safe byte-wise assignment loop instead of two memset() calls and one byte assignment in the middle. Signed-off-by: Jo-Philipp Wich --- diff --git a/utils.c b/utils.c index 756633a..71a0f13 100644 --- a/utils.c +++ b/utils.c @@ -774,6 +774,7 @@ bool fw3_bitlen2netmask(int family, int bits, void *mask) { int i; + uint8_t rem, b; struct in_addr *v4; struct in6_addr *v6; @@ -783,18 +784,17 @@ fw3_bitlen2netmask(int family, int bits, void *mask) return false; v6 = mask; - i = abs(bits); + rem = abs(bits); - memset(v6->s6_addr, 0xff, i / 8); - - if (i < 128) + for (i = 0; i < sizeof(v6->s6_addr); i++) { - memset(v6->s6_addr + (i / 8) + 1, 0, (128 - i) / 8); - v6->s6_addr[i / 8] = 0xff << (8 - (i & 7)); + b = (rem > 8) ? 8 : rem; + v6->s6_addr[i] = (uint8_t)(0xFF << (8 - b)); + rem -= b; } if (bits < 0) - for (i = 0; i < 16; i++) + for (i = 0; i < sizeof(v6->s6_addr); i++) v6->s6_addr[i] = ~v6->s6_addr[i]; } else