From: Jiri Pirko <jpirko@redhat.com> Date: Wed, 12 May 2010 20:30:15 -0400 Subject: [net] arp_tables: fix unaligned accesses Message-id: <20100512203014.GJ2930@psychotron.redhat.com> Patchwork-id: 25035 O-Subject: [RHEL5.6 patch] BZ582268 net: [NETFILTER] arp_tables: Fix unaligned accesses. Bugzilla: 582268 RH-Acked-by: David S. Miller <davem@redhat.com> RH-Acked-by: Amerigo Wang <amwang@redhat.com> BZ582268 https://bugzilla.redhat.com/show_bug.cgi?id=582268 Description: There are two device string comparison loops in arp_packet_match(). The first one goes byte-by-byte but the second one tries to be clever and cast the string to a long and compare by longs. The device name strings in the arp table entries are not guarenteed to be aligned enough to make this value, so just use byte-by-byte for both cases. Upstream: http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=49688c843101ba6275756505e81af45ef50f87d7 Brew: https://brewweb.devel.redhat.com/taskinfo?taskID=2440421 Tested on x86_64. Works as expected. Jirka Signed-off-by: Jiri Pirko <jpirko@redhat.com> Signed-off-by: Jarod Wilson <jarod@redhat.com> diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 1807b66..c2bd5c2 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -168,13 +168,9 @@ static inline int arp_packet_match(const struct arphdr *arphdr, return 0; } - for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) { - unsigned long odev; - memcpy(&odev, outdev + i*sizeof(unsigned long), - sizeof(unsigned long)); - ret |= (odev - ^ ((const unsigned long *)arpinfo->outiface)[i]) - & ((const unsigned long *)arpinfo->outiface_mask)[i]; + for (i = 0, ret = 0; i < IFNAMSIZ; i++) { + ret |= (outdev[i] ^ arpinfo->outiface[i]) + & arpinfo->outiface_mask[i]; } if (FWINV(ret != 0, ARPT_INV_VIA_OUT)) {