Skip site navigation (1)Skip section navigation (2)
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>