| From dde91ccfa25fd58f64c397d91b81a4b393100ffa Mon Sep 17 00:00:00 2001 |
| From: Antoine Tenart <atenart@kernel.org> |
| Date: Fri, 3 Dec 2021 11:13:18 +0100 |
| Subject: ethtool: do not perform operations on net devices being unregistered |
| |
| From: Antoine Tenart <atenart@kernel.org> |
| |
| commit dde91ccfa25fd58f64c397d91b81a4b393100ffa upstream. |
| |
| There is a short period between a net device starts to be unregistered |
| and when it is actually gone. In that time frame ethtool operations |
| could still be performed, which might end up in unwanted or undefined |
| behaviours[1]. |
| |
| Do not allow ethtool operations after a net device starts its |
| unregistration. This patch targets the netlink part as the ioctl one |
| isn't affected: the reference to the net device is taken and the |
| operation is executed within an rtnl lock section and the net device |
| won't be found after unregister. |
| |
| [1] For example adding Tx queues after unregister ends up in NULL |
| pointer exceptions and UaFs, such as: |
| |
| BUG: KASAN: use-after-free in kobject_get+0x14/0x90 |
| Read of size 1 at addr ffff88801961248c by task ethtool/755 |
| |
| CPU: 0 PID: 755 Comm: ethtool Not tainted 5.15.0-rc6+ #778 |
| Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-4.fc34 04/014 |
| Call Trace: |
| dump_stack_lvl+0x57/0x72 |
| print_address_description.constprop.0+0x1f/0x140 |
| kasan_report.cold+0x7f/0x11b |
| kobject_get+0x14/0x90 |
| kobject_add_internal+0x3d1/0x450 |
| kobject_init_and_add+0xba/0xf0 |
| netdev_queue_update_kobjects+0xcf/0x200 |
| netif_set_real_num_tx_queues+0xb4/0x310 |
| veth_set_channels+0x1c3/0x550 |
| ethnl_set_channels+0x524/0x610 |
| |
| Fixes: 041b1c5d4a53 ("ethtool: helper functions for netlink interface") |
| Suggested-by: Jakub Kicinski <kuba@kernel.org> |
| Signed-off-by: Antoine Tenart <atenart@kernel.org> |
| Link: https://lore.kernel.org/r/20211203101318.435618-1-atenart@kernel.org |
| Signed-off-by: Jakub Kicinski <kuba@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| net/ethtool/netlink.h | 3 +++ |
| 1 file changed, 3 insertions(+) |
| |
| --- a/net/ethtool/netlink.h |
| +++ b/net/ethtool/netlink.h |
| @@ -249,6 +249,9 @@ struct ethnl_reply_data { |
| |
| static inline int ethnl_ops_begin(struct net_device *dev) |
| { |
| + if (dev && dev->reg_state == NETREG_UNREGISTERING) |
| + return -ENODEV; |
| + |
| if (dev && dev->ethtool_ops->begin) |
| return dev->ethtool_ops->begin(dev); |
| else |