From 24f74cb52e4020703f47cd35769e08dd54098a1c Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Fri, 14 Oct 2016 15:33:43 -0700 Subject: [PATCH] Fix alignment issue of ones_complement_checksum The ones_complement_checksum function assumes that the bytes passed into it are aligned on 16 bit boundaries. When using gcc (GCC) 6.2.1 20160916 (Red Hat 6.2.1-2) with -O2, this does not seem to hold true anymore; assuming 16 bit alignment will lead to accesses to uninitialized memory and wrong checksums. This commit adds a minimally invasive change that does not assume alignment anymore. This might have a small performance impact for every single packet we process. This error occured reproducibly when called from icmp6_checksum. --- src/net_util.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/net_util.cc b/src/net_util.cc index 677a869cc5..0f1493e190 100644 --- a/src/net_util.cc +++ b/src/net_util.cc @@ -18,13 +18,16 @@ // Returns the ones-complement checksum of a chunk of b short-aligned bytes. int ones_complement_checksum(const void* p, int b, uint32 sum) { - const u_short* sp = (u_short*) p; // better be aligned! + const unsigned char* sp = (unsigned char*) p; b /= 2; // convert to count of short's /* No need for endian conversions. */ while ( --b >= 0 ) - sum += *sp++; + { + sum += *sp + ( *(sp+1) << 8 ); + sp += 2; + } while ( sum > 0xffff ) sum = (sum & 0xffff) + (sum >> 16);