Commit 14a4b42bd6082b4ce3b94bad00cd367707cc1e97

Authored by Jan Engelhardt
Committed by David S. Miller
1 parent 8544b9f737

net: fix unaligned access in IFLA_STATS64

Tony Luck observes that the original IFLA_STATS64 submission causes
unaligned accesses. This is because nla_data() returns a pointer to a
memory region that is only aligned to 32 bits. Do some memcpying to
workaround this.

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 1 changed file with 31 additions and 31 deletions Side-by-side Diff

net/core/rtnetlink.c
... ... @@ -602,36 +602,38 @@
602 602 a->tx_compressed = b->tx_compressed;
603 603 }
604 604  
605   -static void copy_rtnl_link_stats64(struct rtnl_link_stats64 *a,
606   - const struct net_device_stats *b)
  605 +static void copy_rtnl_link_stats64(void *v, const struct net_device_stats *b)
607 606 {
608   - a->rx_packets = b->rx_packets;
609   - a->tx_packets = b->tx_packets;
610   - a->rx_bytes = b->rx_bytes;
611   - a->tx_bytes = b->tx_bytes;
612   - a->rx_errors = b->rx_errors;
613   - a->tx_errors = b->tx_errors;
614   - a->rx_dropped = b->rx_dropped;
615   - a->tx_dropped = b->tx_dropped;
  607 + struct rtnl_link_stats64 a;
616 608  
617   - a->multicast = b->multicast;
618   - a->collisions = b->collisions;
  609 + a.rx_packets = b->rx_packets;
  610 + a.tx_packets = b->tx_packets;
  611 + a.rx_bytes = b->rx_bytes;
  612 + a.tx_bytes = b->tx_bytes;
  613 + a.rx_errors = b->rx_errors;
  614 + a.tx_errors = b->tx_errors;
  615 + a.rx_dropped = b->rx_dropped;
  616 + a.tx_dropped = b->tx_dropped;
619 617  
620   - a->rx_length_errors = b->rx_length_errors;
621   - a->rx_over_errors = b->rx_over_errors;
622   - a->rx_crc_errors = b->rx_crc_errors;
623   - a->rx_frame_errors = b->rx_frame_errors;
624   - a->rx_fifo_errors = b->rx_fifo_errors;
625   - a->rx_missed_errors = b->rx_missed_errors;
  618 + a.multicast = b->multicast;
  619 + a.collisions = b->collisions;
626 620  
627   - a->tx_aborted_errors = b->tx_aborted_errors;
628   - a->tx_carrier_errors = b->tx_carrier_errors;
629   - a->tx_fifo_errors = b->tx_fifo_errors;
630   - a->tx_heartbeat_errors = b->tx_heartbeat_errors;
631   - a->tx_window_errors = b->tx_window_errors;
  621 + a.rx_length_errors = b->rx_length_errors;
  622 + a.rx_over_errors = b->rx_over_errors;
  623 + a.rx_crc_errors = b->rx_crc_errors;
  624 + a.rx_frame_errors = b->rx_frame_errors;
  625 + a.rx_fifo_errors = b->rx_fifo_errors;
  626 + a.rx_missed_errors = b->rx_missed_errors;
632 627  
633   - a->rx_compressed = b->rx_compressed;
634   - a->tx_compressed = b->tx_compressed;
  628 + a.tx_aborted_errors = b->tx_aborted_errors;
  629 + a.tx_carrier_errors = b->tx_carrier_errors;
  630 + a.tx_fifo_errors = b->tx_fifo_errors;
  631 + a.tx_heartbeat_errors = b->tx_heartbeat_errors;
  632 + a.tx_window_errors = b->tx_window_errors;
  633 +
  634 + a.rx_compressed = b->rx_compressed;
  635 + a.tx_compressed = b->tx_compressed;
  636 + memcpy(v, &a, sizeof(a));
635 637 }
636 638  
637 639 static inline int rtnl_vfinfo_size(const struct net_device *dev)
... ... @@ -734,8 +736,6 @@
734 736 sizeof(struct rtnl_link_stats64));
735 737 if (attr == NULL)
736 738 goto nla_put_failure;
737   -
738   - stats = dev_get_stats(dev);
739 739 copy_rtnl_link_stats64(nla_data(attr), stats);
740 740  
741 741 if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent) {