Probable Bug in tcp.h
Marc Lörner
marc.loerner at hob.de
Fri Jun 6 08:25:58 UTC 2008
On Friday 06 June 2008 09:52, Peter Jeremy wrote:
> On 2008-Jun-06 09:30:28 +0200, Marc Lörner <marc.loerner at 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?
More information about the freebsd-net
mailing list