diff options
author | Jan Engelhardt <jengelh@medozas.de> | 2010-03-27 19:35:50 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-03-27 19:35:50 -0400 |
commit | 14a4b42bd6082b4ce3b94bad00cd367707cc1e97 (patch) | |
tree | 68ee8aa13ab92d07434edbed09c64f4ecf2e7df6 | |
parent | 8544b9f7371ec6a7a5c0f8701ddde9e98f52a37e (diff) |
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>
-rw-r--r-- | net/core/rtnetlink.c | 62 |
1 files changed, 31 insertions, 31 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index ffc6cf3495ac..ed0766f0181a 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -602,36 +602,38 @@ static void copy_rtnl_link_stats(struct rtnl_link_stats *a, | |||
602 | a->tx_compressed = b->tx_compressed; | 602 | a->tx_compressed = b->tx_compressed; |
603 | } | 603 | } |
604 | 604 | ||
605 | static void copy_rtnl_link_stats64(struct rtnl_link_stats64 *a, | 605 | static void copy_rtnl_link_stats64(void *v, const struct net_device_stats *b) |
606 | const struct net_device_stats *b) | ||
607 | { | 606 | { |
608 | a->rx_packets = b->rx_packets; | 607 | struct rtnl_link_stats64 a; |
609 | a->tx_packets = b->tx_packets; | 608 | |
610 | a->rx_bytes = b->rx_bytes; | 609 | a.rx_packets = b->rx_packets; |
611 | a->tx_bytes = b->tx_bytes; | 610 | a.tx_packets = b->tx_packets; |
612 | a->rx_errors = b->rx_errors; | 611 | a.rx_bytes = b->rx_bytes; |
613 | a->tx_errors = b->tx_errors; | 612 | a.tx_bytes = b->tx_bytes; |
614 | a->rx_dropped = b->rx_dropped; | 613 | a.rx_errors = b->rx_errors; |
615 | a->tx_dropped = b->tx_dropped; | 614 | a.tx_errors = b->tx_errors; |
616 | 615 | a.rx_dropped = b->rx_dropped; | |
617 | a->multicast = b->multicast; | 616 | a.tx_dropped = b->tx_dropped; |
618 | a->collisions = b->collisions; | 617 | |
619 | 618 | a.multicast = b->multicast; | |
620 | a->rx_length_errors = b->rx_length_errors; | 619 | a.collisions = b->collisions; |
621 | a->rx_over_errors = b->rx_over_errors; | 620 | |
622 | a->rx_crc_errors = b->rx_crc_errors; | 621 | a.rx_length_errors = b->rx_length_errors; |
623 | a->rx_frame_errors = b->rx_frame_errors; | 622 | a.rx_over_errors = b->rx_over_errors; |
624 | a->rx_fifo_errors = b->rx_fifo_errors; | 623 | a.rx_crc_errors = b->rx_crc_errors; |
625 | a->rx_missed_errors = b->rx_missed_errors; | 624 | a.rx_frame_errors = b->rx_frame_errors; |
626 | 625 | a.rx_fifo_errors = b->rx_fifo_errors; | |
627 | a->tx_aborted_errors = b->tx_aborted_errors; | 626 | a.rx_missed_errors = b->rx_missed_errors; |
628 | a->tx_carrier_errors = b->tx_carrier_errors; | 627 | |
629 | a->tx_fifo_errors = b->tx_fifo_errors; | 628 | a.tx_aborted_errors = b->tx_aborted_errors; |
630 | a->tx_heartbeat_errors = b->tx_heartbeat_errors; | 629 | a.tx_carrier_errors = b->tx_carrier_errors; |
631 | a->tx_window_errors = b->tx_window_errors; | 630 | a.tx_fifo_errors = b->tx_fifo_errors; |
632 | 631 | a.tx_heartbeat_errors = b->tx_heartbeat_errors; | |
633 | a->rx_compressed = b->rx_compressed; | 632 | a.tx_window_errors = b->tx_window_errors; |
634 | a->tx_compressed = b->tx_compressed; | 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 | static inline int rtnl_vfinfo_size(const struct net_device *dev) | 639 | static inline int rtnl_vfinfo_size(const struct net_device *dev) |
@@ -734,8 +736,6 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | |||
734 | sizeof(struct rtnl_link_stats64)); | 736 | sizeof(struct rtnl_link_stats64)); |
735 | if (attr == NULL) | 737 | if (attr == NULL) |
736 | goto nla_put_failure; | 738 | goto nla_put_failure; |
737 | |||
738 | stats = dev_get_stats(dev); | ||
739 | copy_rtnl_link_stats64(nla_data(attr), stats); | 739 | copy_rtnl_link_stats64(nla_data(attr), stats); |
740 | 740 | ||
741 | if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent) { | 741 | if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent) { |