From: Maciej S. Szmigiero Date: Tue, 16 Apr 2019 13:00:50 +0000 (+0200) Subject: Fix strict aliasing violation in inet_checksum() X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=f3ba50ed3d14749b7c1ef100d2a49ac30d3b3853;p=oweals%2Ftinc.git Fix strict aliasing violation in inet_checksum() inet_checksum() accesses packet data as an array of uint16_t, but the packet data can be for example of "anonymous struct pseudo" type from route_ipv6_unreachable(). This type isn't a compatible type with uint16_t so a strict aliasing violation occurs and causes the checksum to be computed incorrectly. Fix this by using the memcpy() idiom to read the packet data as an array of uint16_t in inet_checksum() (this should be understood by compilers and optimized accordingly, so no actual copy occurs). --- diff --git a/src/route.c b/src/route.c index 2e8d94a..2fa6175 100644 --- a/src/route.c +++ b/src/route.c @@ -64,16 +64,18 @@ static timeout_t age_subnets_timeout; /* RFC 1071 */ static uint16_t inet_checksum(void *data, int len, uint16_t prevsum) { - uint16_t *p = data; + uint16_t word; uint32_t checksum = prevsum ^ 0xFFFF; while(len >= 2) { - checksum += *p++; + memcpy(&word, data, sizeof(word)); + checksum += word; + data += 2; len -= 2; } if(len) { - checksum += *(uint8_t *)p; + checksum += *(uint8_t *)data; } while(checksum >> 16) {