From f1d9e9d52d7751a09a744f3ad83613c6b025c230 Mon Sep 17 00:00:00 2001 From: Bryan Phillippe Date: Wed, 31 Aug 2011 11:11:59 -0700 Subject: [PATCH] 64bit unaligned access This patch fixes an unaligned access for IPv6. On systems with strict alignment requirements, the unaligned access will either result in garbage data or a crash. --- lib/route/link/inet6.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/lib/route/link/inet6.c b/lib/route/link/inet6.c index 399dd4b..5f75342 100644 --- a/lib/route/link/inet6.c +++ b/lib/route/link/inet6.c @@ -71,23 +71,33 @@ static int inet6_parse_protinfo(struct rtnl_link *link, struct nlattr *attr, if (tb[IFLA_INET6_CONF]) nla_memcpy(&i6->i6_conf, tb[IFLA_INET6_CONF], sizeof(i6->i6_conf)); - + + /* + * Due to 32bit data alignment, these addresses must be copied to an + * aligned location prior to access. + */ if (tb[IFLA_INET6_STATS]) { - uint64_t *cnt = nla_data(tb[IFLA_INET6_STATS]); + unsigned char *cnt = nla_data(tb[IFLA_INET6_STATS]); + uint64_t stat; int i; - for (i = 1; i < __IPSTATS_MIB_MAX; i++) + for (i = 1; i < __IPSTATS_MIB_MAX; i++) { + memcpy(&stat, &cnt[i * sizeof(stat)], sizeof(stat)); rtnl_link_set_stat(link, RTNL_LINK_IP6_INPKTS + i - 1, - cnt[i]); + stat); + } } if (tb[IFLA_INET6_ICMP6STATS]) { - uint64_t *cnt = nla_data(tb[IFLA_INET6_ICMP6STATS]); + unsigned char *cnt = nla_data(tb[IFLA_INET6_ICMP6STATS]); + uint64_t stat; int i; - for (i = 1; i < __ICMP6_MIB_MAX; i++) + for (i = 1; i < __ICMP6_MIB_MAX; i++) { + memcpy(&stat, &cnt[i * sizeof(stat)], sizeof(stat)); rtnl_link_set_stat(link, RTNL_LINK_ICMP6_INMSGS + i - 1, - cnt[i]); + stat); + } } return 0;