diff mbox series

[ovs-dev,v6,6/7] netdev-linux: Properly access 32-bit aligned rtnl_link_stats64 structs.

Message ID 20220411113856.20007.30153.stgit@dceara.remote.csb
State Accepted
Commit c8c49a9db9f20e8b5115e9ef7924e702ee70f4c3
Headers show
Series Fix UndefinedBehaviorSanitizer reported issues and enable it in CI. | expand

Checks

Context Check Description
ovsrobot/apply-robot success apply and check: success
ovsrobot/intel-ovs-compilation success test: success
ovsrobot/github-robot-_Build_and_Test success github build: passed

Commit Message

Dumitru Ceara April 11, 2022, 11:38 a.m. UTC
Detected by UB Sanitizer when running system tests:
  lib/netdev-linux.c:6250:26: runtime error: member access within misaligned address 0x00000229a204 for type 'const struct rpl_rtnl_link_stats64', which requires 8 byte alignment
  0x00000229a204: note: pointer points here
    c4 00 17 00 01 00 00 00  00 00 00 00 01 00 00 00  00 00 00 00 6e 00 00 00  00 00 00 00 6e 00 00 00
                ^
      #0 0x89f10e in netdev_stats_from_rtnl_link_stats64 lib/netdev-linux.c:6250
      #1 0x89f10e in get_stats_via_netlink lib/netdev-linux.c:6298
      #2 0x8a039a in netdev_linux_get_stats lib/netdev-linux.c:2227
      #3 0x68e149 in netdev_get_stats lib/netdev.c:1599
      #4 0x407b21 in iface_refresh_stats vswitchd/bridge.c:2687
      #5 0x419eb6 in iface_create vswitchd/bridge.c:2134
      #6 0x419eb6 in bridge_add_ports__ vswitchd/bridge.c:1170
      #7 0x41f71c in bridge_add_ports vswitchd/bridge.c:1181
      #8 0x41f71c in bridge_reconfigure vswitchd/bridge.c:898
      #9 0x429f59 in bridge_run vswitchd/bridge.c:3331
      #10 0x430af3 in main vswitchd/ovs-vswitchd.c:129
      #11 0x7fbdfd43eb74 in __libc_start_main (/lib64/libc.so.6+0x27b74)
      #12 0x4072fd in _start (/root/ovs/vswitchd/ovs-vswitchd+0x4072fd)

Signed-off-by: Dumitru Ceara <dceara@redhat.com>
---
 include/openvswitch/util.h |    3 +++
 lib/netdev-linux.c         |    9 ++++++++-
 2 files changed, 11 insertions(+), 1 deletion(-)

Comments

Aaron Conole April 11, 2022, 1:44 p.m. UTC | #1
Dumitru Ceara <dceara@redhat.com> writes:

> Detected by UB Sanitizer when running system tests:
>   lib/netdev-linux.c:6250:26: runtime error: member access within misaligned address 0x00000229a204 for type 'const struct rpl_rtnl_link_stats64', which requires 8 byte alignment
>   0x00000229a204: note: pointer points here
>     c4 00 17 00 01 00 00 00  00 00 00 00 01 00 00 00  00 00 00 00 6e 00 00 00  00 00 00 00 6e 00 00 00
>                 ^
>       #0 0x89f10e in netdev_stats_from_rtnl_link_stats64 lib/netdev-linux.c:6250
>       #1 0x89f10e in get_stats_via_netlink lib/netdev-linux.c:6298
>       #2 0x8a039a in netdev_linux_get_stats lib/netdev-linux.c:2227
>       #3 0x68e149 in netdev_get_stats lib/netdev.c:1599
>       #4 0x407b21 in iface_refresh_stats vswitchd/bridge.c:2687
>       #5 0x419eb6 in iface_create vswitchd/bridge.c:2134
>       #6 0x419eb6 in bridge_add_ports__ vswitchd/bridge.c:1170
>       #7 0x41f71c in bridge_add_ports vswitchd/bridge.c:1181
>       #8 0x41f71c in bridge_reconfigure vswitchd/bridge.c:898
>       #9 0x429f59 in bridge_run vswitchd/bridge.c:3331
>       #10 0x430af3 in main vswitchd/ovs-vswitchd.c:129
>       #11 0x7fbdfd43eb74 in __libc_start_main (/lib64/libc.so.6+0x27b74)
>       #12 0x4072fd in _start (/root/ovs/vswitchd/ovs-vswitchd+0x4072fd)
>
> Signed-off-by: Dumitru Ceara <dceara@redhat.com>
> ---

Acked-by: Aaron Conole <aconole@redhat.com>
diff mbox series

Patch

diff --git a/include/openvswitch/util.h b/include/openvswitch/util.h
index 96f600160b23..8e6c46a85f13 100644
--- a/include/openvswitch/util.h
+++ b/include/openvswitch/util.h
@@ -429,6 +429,9 @@  is_pow2(uintmax_t x)
  * segfault, so it is important to be aware of correct alignment. */
 #define ALIGNED_CAST(TYPE, ATTR) ((TYPE) (void *) (ATTR))
 
+#define IS_PTR_ALIGNED(OBJ) \
+    (!(OBJ) || (uintptr_t) (OBJ) % __alignof__(OVS_TYPEOF(OBJ)) == 0)
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c
index 9d125029de01..2766b3f2bf67 100644
--- a/lib/netdev-linux.c
+++ b/lib/netdev-linux.c
@@ -6295,7 +6295,14 @@  get_stats_via_netlink(const struct netdev *netdev_, struct netdev_stats *stats)
     if (ofpbuf_try_pull(reply, NLMSG_HDRLEN + sizeof(struct ifinfomsg))) {
         const struct nlattr *a = nl_attr_find(reply, 0, IFLA_STATS64);
         if (a && nl_attr_get_size(a) >= sizeof(struct rtnl_link_stats64)) {
-            netdev_stats_from_rtnl_link_stats64(stats, nl_attr_get(a));
+            const struct rtnl_link_stats64 *lstats = nl_attr_get(a);
+            struct rtnl_link_stats64 aligned_lstats;
+
+            if (!IS_PTR_ALIGNED(lstats)) {
+                memcpy(&aligned_lstats, lstats, sizeof aligned_lstats);
+                lstats = &aligned_lstats;
+            }
+            netdev_stats_from_rtnl_link_stats64(stats, lstats);
             error = 0;
         } else {
             a = nl_attr_find(reply, 0, IFLA_STATS);