lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <174265441736.356712.5536182528670424751.stgit@pro.pro>
Date: Sat, 22 Mar 2025 17:40:17 +0300
From: Kirill Tkhai <tkhai@...ru>
To: netdev@...r.kernel.org,
	linux-kernel@...r.kernel.org
Cc: tkhai@...ru
Subject: [PATCH NET-PREV 19/51] bpqether: Provide determined context in __register_netdevice()

In case of caller already owns nd_lock, there is
nesting without underlying that to lockdep.

So we use trylock and __register_netdevice() here.

XXX: after callers of netdevice notifyiers are converted,
we will inherit @edev nd_lock instead.

Signed-off-by: Kirill Tkhai <tkhai@...ru>
---
 drivers/net/hamradio/bpqether.c |   33 +++++++++++++++++++++++++++------
 1 file changed, 27 insertions(+), 6 deletions(-)

diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
index 83a16d10eedb..bf2792f98afe 100644
--- a/drivers/net/hamradio/bpqether.c
+++ b/drivers/net/hamradio/bpqether.c
@@ -480,6 +480,7 @@ static int bpq_new_device(struct net_device *edev)
 {
 	int err;
 	struct net_device *ndev;
+	struct nd_lock *nd_lock;
 	struct bpqdev *bpq;
 
 	ndev = alloc_netdev(sizeof(struct bpqdev), "bpq%d", NET_NAME_UNKNOWN,
@@ -487,7 +488,23 @@ static int bpq_new_device(struct net_device *edev)
 	if (!ndev)
 		return -ENOMEM;
 
-		
+	err = -ENOMEM;
+	nd_lock = alloc_nd_lock();
+	if (!nd_lock)
+		goto err_free;
+
+	/* This is called from netdevice notifier, which is not converted yet.
+	 * The context is unknown: either some nd_lock is locked or not. Since
+	 * @ndev is undependent of @edev (on this stage of convertation we don't
+	 * require that, we will require when we convert unregister_netdev()).
+	 * So, a new nd_lock is used for @ndev for now.
+	 * Q: Why is trylock, despite it can't fail?
+	 * A: Caller may own some other nd_lock, so lockdep will unhappy seeing
+	 * there is nested lock without mutex_lock_nested() prefix.
+	 */
+	BUG_ON(!mutex_trylock(&nd_lock->mutex));
+	attach_nd_lock(ndev, nd_lock);
+
 	bpq = netdev_priv(ndev);
 	dev_hold(edev);
 	bpq->ethdev = edev;
@@ -496,19 +513,23 @@ static int bpq_new_device(struct net_device *edev)
 	eth_broadcast_addr(bpq->dest_addr);
 	eth_broadcast_addr(bpq->acpt_addr);
 
-	err = register_netdevice(ndev);
+	err = __register_netdevice(ndev);
 	if (err)
-		goto error;
+		goto err_detach;
 	bpq_set_lockdep_class(ndev);
 
 	/* List protected by RTNL */
 	list_add_rcu(&bpq->bpq_list, &bpq_devices);
-	return 0;
+unlock:
+	unlock_netdev(nd_lock);
+	return err;
 
- error:
+err_detach:
+	detach_nd_lock(ndev);
 	dev_put(edev);
+err_free:
 	free_netdev(ndev);
-	return err;
+	goto unlock;
 	
 }
 


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ