Bug#623634: libnet-rawip-perl: miscalculates header checksums

Steinar H. Gunderson sgunderson at bigfoot.com
Thu Apr 21 23:28:29 UTC 2011


Package: libnet-rawip-perl
Version: 0.25-1
Severity: important

Hi,

It seems Net::RawIP, if you run a script using it long enough
(as in millions of generated UDP packets), eventually generates
bogus UDP checksums in the packets it's sending out (tcpdump
freaks out, the end hosts start ignoring them). I took a
look at the source, and it seems the following fragment from
RawIP.xs in the udp_pkt_creat() function is the culprit:

            memcpy(ptr,(u_char*)&piu,20);
            memcpy(ptr+20,SvPV(ip_opts,PL_na),SvCUR(ip_opts));
            memcpy(ptr+20+SvCUR(ip_opts),(u_char*)&piu + 20,8);
            ((struct iphdr*)ptr)->check = in_cksum((unsigned short *)ptr,iplen);
            RETVAL = newSVpv((char*)ptr, sizeof(IUPKT)+SvCUR(ip_opts));

You can't use cast-as-lvalue like this; it is an aliasing
violation, and with newer gcc seemingly something wrong happens
here. The easiest way to fix this is usually by using memcpy
(which has specific exceptions in POSIX from the aliasing rules),
like this:

           unsigned short cksum;
           [...]
           cksum = in_cksum((unsigned short *)ptr,iplen);
           memcpy(&((struct iphdr*)ptr)->check, &cksum, sizeof(cksum));

Adding this fragment seems to have fixed the issue for us;
at least it's running stable for a day or so. Granted, we also
run with noopt nostrip, so it _could_ be something else, but
it really sticks out as a sore thumb.

FWIW, there are similar fragments many other places in the code,
so you should probably fix all of them.

-- System Information:
Debian Release: wheezy/sid
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: amd64 (x86_64)

Kernel: Linux 2.6.37.3 (SMP w/1 CPU core)
Locale: LANG=en_DK.UTF-8, LC_CTYPE=en_DK.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash





More information about the pkg-perl-maintainers mailing list