Patch "net: rose: fix netdev reference changes" has been added to the 5.4-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    net: rose: fix netdev reference changes

to the 5.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     net-rose-fix-netdev-reference-changes.patch
and it can be found in the queue-5.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 8784a7a37d0d2c125ba0d454789ec0e26cda031f
Author: Eric Dumazet <edumazet@xxxxxxxxxx>
Date:   Fri Jul 29 09:12:32 2022 +0000

    net: rose: fix netdev reference changes
    
    [ Upstream commit 931027820e4dafabc78aff82af59f8c1c4bd3128 ]
    
    Bernard reported that trying to unload rose module would lead
    to infamous messages:
    
    unregistered_netdevice: waiting for rose0 to become free. Usage count = xx
    
    This patch solves the issue, by making sure each socket referring to
    a netdevice holds a reference count on it, and properly releases it
    in rose_release().
    
    rose_dev_first() is also fixed to take a device reference
    before leaving the rcu_read_locked section.
    
    Following patch will add ref_tracker annotations to ease
    future bug hunting.
    
    Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
    Reported-by: Bernard Pidoux <f6bvp@xxxxxxx>
    Signed-off-by: Eric Dumazet <edumazet@xxxxxxxxxx>
    Tested-by: Bernard Pidoux <f6bvp@xxxxxxx>
    Signed-off-by: Jakub Kicinski <kuba@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index 6a0df7c8a939..95dda29058a0 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -169,6 +169,7 @@ static void rose_kill_by_device(struct net_device *dev)
 			rose_disconnect(s, ENETUNREACH, ROSE_OUT_OF_ORDER, 0);
 			if (rose->neighbour)
 				rose->neighbour->use--;
+			dev_put(rose->device);
 			rose->device = NULL;
 		}
 	}
@@ -569,6 +570,8 @@ static struct sock *rose_make_new(struct sock *osk)
 	rose->idle	= orose->idle;
 	rose->defer	= orose->defer;
 	rose->device	= orose->device;
+	if (rose->device)
+		dev_hold(rose->device);
 	rose->qbitincl	= orose->qbitincl;
 
 	return sk;
@@ -622,6 +625,7 @@ static int rose_release(struct socket *sock)
 		break;
 	}
 
+	dev_put(rose->device);
 	sock->sk = NULL;
 	release_sock(sk);
 	sock_put(sk);
@@ -698,7 +702,6 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
 	struct rose_sock *rose = rose_sk(sk);
 	struct sockaddr_rose *addr = (struct sockaddr_rose *)uaddr;
 	unsigned char cause, diagnostic;
-	struct net_device *dev;
 	ax25_uid_assoc *user;
 	int n, err = 0;
 
@@ -755,9 +758,12 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
 	}
 
 	if (sock_flag(sk, SOCK_ZAPPED)) {	/* Must bind first - autobinding in this may or may not work */
+		struct net_device *dev;
+
 		sock_reset_flag(sk, SOCK_ZAPPED);
 
-		if ((dev = rose_dev_first()) == NULL) {
+		dev = rose_dev_first();
+		if (!dev) {
 			err = -ENETUNREACH;
 			goto out_release;
 		}
@@ -765,6 +771,7 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
 		user = ax25_findbyuid(current_euid());
 		if (!user) {
 			err = -EINVAL;
+			dev_put(dev);
 			goto out_release;
 		}
 
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
index 5f32113c9bbd..64d441d3b653 100644
--- a/net/rose/rose_route.c
+++ b/net/rose/rose_route.c
@@ -613,6 +613,8 @@ struct net_device *rose_dev_first(void)
 			if (first == NULL || strncmp(dev->name, first->name, 3) < 0)
 				first = dev;
 	}
+	if (first)
+		dev_hold(first);
 	rcu_read_unlock();
 
 	return first;



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux