problem in if_tap.c

2008-04-14 Thread Marc Lörner
Hello,
I found the following problem in the if_tap-device code in function tapcreate
when used on 64-bit systems:

   TAPDEBUG("tapcreate(%s%d). minor = %#x\n", name, unit, minor(dev));

/* generate fake MAC address: 00 bd xx xx xx unit_no */
macaddr_hi = htons(0x00bd);
bcopy(&macaddr_hi, eaddr, sizeof(short));

>
bcopy(&ticks, &eaddr[2], sizeof(long));
eaddr[5] = (u_char)unit;

/* fill the rest and attach interface */

sizeof(long) is not always 4 on any system (e.g. on ia64 it's 8)
=> bytes are copied from undefined memory  into undefined memory

Regards,
Marc

P.S.: On replies please cc me because I'm not on the list.
___
freebsd-net@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "[EMAIL PROTECTED]"


Unaligned references in /usr/src/sys/netinet6/in6.h

2008-06-03 Thread Marc Lörner
Hello,

within testing on a ia64-platform I spotted unaligned references in the 
macros:
IN6_IS_ADDR_UNSPECIFIED(a), IN6_IS_ADDR_LOOPBACK(a), 
IN6_IS_ADDR_V4COMPAT(a) and IN6_IS_ADDR_V4MAPPED(a)

It's not always true that the s6_addr array is aligned to 4-byte and this 
causes some trouble at least with ia64-platforms.

After changing from u_int32_t to u_int8_t accesses the unalignment faults seem 
to be gone.

Regards,
Marc

P.S.: On replies please CC me because I'm not on the list.
___
freebsd-net@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "[EMAIL PROTECTED]"


Probable Bug in tcp.h

2008-06-05 Thread Marc Lörner
Hello,
I probably found a bug in declaration of "struct tcphdr"!

struct tcphdr {
u_short th_sport;   /* source port */
u_short th_dport;   /* destination port */
tcp_seq th_seq; /* sequence number */
tcp_seq th_ack; /* acknowledgement number */
#if BYTE_ORDER == LITTLE_ENDIAN
u_int   th_x2:4,/* (unused) */  
<---here
th_off:4;   /* data offset */   
<---
#endif
#if BYTE_ORDER == BIG_ENDIAN
u_int   th_off:4,   /* data offset */
th_x2:4;/* (unused) */
#endif
u_char  th_flags;

First of all I have the problam of misalignment of th_off. Because in this way 
always 4 bytes are read and the the bits of th_off are replaced. Then the 4 
bytes are written back. 

But should (th_x and th_off) not only be 1 byte in whole -> only read and 
write 1 byte?

I think if this was changed, my misalignment problems would go away!

I'll appreciate any thoughts on this!

Regards,
Marc

P.S.: Please cc me because I'm not on the list!
___
freebsd-net@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "[EMAIL PROTECTED]"


Re: Probable Bug in tcp.h

2008-06-06 Thread Marc Lörner
On Thursday 05 June 2008 17:56, Rui Paulo wrote:
> On Thu, Jun 05, 2008 at 05:12:47PM +0200, =?ISO-8859-1?Q?Marc_L=F6rner_ 
wrote:
> > Hello,
> > I probably found a bug in declaration of "struct tcphdr"!
> >
> > struct tcphdr {
> > u_short th_sport;   /* source port */
> > u_short th_dport;   /* destination port */
> > tcp_seq th_seq; /* sequence number */
> > tcp_seq th_ack; /* acknowledgement number */
> > #if BYTE_ORDER == LITTLE_ENDIAN
> > u_int   th_x2:4,/* (unused) */  
> > <---here
> > th_off:4;   /* data offset */   
> > <---
> > #endif
> > #if BYTE_ORDER == BIG_ENDIAN
> > u_int   th_off:4,   /* data offset */
> > th_x2:4;/* (unused) */
> > #endif
> > u_char  th_flags;
> >
> > First of all I have the problam of misalignment of th_off. Because in
> > this way always 4 bytes are read and the the bits of th_off are replaced.
> > Then the 4 bytes are written back.
> >
> > But should (th_x and th_off) not only be 1 byte in whole -> only read and
> > write 1 byte?
> >
> > I think if this was changed, my misalignment problems would go away!
>
> I'm not sure what you mean.
>
> Please supply more information, like:
> 1) Are you running on little endian? Or big endian?

I'm on itanium-architecture, therefore I can run big and little endian. But 
for now it is little endian.

> 2) th_x2 + th_off are 1 byte in size. What do you mean?

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 we'd change to 1 byte-accesses => I won't get any misaligned faults 
anymore.


Hope this makes my dilemma a bit clearer,
Marc
___
freebsd-net@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "[EMAIL PROTECTED]"


Re: Probable Bug in tcp.h

2008-06-06 Thread Marc Lörner
On Thursday 05 June 2008 18:09, Bruce M. Simpson wrote:
> Marc Lörner wrote:
> > ..
> > First of all I have the problam of misalignment of th_off. Because in
> > this way always 4 bytes are read and the the bits of th_off are replaced.
> > Then the 4 bytes are written back.
> >
> > But should (th_x and th_off) not only be 1 byte in whole -> only read and
> > write 1 byte?
>
> Which machine architecture are you attempting to compile this code on?
>

ia64/itanium

> On FreeBSD Tier 1 platforms, the access is probably going to come out of
> L2 cache anyway, so the fields in question will be read by a burst cycle.
>

I know! But the problem (on itanium) is that bitfields are always accessed as 
integers => 4-byte access 

But th_x/th_off may not always be aligned to 4-bytes
=> I get an unalignment reference fault

If access of th_x/th_off could be changed to 1-byte => 1-byte aligned
=> my unaligned reference fault would go away

> It is worth noting that NetBSD changed the base type of tcphdr's
> bitfields to uint8_t, however this shuffles the compiler dependency into
> the treatment of the "char" type. Most modern C compilers support
> "unsigned char".

Does this really change the access to 1-byte? 
As in "Programming in C" by Kernighan and Ritchie is stated that bitfields 
must and will always be defined as ints.
___
freebsd-net@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "[EMAIL PROTECTED]"


Re: Probable Bug in tcp.h

2008-06-06 Thread Marc Lörner
On Friday 06 June 2008 09:52, Peter Jeremy wrote:
> On 2008-Jun-06 09:30:28 +0200, Marc Lörner <[EMAIL PROTECTED]> 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?
___
freebsd-net@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "[EMAIL PROTECTED]"


Re: Probable Bug in tcp.h

2008-06-09 Thread Marc Lörner
On Friday 06 June 2008 14:25, Bruce Evans wrote:
> On Fri, 6 Jun 2008, Marc [iso-8859-1] Lörner wrote:
> > On Friday 06 June 2008 09:52, Peter Jeremy wrote:
> >> 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?
>
> Quite likely.  th is normally at offset off0 in ip, where ip is required
> to be 32-bit aligned (see my previous reply).  You can see off0 in a
> stack trace.
>

off0 is 0x14 => no problem with that
but address of ip is 0xe00021c8706e => not correct aligned to 32-bits

Can anyone tell me, where ip is allocated, so I can do a little bit more 
research?

Marc
___
freebsd-net@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "[EMAIL PROTECTED]"