Skip to content

Commit

Permalink
netdev-linux: Fix unaligned access to rpl_rtnl_link_stats64.
Browse files Browse the repository at this point in the history
Compilers are allowed to make alignment assumptions based on the
pointer type passed to memcpy().  We have to cast before using it
to avoid misaligned reads:

  lib/netdev-linux.c:6738:41: runtime error: load of misaligned address
    0x51b000008db4 for type 'const struct rpl_rtnl_link_stats64 *',
    which requires 8 byte alignment
  0x51b000008db4: note: pointer points here
  cc 00 17 00 01 00 00 00  00 00 00 00 01 00 00 00
              ^
   0 0xad2d8 in get_stats_via_netlink lib/netdev-linux.c:6738:17
   1 0x9dcce in netdev_linux_get_stats lib/netdev-linux.c:2293:13
   2 0xee5b8 in netdev_get_stats lib/netdev.c:1722:16
   3 0xc07ad in iface_refresh_stats vswitchd/bridge.c:2795:5
   4 0xbf4fc in iface_create vswitchd/bridge.c:2274:5
   5 0xbf4fc in bridge_add_ports__ vswitchd/bridge.c:1225:21
   6 0x989fc in bridge_add_ports vswitchd/bridge.c:1236:5
   7 0x989fc in bridge_reconfigure vswitchd/bridge.c:952:9
   8 0x9102a in bridge_run vswitchd/bridge.c:3439:9
   9 0xc8976 in main vswitchd/ovs-vswitchd.c:137:9
  10 0x2a1c9 in __libc_start_call_main
  11 0x2a28a in __libc_start_main
  12 0xb3ff4 in _start (vswitchd/ovs-vswitchd+0x734ff4)

Reported by Clang 18 with UBsan on Ubuntu 24.04.

Casting the original 'void *' pointer returned from nl_attr_get() call
to 'struct rpl_rtnl_link_stats64 *' also technically constitutes an
undefined behavior, since the resulting pointer is not correctly
aligned for the referenced type, but compilers do not insist on that
today.

Fixes: c8c49a9 ("netdev-linux: Properly access 32-bit aligned rtnl_link_stats64 structs.")
Reviewed-by: Simon Horman <horms@kernel.org>
Acked-by: Dumitru Ceara <dceara@redhat.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
  • Loading branch information
igsilya committed Aug 14, 2024
1 parent 8d3cd41 commit ea2bd0d
Showing 1 changed file with 2 additions and 1 deletion.
3 changes: 2 additions & 1 deletion lib/netdev-linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -6735,7 +6735,8 @@ get_stats_via_netlink(const struct netdev *netdev_, struct netdev_stats *stats)
struct rtnl_link_stats64 aligned_lstats;

if (!IS_PTR_ALIGNED(lstats)) {
memcpy(&aligned_lstats, lstats, sizeof aligned_lstats);
memcpy(&aligned_lstats, (void *) lstats,
sizeof aligned_lstats);
lstats = &aligned_lstats;
}
netdev_stats_from_rtnl_link_stats64(stats, lstats);
Expand Down

0 comments on commit ea2bd0d

Please sign in to comment.