All of lore.kernel.org
 help / color / mirror / Atom feed
From: Antoine Tenart <atenart@kernel.org>
To: davem@davemloft.net, kuba@kernel.org
Cc: Antoine Tenart <atenart@kernel.org>,
	alexander.duyck@gmail.com, netdev@vger.kernel.org
Subject: [PATCH net v2] net: avoid registering new queue objects after device unregistration
Date: Mon, 22 Nov 2021 17:20:07 +0100	[thread overview]
Message-ID: <20211122162007.303623-1-atenart@kernel.org> (raw)

netdev_queue_update_kobjects can be called after device unregistration
started (and device_del was called) resulting in two issues: possible
registration of new queue kobjects (leading to the following trace) and
providing a wrong 'old_queue' number (because real_num_tx_queues is not
updated in the unregistration path).

  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

The fix for both is to only allow unregistering queue kobjects after a
net device started its unregistration and to ensure we know the current
Tx queue numbers (we update dev->real_num_tx_queues before returning).
This relies on the fact that dev->real_num_tx_queues is used for
'old_num' expect when firstly allocating queues.

(Rx queues are not affected as net_rx_queue_update_kobjects can't be
called after a net device started its unregistration).

Fixes: 5c56580b74e5 ("net: Adjust TX queue kobjects if number of queues changes during unregister")
Signed-off-by: Antoine Tenart <atenart@kernel.org>
---

Since v1:
  - Rebased on latest net tree.

David asked in v1 to rename queue functions in net-sysfs[1]. I do have a
patch to prefix all Rx queue functions with net_rx_queue_ and all Tx
ones with net_tx_queue_ in net-sysfs. However this could be confusing as
for historical reasons 'netdev_queue' was always used for Tx queues and
'(net(dev)_)rx_queue' for Rx ones, including 'struct netdev_queue' and
'struct netdev_rx_queue.

- Only renaming the functions in net-sysfs can be a little confusing
  with key structures not following the same scheme.

- But renaming 'struct netdev_queue' is really invasive (380+
  occurrences all over the kernel).

WDYT?

(Anyway such a patch would target net-next while this one is a fix for
net).

Thanks!

[1] https://lore.kernel.org/all/20211026133822.949135-1-atenart@kernel.org/T/#mb0ed3e8366d92df21c35b95cecb2a7e497d25544

 net/core/net-sysfs.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 9c01c642cf9e..0d9777484576 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -1706,6 +1706,12 @@ netdev_queue_update_kobjects(struct net_device *dev, int old_num, int new_num)
 	int i;
 	int error = 0;
 
+	/* When unregistering a net device we can't register new kobjects, as
+	 * this would result in an UaF of the device's kobj.
+	 */
+	if (dev->reg_state == NETREG_UNREGISTERING && new_num > old_num)
+		return -EINVAL;
+
 	for (i = old_num; i < new_num; i++) {
 		error = netdev_queue_add_kobject(dev, i);
 		if (error) {
@@ -1725,6 +1731,7 @@ netdev_queue_update_kobjects(struct net_device *dev, int old_num, int new_num)
 		kobject_put(&queue->kobj);
 	}
 
+	dev->real_num_tx_queues = new_num;
 	return error;
 #else
 	return 0;
-- 
2.33.1


             reply	other threads:[~2021-11-22 16:20 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-22 16:20 Antoine Tenart [this message]
2021-11-22 16:31 ` [PATCH net v2] net: avoid registering new queue objects after device unregistration Jakub Kicinski
2021-11-22 16:56   ` Antoine Tenart
2021-11-22 19:37     ` Jakub Kicinski
2021-11-23 11:18       ` Antoine Tenart

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211122162007.303623-1-atenart@kernel.org \
    --to=atenart@kernel.org \
    --cc=alexander.duyck@gmail.com \
    --cc=davem@davemloft.net \
    --cc=kuba@kernel.org \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.