Subject: Re: alignment crash in v6 ipfilter when receiving on gif
To: Martin Husemann <martin@duskware.de>
From: Greg Troxel <gdt@ir.bbn.com>
List: port-sparc64
Date: 07/10/2007 12:47:55
I think Martin is right that i6addr_t must be aligned to 64 bits and
thus the compiler assumes it is after a cast and is correct to coalesce
two 32-bit compares to a 64-bit compare.
I took the patch from Geoff's mail and re-applied it by hand since the
diff was munged by the archives. This is against the current contents
of netbsd-4.
With the patch, I can traceroute from and through my sparc64 router.
Should I commit this to -current and then request a pullup after a week?
The patch applies with only a bit of fuzz/offset, so pretty clearly the
same issue would be present there.
Thanks for the help.
Index: sys/dist/ipf/netinet/fil.c
===================================================================
RCS file: /cvsroot/src/sys/dist/ipf/netinet/fil.c,v
retrieving revision 1.28.2.4
diff -u -p -r1.28.2.4 fil.c
--- sys/dist/ipf/netinet/fil.c 8 Jun 2007 09:20:06 -0000 1.28.2.4
+++ sys/dist/ipf/netinet/fil.c 10 Jul 2007 16:46:17 -0000
@@ -726,6 +726,7 @@ fr_info_t *fin;
if (fin->fin_dlen > 1) {
ip6_t *ip6;
+ struct in6_addr ip6_src;
icmp6 = fin->fin_dp;
@@ -757,8 +758,15 @@ fr_info_t *fin;
* not correct.
*/
ip6 = (ip6_t *)((char *)icmp6 + ICMPERR_ICMPHLEN);
+ /*
+ * There is no guarantee that ip6 is aligned to 64 bits,
+ * and gcc uses 64-bit loads because ip6_t contains
+ * pointers and thus must be 64-bit aligned.
+ */
+ memcpy(&ip6_src, &ip6->ip6_src,
+ sizeof(struct in6_addr));
if (IP6_NEQ(&fin->fin_fi.fi_dst,
- (i6addr_t *)&ip6->ip6_src))
+ &ip6_src))
fin->fin_flx |= FI_BAD;
minicmpsz = ICMP6ERR_IPICMPHLEN - sizeof(ip6_t);