/* * Minimal reproducer for https://bugs.gentoo.org/697672 * * $ gcc dhcp.c -o dhcp -O2 && ./dhcp * packet sum: 0x011f5b * $ gcc dhcp.c -o dhcp -O2 -fno-strict-aliasing && ./dhcp * packet sum: 0x005555 */ #include #include #include struct foo { uint32_t ip_src; uint32_t ip_dst; // not really needed to reproduce bug. elides a warning }; // Trimmed-down version of dhcpcd-8.1.0:dhcp.c:dhcp_readbpf() function. // Without top-level loop. uint32_t do_sum(const void * packet) __attribute__((noinline)); uint32_t do_sum(const void * packet) { const struct foo *ip = packet; // interpret network packet as a struct // creaft a new packet based on a subset of fields for original packet const struct foo pseudo_ip = { // -fno-strict-aliasing affects ths line .ip_src = ip->ip_src, }; // and compute checksum based on uint16_t const void *data = &pseudo_ip; size_t len = sizeof (pseudo_ip); const uint16_t *word = data; uint32_t sum = 0; for (; len > 1; len -= sizeof(*word)) sum += *word++; return sum; } int main(void) { printf("packet sum: %#08x\n", do_sum("\x11\x11\x44\x44\x22\x22\x11\x11")); }