From f3ba50ed3d14749b7c1ef100d2a49ac30d3b3853 Mon Sep 17 00:00:00 2001 From: "Maciej S. Szmigiero" Date: Tue, 16 Apr 2019 15:00:50 +0200 Subject: [PATCH] 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). --- src/route.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) 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) { -- 2.25.1