Subject: Re: alignment crash in v6 ipfilter when receiving on gif
To: Greg Troxel <gdt@ir.bbn.com>
From: Darren Reed <darrenr@netbsd.org>
List: port-sparc64
Date: 07/18/2007 05:52:19
Greg,
The comment should go in ip_compat.h, not fil.c.
Otherwise, it looks good to go.
Darren
Greg Troxel wrote:
> From: Darren Reed <darrenr@netbsd.org>
>
> I think the correct thing to do is change these:
>
> #define I60(x) (((i6addr_t *)(x))->i6[0])
> [rest trimmed]
>
> to be:
>
> #define I60(x) (((u_32_t *)(x))[0])
>
> I did that and the resulting kernel doesn't crash and traceroute6
> through it works.
>
> Here's a patch against netbsd-4, which also includes a caution about a
> remaining unsafe cast. Shall I apply it to current and request a pullup
> (I've tested on netbsd-4 sparc64 only, and not really tested that there
> are no functional problems), or would you like to handle this?
>
> Index: sys/dist/ipf/netinet/fil.c
> ===================================================================
> RCS file: /cvsroot/src/sys/dist/ipf/netinet/fil.c,v
> retrieving revision 1.28.2.6
> diff -u -p -r1.28.2.6 fil.c
> --- sys/dist/ipf/netinet/fil.c 16 Jul 2007 11:08:45 -0000 1.28.2.6
> +++ sys/dist/ipf/netinet/fil.c 17 Jul 2007 14:39:00 -0000
> @@ -770,6 +770,11 @@ fr_info_t *fin;
> */
> icmp6 = fin->fin_dp;
> ip6 = (ip6_t *)((char *)icmp6 + ICMPERR_ICMPHLEN);
> + /*
> + * 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.
> + */
> if (IP6_NEQ(&fin->fin_fi.fi_dst,
> (i6addr_t *)&ip6->ip6_src))
> fin->fin_flx |= FI_BAD;
> Index: sys/dist/ipf/netinet/ip_fil.h
> ===================================================================
> RCS file: /cvsroot/src/sys/dist/ipf/netinet/ip_fil.h,v
> retrieving revision 1.6.12.4
> diff -u -p -r1.6.12.4 ip_fil.h
> --- sys/dist/ipf/netinet/ip_fil.h 16 Jul 2007 11:05:41 -0000 1.6.12.4
> +++ sys/dist/ipf/netinet/ip_fil.h 17 Jul 2007 14:39:00 -0000
> @@ -158,14 +158,14 @@ typedef union i6addr {
> #define iplookupptr vptr[0]
> #define iplookupfunc lptr[1]
>
> -#define I60(x) (((i6addr_t *)(x))->i6[0])
> -#define I61(x) (((i6addr_t *)(x))->i6[1])
> -#define I62(x) (((i6addr_t *)(x))->i6[2])
> -#define I63(x) (((i6addr_t *)(x))->i6[3])
> -#define HI60(x) ntohl(((i6addr_t *)(x))->i6[0])
> -#define HI61(x) ntohl(((i6addr_t *)(x))->i6[1])
> -#define HI62(x) ntohl(((i6addr_t *)(x))->i6[2])
> -#define HI63(x) ntohl(((i6addr_t *)(x))->i6[3])
> +#define I60(x) (((u_32_t *)(x))[0])
> +#define I61(x) (((u_32_t *)(x))[1])
> +#define I62(x) (((u_32_t *)(x))[2])
> +#define I63(x) (((u_32_t *)(x))[3])
> +#define HI60(x) ntohl(((u_32_t *)(x))[0])
> +#define HI61(x) ntohl(((u_32_t *)(x))[1])
> +#define HI62(x) ntohl(((u_32_t *)(x))[2])
> +#define HI63(x) ntohl(((u_32_t *)(x))[3])
>
> #define IP6_EQ(a,b) ((I63(a) == I63(b)) && (I62(a) == I62(b)) && \
> (I61(a) == I61(b)) && (I60(a) == I60(b)))