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
This commit is contained in:
Beniamino Galvani
2016-10-08 14:39:19 +02:00
parent 22cc119da5
commit 89bcf50f61

View File

@@ -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;