linux-block.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* bdi lifetime fix
@ 2021-08-16 12:26 Christoph Hellwig
  2021-08-16 12:26 ` [PATCH 1/2] block: free the extended dev_t minor later Christoph Hellwig
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Christoph Hellwig @ 2021-08-16 12:26 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Qian Cai, linux-block

Hi Jens,

this series fixes a bdi lifetime issue.  The bug report was triggered
by the move of the bdi to the gendisk, but the underlying issue is much
older.

This supersedes the ealier "block: ensure the bdi is freed after
inode_detach_wb" patch.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/2] block: free the extended dev_t minor later
  2021-08-16 12:26 bdi lifetime fix Christoph Hellwig
@ 2021-08-16 12:26 ` Christoph Hellwig
  2021-08-16 12:26 ` [PATCH 2/2] block: ensure the bdi is freed after inode_detach_wb Christoph Hellwig
  2021-08-16 16:49 ` bdi lifetime fix Jens Axboe
  2 siblings, 0 replies; 4+ messages in thread
From: Christoph Hellwig @ 2021-08-16 12:26 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Qian Cai, linux-block

The dev_t is used as the inode hash, so we should only released it
once then block device inode is gone from the inode cache.  Move it
to bdev_free_inode to ensure that.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 block/genhd.c           | 2 --
 block/partitions/core.c | 2 --
 fs/block_dev.c          | 5 +++++
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/block/genhd.c b/block/genhd.c
index 9d6b3aeea288..ed58ddf6258b 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -1085,8 +1085,6 @@ static void disk_release(struct device *dev)
 	might_sleep();
 
 	bdi_put(disk->bdi);
-	if (MAJOR(dev->devt) == BLOCK_EXT_MAJOR)
-		blk_free_ext_minor(MINOR(dev->devt));
 	disk_release_events(disk);
 	kfree(disk->random);
 	xa_destroy(&disk->part_tbl);
diff --git a/block/partitions/core.c b/block/partitions/core.c
index 9265936df77e..58c4c362c94f 100644
--- a/block/partitions/core.c
+++ b/block/partitions/core.c
@@ -259,8 +259,6 @@ static const struct attribute_group *part_attr_groups[] = {
 
 static void part_release(struct device *dev)
 {
-	if (MAJOR(dev->devt) == BLOCK_EXT_MAJOR)
-		blk_free_ext_minor(MINOR(dev->devt));
 	put_disk(dev_to_bdev(dev)->bd_disk);
 	iput(dev_to_bdev(dev)->bd_inode);
 }
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 38a8b0e04a0c..4bd2a632c79c 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -35,6 +35,7 @@
 #include <linux/uaccess.h>
 #include <linux/suspend.h>
 #include "internal.h"
+#include "../block/blk.h"
 
 struct bdev_inode {
 	struct block_device bdev;
@@ -813,6 +814,10 @@ static void bdev_free_inode(struct inode *inode)
 
 	if (!bdev_is_partition(bdev))
 		kfree(bdev->bd_disk);
+
+	if (MAJOR(bdev->bd_dev) == BLOCK_EXT_MAJOR)
+		blk_free_ext_minor(MINOR(bdev->bd_dev));
+
 	kmem_cache_free(bdev_cachep, BDEV_I(inode));
 }
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2] block: ensure the bdi is freed after inode_detach_wb
  2021-08-16 12:26 bdi lifetime fix Christoph Hellwig
  2021-08-16 12:26 ` [PATCH 1/2] block: free the extended dev_t minor later Christoph Hellwig
@ 2021-08-16 12:26 ` Christoph Hellwig
  2021-08-16 16:49 ` bdi lifetime fix Jens Axboe
  2 siblings, 0 replies; 4+ messages in thread
From: Christoph Hellwig @ 2021-08-16 12:26 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Qian Cai, linux-block, syzbot

inode_detach_wb references the "main" bdi of the inode.  With the
recent change to move the bdi from the request_queue to the gendisk
this causes a guaranteed use after free when using certain cgroup
configurations.  The big itself is older through as any non-default
inode reference (e.g. an open file descriptor) could have injected
this use after free even before that.

Fixes: 52ebea749aae ("writeback: make backing_dev_info host cgroup-specific bdi_writebacks")
Reported-by: Qian Cai <quic_qiancai@quicinc.com>
Reported-by: syzbot <syzbot+1fb38bb7d3ce0fa3e1c4@syzkaller.appspotmail.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 block/genhd.c  | 1 -
 fs/block_dev.c | 7 ++++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/block/genhd.c b/block/genhd.c
index ed58ddf6258b..731a46063132 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -1084,7 +1084,6 @@ static void disk_release(struct device *dev)
 
 	might_sleep();
 
-	bdi_put(disk->bdi);
 	disk_release_events(disk);
 	kfree(disk->random);
 	xa_destroy(&disk->part_tbl);
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 4bd2a632c79c..d3a8062302a0 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -812,8 +812,11 @@ static void bdev_free_inode(struct inode *inode)
 	free_percpu(bdev->bd_stats);
 	kfree(bdev->bd_meta_info);
 
-	if (!bdev_is_partition(bdev))
+	if (!bdev_is_partition(bdev)) {
+		if (bdev->bd_disk && bdev->bd_disk->bdi)
+			bdi_put(bdev->bd_disk->bdi);
 		kfree(bdev->bd_disk);
+	}
 
 	if (MAJOR(bdev->bd_dev) == BLOCK_EXT_MAJOR)
 		blk_free_ext_minor(MINOR(bdev->bd_dev));
@@ -833,8 +836,6 @@ static void bdev_evict_inode(struct inode *inode)
 	truncate_inode_pages_final(&inode->i_data);
 	invalidate_inode_buffers(inode); /* is it needed here? */
 	clear_inode(inode);
-	/* Detach inode from wb early as bdi_put() may free bdi->wb */
-	inode_detach_wb(inode);
 }
 
 static const struct super_operations bdev_sops = {
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: bdi lifetime fix
  2021-08-16 12:26 bdi lifetime fix Christoph Hellwig
  2021-08-16 12:26 ` [PATCH 1/2] block: free the extended dev_t minor later Christoph Hellwig
  2021-08-16 12:26 ` [PATCH 2/2] block: ensure the bdi is freed after inode_detach_wb Christoph Hellwig
@ 2021-08-16 16:49 ` Jens Axboe
  2 siblings, 0 replies; 4+ messages in thread
From: Jens Axboe @ 2021-08-16 16:49 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Qian Cai, linux-block

On 8/16/21 6:26 AM, Christoph Hellwig wrote:
> Hi Jens,
> 
> this series fixes a bdi lifetime issue.  The bug report was triggered
> by the move of the bdi to the gendisk, but the underlying issue is much
> older.
> 
> This supersedes the ealier "block: ensure the bdi is freed after
> inode_detach_wb" patch.

Applied, thanks.

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-08-16 16:49 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-16 12:26 bdi lifetime fix Christoph Hellwig
2021-08-16 12:26 ` [PATCH 1/2] block: free the extended dev_t minor later Christoph Hellwig
2021-08-16 12:26 ` [PATCH 2/2] block: ensure the bdi is freed after inode_detach_wb Christoph Hellwig
2021-08-16 16:49 ` bdi lifetime fix Jens Axboe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).