summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryan Phillippe <bp@darkforest.org>2011-08-31 11:11:59 -0700
committerThomas Graf <tgraf@lsx.localdomain>2011-09-01 08:39:48 +0200
commitf1d9e9d52d7751a09a744f3ad83613c6b025c230 (patch)
tree866de722f2ab18f876acb6b2a3ed357464529288
parent7adaad784f02dc3cab0ad97a284edb0eaf2f0663 (diff)
downloadlibnl-f1d9e9d52d7751a09a744f3ad83613c6b025c230.tar.gz
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.
-rw-r--r--lib/route/link/inet6.c24
1 files 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;