[Devel] [PATCH rh7 3/8] nbd: fix use after free on module unload

Andrey Ryabinin aryabinin at virtuozzo.com
Fri Nov 1 22:12:13 MSK 2019


From: Josef Bacik <josef at toxicpanda.com>

list_for_each_entry() isn't super safe if we're freeing the objects
while we traverse the list.  Also don't bother taking the extra
reference, the module refcounting stuff will save us from having anybody
messing with the device while we're trying to unload.

Reported-by: Ming Lei <ming.lei at redhat.com>
Signed-off-by: Josef Bacik <jbacik at fb.com>
Signed-off-by: Jens Axboe <axboe at fb.com>

https://jira.sw.ru/browse/PSBM-99102
(cherry picked from commit 60ae36ad0340b1ba88530d6a5e141455dd3afd81)
Signed-off-by: Andrey Ryabinin <aryabinin at virtuozzo.com>
---
 drivers/block/nbd.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 27fade554583..6713deae68cb 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -1426,7 +1426,6 @@ static int nbd_exit_cb(int id, void *ptr, void *data)
 	struct list_head *list = (struct list_head *)data;
 	struct nbd_device *nbd = ptr;
 
-	refcount_inc(&nbd->refs);
 	list_add_tail(&nbd->list, list);
 	return 0;
 }
@@ -1442,11 +1441,12 @@ static void __exit nbd_cleanup(void)
 	idr_for_each(&nbd_index_idr, &nbd_exit_cb, &del_list);
 	mutex_unlock(&nbd_index_mutex);
 
-	list_for_each_entry(nbd, &del_list, list) {
-		if (refcount_read(&nbd->refs) != 2)
+	while (!list_empty(&del_list)) {
+		nbd = list_first_entry(&del_list, struct nbd_device, list);
+		list_del_init(&nbd->list);
+		if (refcount_read(&nbd->refs) != 1)
 			printk(KERN_ERR "nbd: possibly leaking a device\n");
 		nbd_put(nbd);
-		nbd_put(nbd);
 	}
 
 	idr_destroy(&nbd_index_idr);
-- 
2.23.0



More information about the Devel mailing list