Date: Fri, 6 Jun 2008 10:25:37 +0200 From: Marc =?iso-8859-1?q?L=F6rner?= <marc.loerner@hob.de> To: Peter Jeremy <peterjeremy@optushome.com.au> Cc: freebsd-net@freebsd.org Subject: Re: Probable Bug in tcp.h Message-ID: <200806061025.37856.marc.loerner@hob.de> In-Reply-To: <20080606075210.GD67629@server.vk2pj.dyndns.org> References: <200806051712.47048.marc.loerner@hob.de> <200806060930.28527.marc.loerner@hob.de> <20080606075210.GD67629@server.vk2pj.dyndns.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Friday 06 June 2008 09:52, Peter Jeremy wrote:
> On 2008-Jun-06 09:30:28 +0200, Marc Lörner <marc.loerner@hob.de> wrote:
> >th_x2 and th_off are created as a bitfield. But C-Standard says that
> >bitfields are accessed as integers => 4-bytes
> >
> >On itanium integers are read with ld4-command but the address of
> >th_x2/th_off may not be aligned to 4-bytes => we get an unaligned
> >reference fault.
>
> If the C compiler chooses to implement bitfields as a subset of a
> 32-bit integers, it is up to it to load an aligned 32-bit integer
> and shift/mask the result appropriately to extract the fields.
>
> In this particular case, th_x2/th_off are immediately preceeded by
> a tcp_seq (u_int32_t) field and so will have 32-bit alignment. Note
> that the presence of 32-bit fields in the definition for struct tcphdr
> means that the struct must be aligned to at least 32 bits.
>
> >If we'd change to 1 byte-accesses => I won't get any misaligned faults
> >anymore.
>
> I gather from this comment that you have some code using struct tcphdr
> that is getting alignment errors. struct tcphdr is extensively used
> in the TCP stack within the kernel so it's likely that any layout or
> alignment problem with it would show up there. I suspect you are
> dereferencing a mis-aligned struct tcphdr.
The funny thing is that the dereferencing occurs in
"/usr/src/sys/netinet/tcp_input.c" in function tcp_input in line 550:
/*
* Check that TCP offset makes sense,
* pull out TCP options and adjust length. XXX
*/
off = th->th_off << 2; <----- here
if (off < sizeof (struct tcphdr) || off > tlen) {
tcpstat.tcps_rcvbadoff++;
goto drop;
}
So the misalignment may probably lie in TCP stack?
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200806061025.37856.marc.loerner>
