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