From: James Bottomley Date: Mon, 7 Jul 2008 20:50:01 +0000 (-0500) Subject: [SCSI] bsg: fix oops on remove X-Git-Tag: firefly_0821_release~19717^2 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=8df5fc042c8e7c08dc438c8198b62407ee1e91a0;p=firefly-linux-kernel-4.4.55.git [SCSI] bsg: fix oops on remove If you do a modremove of any sas driver, you run into an oops on shutdown when the host is removed (coming from the host bsg device). The root cause seems to be that there's a use after free of the bsg_class_device: In bsg_kref_release_function, this is used (to do a put_device(bcg->parent) after bcg->release has been called. In sas (and possibly many other things) bcd->release frees the queue which contains the bsg_class_device, so we get a put_device on unreferenced memory. Fix this by taking a copy of the pointer to the parent before releasing bsg. Acked-by: FUJITA Tomonori Signed-off-by: James Bottomley --- diff --git a/block/bsg.c b/block/bsg.c index f0b7cd343216..54d617f7df3e 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -709,11 +709,12 @@ static void bsg_kref_release_function(struct kref *kref) { struct bsg_class_device *bcd = container_of(kref, struct bsg_class_device, ref); + struct device *parent = bcd->parent; if (bcd->release) bcd->release(bcd->parent); - put_device(bcd->parent); + put_device(parent); } static int bsg_put_device(struct bsg_device *bd)