From: Guus Sliepen Date: Tue, 27 Feb 2018 20:08:57 +0000 (+0100) Subject: Work around a GCC bug that causes inet_checksum() to give wrong results. X-Git-Tag: release-1.1pre16~16 X-Git-Url: https://git.tinc-vpn.org/git/browse?a=commitdiff_plain;h=7c73cb3ace6659df58ec2382b8d47bb521dad886;p=tinc Work around a GCC bug that causes inet_checksum() to give wrong results. Valgrind reports the following bug: ==24877== Conditional jump or move depends on uninitialised value(s) ==24877== at 0x12283E: inet_checksum (route.c:80) ==24877== by 0x12283E: route_ipv6_unreachable (route.c:315) ==24877== by 0x1236AC: route_ipv6 (route.c:751) ==24877== by 0x1236AC: route (route.c:1160) ==24877== by 0x113DE0: receive_tcppacket (net_packet.c:493) ==24877== by 0x1119D4: receive_meta (meta.c:315) ==24877== by 0x113288: handle_meta_connection_data (net.c:287) ==24877== by 0x11A091: handle_meta_io (net_socket.c:491) ==24877== by 0x10FB0C: event_loop (event.c:370) ==24877== by 0x11362E: main_loop (net.c:489) ==24877== by 0x10CACA: main (tincd.c:551) Clearing the variable pseudo in route_ipv6_unreachable removes this error, but the resulting checksum is still bad. If one instead adds a dummy write that depends on checksum, the error goes away and the checksum is correct. --- diff --git a/src/route.c b/src/route.c index a3e92020..4d712795 100644 --- a/src/route.c +++ b/src/route.c @@ -59,6 +59,7 @@ static const size_t opt_size = sizeof(struct nd_opt_hdr); #define MAX(a, b) ((a) > (b) ? (a) : (b)) #endif +volatile int dummy; static timeout_t age_subnets_timeout; /* RFC 1071 */ @@ -80,6 +81,11 @@ static uint16_t inet_checksum(void *data, int len, uint16_t prevsum) { checksum = (checksum & 0xFFFF) + (checksum >> 16); } + // Work around a compiler optimization bug. + if(checksum) { + dummy = 1; + } + return ~checksum; }