Subject: Re: alignment crash in v6 ipfilter when receiving on gif
To: Pavel Cahyna <pavel@netbsd.org>
From: Greg Troxel <gdt@ir.bbn.com>
List: port-sparc64
Date: 07/17/2007 19:51:47
Pavel Cahyna <pavel@NetBSD.org> writes:

> On Tue, Jul 17, 2007 at 11:26:36AM -0400, der Mouse wrote:
>> > +			/*
>> > +			 * XXX cast to i6addr_t is unsafe because it
>> > +			 * presumes void * alignment which may not be
>> > +			 * true, but IP6_NEQ casts to u_32_t.
>> > +			 */
>> 
>> While this is fine for sparc64, and I think is OK for all architectures
>> NetBSD supports, it is not correct C; converting to i6addr_t * may lose
>> information, which of course cannot be recovered by casting back to
>> some other type.
>> 
>> Why cast to i6addr_t * at all, when IP6_NEQ casts immediately anyway?
>
> How is it fine for sparc64? Converting to i6addr_t * tells the compiler
> that it is possible to assume 64-bit alignment, which is wrong in this
> situation. Or am I missing something? I am surprised that this works.

It's only semi-ok because the pointer that's cast to i6addr_t * is only
used by
  cast to a 32-bit pointer
  use that to fetch 32-bit words

Or rather because gcc in that case doesn't use ldx.  I suppose it could
propagate the "is 64-bit aligned" property throught the 32-bit pointer
cast and then use ldx, but fortunately it's not that smart.

But really I was trying to make minimal changes, and let Darren figure
out the long-term fix.  This is in ipfilter, which has to build and work
on lots of systems and architectures, and I'm not familiar with the
others, so whacking in a NetBSD-appropriate fix without considering the
others seems unwise.

There's a deeper problem, which is that I'm not sure our network code
guarantees any alignment at all of packets in mbufs.  mbuf(9) doesn't
address alignment.  But it seems on sparc64 everything is naturally
32-bit aligned, and 64-bit except for gif, or this would have blown up
on other interfaces.