From 84d213f7c56f87b3f300e8213a4fd8a658fc5e82 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Sat, 8 Oct 2016 14:39:19 +0200 Subject: [PATCH] platform: avoid unaligned access to link stats on 64bit architectures The undefined behavior sanitizer complains with: platform/nm-linux-platform.c:1482:31: runtime error: member access within misaligned address 0x61a000016fac for type 'struct rtnl_link_stats64', which requires 8 byte alignment 0x61a000016fac: note: pointer points here bc 00 17 00 bf 05 00 00 00 00 00 00 bf 05 00 00 00 00 00 00 b5 68 02 00 00 00 00 00 b5 68 02 00 ^ platform/nm-linux-platform.c:1483:29: runtime error: member access within misaligned address 0x61a000016fac for type 'struct rtnl_link_stats64', which requires 8 byte alignment 0x61a000016fac: note: pointer points here bc 00 17 00 bf 05 00 00 00 00 00 00 bf 05 00 00 00 00 00 00 b5 68 02 00 00 00 00 00 b5 68 02 00 ^ platform/nm-linux-platform.c:1484:31: runtime error: member access within misaligned address 0x61a000016fac for type 'struct rtnl_link_stats64', which requires 8 byte alignment 0x61a000016fac: note: pointer points here bc 00 17 00 bf 05 00 00 00 00 00 00 bf 05 00 00 00 00 00 00 b5 68 02 00 00 00 00 00 b5 68 02 00 ^ platform/nm-linux-platform.c:1485:29: runtime error: member access within misaligned address 0x61a000016fac for type 'struct rtnl_link_stats64', which requires 8 byte alignment 0x61a000016fac: note: pointer points here bc 00 17 00 bf 05 00 00 00 00 00 00 bf 05 00 00 00 00 00 00 b5 68 02 00 00 00 00 00 b5 68 02 00 ^ That's because the pointer returned by nla_data() is only 32bit-aligned and using it to access structure members can cause issues on some 64bit architectures. Use the unaligned_read_ne64() macro to access the structure members. https://bugzilla.gnome.org/show_bug.cgi?id=772605 (cherry picked from commit 89bcf50f617193e88d69992ed3f9ba73decdffe7) --- src/platform/nm-linux-platform.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index ad07078f87..d6f111081c 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -49,6 +49,7 @@ #include "nm-platform-utils.h" #include "wifi/wifi-utils.h" #include "wifi/wifi-utils-wext.h" +#include "nm-utils/unaligned.h" #define offset_plus_sizeof(t,m) (offsetof (t,m) + sizeof (((t *) NULL)->m)) @@ -1472,12 +1473,18 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr } if (tb[IFLA_STATS64]) { - struct rtnl_link_stats64 *stats = nla_data (tb[IFLA_STATS64]); + /* tb[IFLA_STATS64] is only guaranteed to be 32bit-aligned, + * so in general we can't access the rtnl_link_stats64 struct + * members directly on 64bit architectures. */ + char *stats = nla_data (tb[IFLA_STATS64]); - obj->link.rx_packets = stats->rx_packets; - obj->link.rx_bytes = stats->rx_bytes; - obj->link.tx_packets = stats->tx_packets; - obj->link.tx_bytes = stats->tx_bytes; +#define READ_STAT64(member) \ + unaligned_read_ne64 (stats + offsetof (struct rtnl_link_stats64, member)) + + obj->link.rx_packets = READ_STAT64 (rx_packets); + obj->link.rx_bytes = READ_STAT64 (rx_bytes); + obj->link.tx_packets = READ_STAT64 (tx_packets); + obj->link.tx_bytes = READ_STAT64 (tx_bytes); } obj->link.n_ifi_flags = ifi->ifi_flags;