linux-block.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* bdi: fix use-after-free for dev_name(bdi->dev) v3 (resend)
@ 2020-05-04 12:47 Christoph Hellwig
  2020-05-04 12:47 ` [PATCH 1/9] vboxsf: don't use the source name in the bdi name Christoph Hellwig
                   ` (10 more replies)
  0 siblings, 11 replies; 13+ messages in thread
From: Christoph Hellwig @ 2020-05-04 12:47 UTC (permalink / raw)
  To: axboe
  Cc: yuyufen, tj, jack, bvanassche, tytso, hdegoede, gregkh,
	linux-block, linux-kernel

Hi Jens,

can you pick up this series?

the first three patches are my take on the proposal from Yufen Yu
to fix the use after free of the device name of the bdi device.

The rest is vaguely related cleanups.

Changes since v2:
 - switch vboxsf to a shorter bdi name

Changes since v1:
 - use a static dev_name buffer inside struct backing_dev_info

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

* [PATCH 1/9] vboxsf: don't use the source name in the bdi name
  2020-05-04 12:47 bdi: fix use-after-free for dev_name(bdi->dev) v3 (resend) Christoph Hellwig
@ 2020-05-04 12:47 ` Christoph Hellwig
  2020-05-04 12:47 ` [PATCH 2/9] bdi: move bdi_dev_name out of line Christoph Hellwig
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Christoph Hellwig @ 2020-05-04 12:47 UTC (permalink / raw)
  To: axboe
  Cc: yuyufen, tj, jack, bvanassche, tytso, hdegoede, gregkh,
	linux-block, linux-kernel

Simplify the bdi name to mirror what we are doing elsewhere, and
drop them name in favor of just using a number.  This avoids a
potentially very long bdi name.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
---
 fs/vboxsf/super.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/vboxsf/super.c b/fs/vboxsf/super.c
index 675e269893765..8fe03b4a0d2b0 100644
--- a/fs/vboxsf/super.c
+++ b/fs/vboxsf/super.c
@@ -164,7 +164,7 @@ static int vboxsf_fill_super(struct super_block *sb, struct fs_context *fc)
 		goto fail_free;
 	}
 
-	err = super_setup_bdi_name(sb, "vboxsf-%s.%d", fc->source, sbi->bdi_id);
+	err = super_setup_bdi_name(sb, "vboxsf-%d", sbi->bdi_id);
 	if (err)
 		goto fail_free;
 
-- 
2.26.2


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

* [PATCH 2/9] bdi: move bdi_dev_name out of line
  2020-05-04 12:47 bdi: fix use-after-free for dev_name(bdi->dev) v3 (resend) Christoph Hellwig
  2020-05-04 12:47 ` [PATCH 1/9] vboxsf: don't use the source name in the bdi name Christoph Hellwig
@ 2020-05-04 12:47 ` Christoph Hellwig
  2020-05-04 12:47 ` [PATCH 3/9] bdi: use bdi_dev_name() to get device name Christoph Hellwig
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Christoph Hellwig @ 2020-05-04 12:47 UTC (permalink / raw)
  To: axboe
  Cc: yuyufen, tj, jack, bvanassche, tytso, hdegoede, gregkh,
	linux-block, linux-kernel

bdi_dev_name is not a fast path function, move it out of line.  This
prepares for using it from modular callers without having to export
an implementation detail like bdi_unknown_name.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
---
 include/linux/backing-dev.h |  9 +--------
 mm/backing-dev.c            | 10 +++++++++-
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
index f88197c1ffc2d..c9ad5c3b7b4b2 100644
--- a/include/linux/backing-dev.h
+++ b/include/linux/backing-dev.h
@@ -505,13 +505,6 @@ static inline int bdi_rw_congested(struct backing_dev_info *bdi)
 				  (1 << WB_async_congested));
 }
 
-extern const char *bdi_unknown_name;
-
-static inline const char *bdi_dev_name(struct backing_dev_info *bdi)
-{
-	if (!bdi || !bdi->dev)
-		return bdi_unknown_name;
-	return dev_name(bdi->dev);
-}
+const char *bdi_dev_name(struct backing_dev_info *bdi);
 
 #endif	/* _LINUX_BACKING_DEV_H */
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index c81b4f3a72684..c2c44c89ee5d7 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -21,7 +21,7 @@ struct backing_dev_info noop_backing_dev_info = {
 EXPORT_SYMBOL_GPL(noop_backing_dev_info);
 
 static struct class *bdi_class;
-const char *bdi_unknown_name = "(unknown)";
+static const char *bdi_unknown_name = "(unknown)";
 
 /*
  * bdi_lock protects bdi_tree and updates to bdi_list. bdi_list has RCU
@@ -1043,6 +1043,14 @@ void bdi_put(struct backing_dev_info *bdi)
 }
 EXPORT_SYMBOL(bdi_put);
 
+const char *bdi_dev_name(struct backing_dev_info *bdi)
+{
+	if (!bdi || !bdi->dev)
+		return bdi_unknown_name;
+	return dev_name(bdi->dev);
+}
+EXPORT_SYMBOL_GPL(bdi_dev_name);
+
 static wait_queue_head_t congestion_wqh[2] = {
 		__WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[0]),
 		__WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[1])
-- 
2.26.2


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

* [PATCH 3/9] bdi: use bdi_dev_name() to get device name
  2020-05-04 12:47 bdi: fix use-after-free for dev_name(bdi->dev) v3 (resend) Christoph Hellwig
  2020-05-04 12:47 ` [PATCH 1/9] vboxsf: don't use the source name in the bdi name Christoph Hellwig
  2020-05-04 12:47 ` [PATCH 2/9] bdi: move bdi_dev_name out of line Christoph Hellwig
@ 2020-05-04 12:47 ` Christoph Hellwig
  2020-05-04 12:47 ` [PATCH 4/9] bdi: add a ->dev_name field to struct backing_dev_info Christoph Hellwig
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Christoph Hellwig @ 2020-05-04 12:47 UTC (permalink / raw)
  To: axboe
  Cc: yuyufen, tj, jack, bvanassche, tytso, hdegoede, gregkh,
	linux-block, linux-kernel

From: Yufen Yu <yuyufen@huawei.com>

Use the common interface bdi_dev_name() to get device name.

Signed-off-by: Yufen Yu <yuyufen@huawei.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
---
 block/bfq-iosched.c        | 5 +++--
 block/blk-cgroup.c         | 2 +-
 fs/ceph/debugfs.c          | 2 +-
 include/trace/events/wbt.h | 8 ++++----
 4 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
index 78ba57efd16b5..4d4fe44a9eea6 100644
--- a/block/bfq-iosched.c
+++ b/block/bfq-iosched.c
@@ -4976,8 +4976,9 @@ bfq_set_next_ioprio_data(struct bfq_queue *bfqq, struct bfq_io_cq *bic)
 	ioprio_class = IOPRIO_PRIO_CLASS(bic->ioprio);
 	switch (ioprio_class) {
 	default:
-		dev_err(bfqq->bfqd->queue->backing_dev_info->dev,
-			"bfq: bad prio class %d\n", ioprio_class);
+		pr_err("bdi %s: bfq: bad prio class %d\n",
+				bdi_dev_name(bfqq->bfqd->queue->backing_dev_info),
+				ioprio_class);
 		/* fall through */
 	case IOPRIO_CLASS_NONE:
 		/*
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index 0a63c6cbbcb14..0ecc897b225c9 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -496,7 +496,7 @@ const char *blkg_dev_name(struct blkcg_gq *blkg)
 {
 	/* some drivers (floppy) instantiate a queue w/o disk registered */
 	if (blkg->q->backing_dev_info->dev)
-		return dev_name(blkg->q->backing_dev_info->dev);
+		return bdi_dev_name(blkg->q->backing_dev_info);
 	return NULL;
 }
 
diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c
index 481ac97b4d25b..dcaed75de9e6a 100644
--- a/fs/ceph/debugfs.c
+++ b/fs/ceph/debugfs.c
@@ -271,7 +271,7 @@ void ceph_fs_debugfs_init(struct ceph_fs_client *fsc)
 				    &congestion_kb_fops);
 
 	snprintf(name, sizeof(name), "../../bdi/%s",
-		 dev_name(fsc->sb->s_bdi->dev));
+		 bdi_dev_name(fsc->sb->s_bdi));
 	fsc->debugfs_bdi =
 		debugfs_create_symlink("bdi",
 				       fsc->client->debugfs_dir,
diff --git a/include/trace/events/wbt.h b/include/trace/events/wbt.h
index 784814160197b..9c66e59d859cb 100644
--- a/include/trace/events/wbt.h
+++ b/include/trace/events/wbt.h
@@ -33,7 +33,7 @@ TRACE_EVENT(wbt_stat,
 	),
 
 	TP_fast_assign(
-		strlcpy(__entry->name, dev_name(bdi->dev),
+		strlcpy(__entry->name, bdi_dev_name(bdi),
 			ARRAY_SIZE(__entry->name));
 		__entry->rmean		= stat[0].mean;
 		__entry->rmin		= stat[0].min;
@@ -68,7 +68,7 @@ TRACE_EVENT(wbt_lat,
 	),
 
 	TP_fast_assign(
-		strlcpy(__entry->name, dev_name(bdi->dev),
+		strlcpy(__entry->name, bdi_dev_name(bdi),
 			ARRAY_SIZE(__entry->name));
 		__entry->lat = div_u64(lat, 1000);
 	),
@@ -105,7 +105,7 @@ TRACE_EVENT(wbt_step,
 	),
 
 	TP_fast_assign(
-		strlcpy(__entry->name, dev_name(bdi->dev),
+		strlcpy(__entry->name, bdi_dev_name(bdi),
 			ARRAY_SIZE(__entry->name));
 		__entry->msg	= msg;
 		__entry->step	= step;
@@ -141,7 +141,7 @@ TRACE_EVENT(wbt_timer,
 	),
 
 	TP_fast_assign(
-		strlcpy(__entry->name, dev_name(bdi->dev),
+		strlcpy(__entry->name, bdi_dev_name(bdi),
 			ARRAY_SIZE(__entry->name));
 		__entry->status		= status;
 		__entry->step		= step;
-- 
2.26.2


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

* [PATCH 4/9] bdi: add a ->dev_name field to struct backing_dev_info
  2020-05-04 12:47 bdi: fix use-after-free for dev_name(bdi->dev) v3 (resend) Christoph Hellwig
                   ` (2 preceding siblings ...)
  2020-05-04 12:47 ` [PATCH 3/9] bdi: use bdi_dev_name() to get device name Christoph Hellwig
@ 2020-05-04 12:47 ` Christoph Hellwig
  2020-05-04 12:47 ` [PATCH 5/9] driver core: remove device_create_vargs Christoph Hellwig
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Christoph Hellwig @ 2020-05-04 12:47 UTC (permalink / raw)
  To: axboe
  Cc: yuyufen, tj, jack, bvanassche, tytso, hdegoede, gregkh,
	linux-block, linux-kernel

Cache a copy of the name for the life time of the backing_dev_info
structure so that we can reference it even after unregistering.

Fixes: 68f23b89067f ("memcg: fix a crash in wb_workfn when a device disappears")
Reported-by: Yufen Yu <yuyufen@huawei.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
---
 include/linux/backing-dev-defs.h | 1 +
 mm/backing-dev.c                 | 5 +++--
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/include/linux/backing-dev-defs.h b/include/linux/backing-dev-defs.h
index 4fc87dee005ab..2849bdbb3acbe 100644
--- a/include/linux/backing-dev-defs.h
+++ b/include/linux/backing-dev-defs.h
@@ -220,6 +220,7 @@ struct backing_dev_info {
 	wait_queue_head_t wb_waitq;
 
 	struct device *dev;
+	char dev_name[64];
 	struct device *owner;
 
 	struct timer_list laptop_mode_wb_timer;
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index c2c44c89ee5d7..efc5b83acd2df 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -938,7 +938,8 @@ int bdi_register_va(struct backing_dev_info *bdi, const char *fmt, va_list args)
 	if (bdi->dev)	/* The driver needs to use separate queues per device */
 		return 0;
 
-	dev = device_create_vargs(bdi_class, NULL, MKDEV(0, 0), bdi, fmt, args);
+	vsnprintf(bdi->dev_name, sizeof(bdi->dev_name), fmt, args);
+	dev = device_create(bdi_class, NULL, MKDEV(0, 0), bdi, bdi->dev_name);
 	if (IS_ERR(dev))
 		return PTR_ERR(dev);
 
@@ -1047,7 +1048,7 @@ const char *bdi_dev_name(struct backing_dev_info *bdi)
 {
 	if (!bdi || !bdi->dev)
 		return bdi_unknown_name;
-	return dev_name(bdi->dev);
+	return bdi->dev_name;
 }
 EXPORT_SYMBOL_GPL(bdi_dev_name);
 
-- 
2.26.2


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

* [PATCH 5/9] driver core: remove device_create_vargs
  2020-05-04 12:47 bdi: fix use-after-free for dev_name(bdi->dev) v3 (resend) Christoph Hellwig
                   ` (3 preceding siblings ...)
  2020-05-04 12:47 ` [PATCH 4/9] bdi: add a ->dev_name field to struct backing_dev_info Christoph Hellwig
@ 2020-05-04 12:47 ` Christoph Hellwig
  2020-05-04 12:47 ` [PATCH 6/9] bdi: unexport bdi_register_va Christoph Hellwig
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Christoph Hellwig @ 2020-05-04 12:47 UTC (permalink / raw)
  To: axboe
  Cc: yuyufen, tj, jack, bvanassche, tytso, hdegoede, gregkh,
	linux-block, linux-kernel

All external users of device_create_vargs are gone, so remove it and
open code it in the only caller.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Jan Kara <jack@suse.cz>
---
 drivers/base/core.c    | 37 ++-----------------------------------
 include/linux/device.h |  4 ----
 2 files changed, 2 insertions(+), 39 deletions(-)

diff --git a/drivers/base/core.c b/drivers/base/core.c
index 139cdf7e73271..fb8ae248e5aa8 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -3188,40 +3188,6 @@ device_create_groups_vargs(struct class *class, struct device *parent,
 	return ERR_PTR(retval);
 }
 
-/**
- * device_create_vargs - creates a device and registers it with sysfs
- * @class: pointer to the struct class that this device should be registered to
- * @parent: pointer to the parent struct device of this new device, if any
- * @devt: the dev_t for the char device to be added
- * @drvdata: the data to be added to the device for callbacks
- * @fmt: string for the device's name
- * @args: va_list for the device's name
- *
- * This function can be used by char device classes.  A struct device
- * will be created in sysfs, registered to the specified class.
- *
- * A "dev" file will be created, showing the dev_t for the device, if
- * the dev_t is not 0,0.
- * If a pointer to a parent struct device is passed in, the newly created
- * struct device will be a child of that device in sysfs.
- * The pointer to the struct device will be returned from the call.
- * Any further sysfs files that might be required can be created using this
- * pointer.
- *
- * Returns &struct device pointer on success, or ERR_PTR() on error.
- *
- * Note: the struct class passed to this function must have previously
- * been created with a call to class_create().
- */
-struct device *device_create_vargs(struct class *class, struct device *parent,
-				   dev_t devt, void *drvdata, const char *fmt,
-				   va_list args)
-{
-	return device_create_groups_vargs(class, parent, devt, drvdata, NULL,
-					  fmt, args);
-}
-EXPORT_SYMBOL_GPL(device_create_vargs);
-
 /**
  * device_create - creates a device and registers it with sysfs
  * @class: pointer to the struct class that this device should be registered to
@@ -3253,7 +3219,8 @@ struct device *device_create(struct class *class, struct device *parent,
 	struct device *dev;
 
 	va_start(vargs, fmt);
-	dev = device_create_vargs(class, parent, devt, drvdata, fmt, vargs);
+	dev = device_create_groups_vargs(class, parent, devt, drvdata, NULL,
+					  fmt, vargs);
 	va_end(vargs);
 	return dev;
 }
diff --git a/include/linux/device.h b/include/linux/device.h
index ac8e37cd716a3..15460a5ac024a 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -884,10 +884,6 @@ extern bool device_is_bound(struct device *dev);
 /*
  * Easy functions for dynamically creating devices on the fly
  */
-extern __printf(5, 0)
-struct device *device_create_vargs(struct class *cls, struct device *parent,
-				   dev_t devt, void *drvdata,
-				   const char *fmt, va_list vargs);
 extern __printf(5, 6)
 struct device *device_create(struct class *cls, struct device *parent,
 			     dev_t devt, void *drvdata,
-- 
2.26.2


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

* [PATCH 6/9] bdi: unexport bdi_register_va
  2020-05-04 12:47 bdi: fix use-after-free for dev_name(bdi->dev) v3 (resend) Christoph Hellwig
                   ` (4 preceding siblings ...)
  2020-05-04 12:47 ` [PATCH 5/9] driver core: remove device_create_vargs Christoph Hellwig
@ 2020-05-04 12:47 ` Christoph Hellwig
  2020-05-04 12:47 ` [PATCH 7/9] bdi: remove bdi_register_owner Christoph Hellwig
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Christoph Hellwig @ 2020-05-04 12:47 UTC (permalink / raw)
  To: axboe
  Cc: yuyufen, tj, jack, bvanassche, tytso, hdegoede, gregkh,
	linux-block, linux-kernel

bdi_register_va is only used by super.c, which can't be modular.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
---
 mm/backing-dev.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index efc5b83acd2df..eb6b51e49d11f 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -964,7 +964,6 @@ int bdi_register_va(struct backing_dev_info *bdi, const char *fmt, va_list args)
 	trace_writeback_bdi_register(bdi);
 	return 0;
 }
-EXPORT_SYMBOL(bdi_register_va);
 
 int bdi_register(struct backing_dev_info *bdi, const char *fmt, ...)
 {
-- 
2.26.2


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

* [PATCH 7/9] bdi: remove bdi_register_owner
  2020-05-04 12:47 bdi: fix use-after-free for dev_name(bdi->dev) v3 (resend) Christoph Hellwig
                   ` (5 preceding siblings ...)
  2020-05-04 12:47 ` [PATCH 6/9] bdi: unexport bdi_register_va Christoph Hellwig
@ 2020-05-04 12:47 ` Christoph Hellwig
  2020-05-04 12:48 ` [PATCH 8/9] bdi: simplify bdi_alloc Christoph Hellwig
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Christoph Hellwig @ 2020-05-04 12:47 UTC (permalink / raw)
  To: axboe
  Cc: yuyufen, tj, jack, bvanassche, tytso, hdegoede, gregkh,
	linux-block, linux-kernel

Split out a new bdi_set_owner helper to set the owner, and move the policy
for creating the bdi name back into genhd.c, where it belongs.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
---
 block/genhd.c               |  8 +++++---
 include/linux/backing-dev.h |  2 +-
 mm/backing-dev.c            | 12 ++----------
 3 files changed, 8 insertions(+), 14 deletions(-)

diff --git a/block/genhd.c b/block/genhd.c
index c05d509877fa7..27511b3d164dd 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -840,13 +840,15 @@ static void __device_add_disk(struct device *parent, struct gendisk *disk,
 		disk->flags |= GENHD_FL_SUPPRESS_PARTITION_INFO;
 		disk->flags |= GENHD_FL_NO_PART_SCAN;
 	} else {
+		struct backing_dev_info *bdi = disk->queue->backing_dev_info;
+		struct device *dev = disk_to_dev(disk);
 		int ret;
 
 		/* Register BDI before referencing it from bdev */
-		disk_to_dev(disk)->devt = devt;
-		ret = bdi_register_owner(disk->queue->backing_dev_info,
-						disk_to_dev(disk));
+		dev->devt = devt;
+		ret = bdi_register(bdi, "%u:%u", MAJOR(devt), MINOR(devt));
 		WARN_ON(ret);
+		bdi_set_owner(bdi, dev);
 		blk_register_region(disk_devt(disk), disk->minors, NULL,
 				    exact_match, exact_lock, disk);
 	}
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
index c9ad5c3b7b4b2..4098ed6ba6b43 100644
--- a/include/linux/backing-dev.h
+++ b/include/linux/backing-dev.h
@@ -33,7 +33,7 @@ int bdi_register(struct backing_dev_info *bdi, const char *fmt, ...);
 __printf(2, 0)
 int bdi_register_va(struct backing_dev_info *bdi, const char *fmt,
 		    va_list args);
-int bdi_register_owner(struct backing_dev_info *bdi, struct device *owner);
+void bdi_set_owner(struct backing_dev_info *bdi, struct device *owner);
 void bdi_unregister(struct backing_dev_info *bdi);
 
 struct backing_dev_info *bdi_alloc_node(gfp_t gfp_mask, int node_id);
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index eb6b51e49d11f..bb993f99d4244 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -977,20 +977,12 @@ int bdi_register(struct backing_dev_info *bdi, const char *fmt, ...)
 }
 EXPORT_SYMBOL(bdi_register);
 
-int bdi_register_owner(struct backing_dev_info *bdi, struct device *owner)
+void bdi_set_owner(struct backing_dev_info *bdi, struct device *owner)
 {
-	int rc;
-
-	rc = bdi_register(bdi, "%u:%u", MAJOR(owner->devt), MINOR(owner->devt));
-	if (rc)
-		return rc;
-	/* Leaking owner reference... */
-	WARN_ON(bdi->owner);
+	WARN_ON_ONCE(bdi->owner);
 	bdi->owner = owner;
 	get_device(owner);
-	return 0;
 }
-EXPORT_SYMBOL(bdi_register_owner);
 
 /*
  * Remove bdi from bdi_list, and ensure that it is no longer visible
-- 
2.26.2


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

* [PATCH 8/9] bdi: simplify bdi_alloc
  2020-05-04 12:47 bdi: fix use-after-free for dev_name(bdi->dev) v3 (resend) Christoph Hellwig
                   ` (6 preceding siblings ...)
  2020-05-04 12:47 ` [PATCH 7/9] bdi: remove bdi_register_owner Christoph Hellwig
@ 2020-05-04 12:48 ` Christoph Hellwig
  2020-05-04 12:48 ` [PATCH 9/9] bdi: remove the name field in struct backing_dev_info Christoph Hellwig
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Christoph Hellwig @ 2020-05-04 12:48 UTC (permalink / raw)
  To: axboe
  Cc: yuyufen, tj, jack, bvanassche, tytso, hdegoede, gregkh,
	linux-block, linux-kernel

Merge the _node vs normal version and drop the superflous gfp_t argument.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
---
 block/blk-core.c            | 2 +-
 drivers/mtd/mtdcore.c       | 2 +-
 fs/super.c                  | 2 +-
 include/linux/backing-dev.h | 6 +-----
 mm/backing-dev.c            | 7 +++----
 5 files changed, 7 insertions(+), 12 deletions(-)

diff --git a/block/blk-core.c b/block/blk-core.c
index 7f11560bfddbb..285a2f8ee8d3a 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -501,7 +501,7 @@ struct request_queue *__blk_alloc_queue(int node_id)
 	if (ret)
 		goto fail_id;
 
-	q->backing_dev_info = bdi_alloc_node(GFP_KERNEL, node_id);
+	q->backing_dev_info = bdi_alloc(node_id);
 	if (!q->backing_dev_info)
 		goto fail_split;
 
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 2916674208b32..39ec563d9a14b 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -2036,7 +2036,7 @@ static struct backing_dev_info * __init mtd_bdi_init(char *name)
 	struct backing_dev_info *bdi;
 	int ret;
 
-	bdi = bdi_alloc(GFP_KERNEL);
+	bdi = bdi_alloc(NUMA_NO_NODE);
 	if (!bdi)
 		return ERR_PTR(-ENOMEM);
 
diff --git a/fs/super.c b/fs/super.c
index cd352530eca90..dd28fcd706ff5 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -1598,7 +1598,7 @@ int super_setup_bdi_name(struct super_block *sb, char *fmt, ...)
 	int err;
 	va_list args;
 
-	bdi = bdi_alloc(GFP_KERNEL);
+	bdi = bdi_alloc(NUMA_NO_NODE);
 	if (!bdi)
 		return -ENOMEM;
 
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
index 4098ed6ba6b43..6b3504bf7a42b 100644
--- a/include/linux/backing-dev.h
+++ b/include/linux/backing-dev.h
@@ -36,11 +36,7 @@ int bdi_register_va(struct backing_dev_info *bdi, const char *fmt,
 void bdi_set_owner(struct backing_dev_info *bdi, struct device *owner);
 void bdi_unregister(struct backing_dev_info *bdi);
 
-struct backing_dev_info *bdi_alloc_node(gfp_t gfp_mask, int node_id);
-static inline struct backing_dev_info *bdi_alloc(gfp_t gfp_mask)
-{
-	return bdi_alloc_node(gfp_mask, NUMA_NO_NODE);
-}
+struct backing_dev_info *bdi_alloc(int node_id);
 
 void wb_start_background_writeback(struct bdi_writeback *wb);
 void wb_workfn(struct work_struct *work);
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index bb993f99d4244..1f55d5b8269ff 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -865,12 +865,11 @@ static int bdi_init(struct backing_dev_info *bdi)
 	return ret;
 }
 
-struct backing_dev_info *bdi_alloc_node(gfp_t gfp_mask, int node_id)
+struct backing_dev_info *bdi_alloc(int node_id)
 {
 	struct backing_dev_info *bdi;
 
-	bdi = kmalloc_node(sizeof(struct backing_dev_info),
-			   gfp_mask | __GFP_ZERO, node_id);
+	bdi = kzalloc_node(sizeof(*bdi), GFP_KERNEL, node_id);
 	if (!bdi)
 		return NULL;
 
@@ -880,7 +879,7 @@ struct backing_dev_info *bdi_alloc_node(gfp_t gfp_mask, int node_id)
 	}
 	return bdi;
 }
-EXPORT_SYMBOL(bdi_alloc_node);
+EXPORT_SYMBOL(bdi_alloc);
 
 static struct rb_node **bdi_lookup_rb_node(u64 id, struct rb_node **parentp)
 {
-- 
2.26.2


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

* [PATCH 9/9] bdi: remove the name field in struct backing_dev_info
  2020-05-04 12:47 bdi: fix use-after-free for dev_name(bdi->dev) v3 (resend) Christoph Hellwig
                   ` (7 preceding siblings ...)
  2020-05-04 12:48 ` [PATCH 8/9] bdi: simplify bdi_alloc Christoph Hellwig
@ 2020-05-04 12:48 ` Christoph Hellwig
  2020-05-07  6:27 ` PING for Re: bdi: fix use-after-free for dev_name(bdi->dev) v3 (resend) Christoph Hellwig
  2020-05-07  7:44 ` Ming Lei
  10 siblings, 0 replies; 13+ messages in thread
From: Christoph Hellwig @ 2020-05-04 12:48 UTC (permalink / raw)
  To: axboe
  Cc: yuyufen, tj, jack, bvanassche, tytso, hdegoede, gregkh,
	linux-block, linux-kernel

The name is only printed for a not registered bdi in writeback.  Use the
device name there as is more useful anyway for the unlike case that the
warning triggers.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
---
 block/blk-core.c                 | 1 -
 drivers/mtd/mtdcore.c            | 1 -
 fs/fs-writeback.c                | 2 +-
 fs/super.c                       | 2 --
 include/linux/backing-dev-defs.h | 2 --
 mm/backing-dev.c                 | 1 -
 6 files changed, 1 insertion(+), 8 deletions(-)

diff --git a/block/blk-core.c b/block/blk-core.c
index 285a2f8ee8d3a..538cbc725620b 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -511,7 +511,6 @@ struct request_queue *__blk_alloc_queue(int node_id)
 
 	q->backing_dev_info->ra_pages = VM_READAHEAD_PAGES;
 	q->backing_dev_info->capabilities = BDI_CAP_CGROUP_WRITEBACK;
-	q->backing_dev_info->name = "block";
 	q->node = node_id;
 
 	timer_setup(&q->backing_dev_info->laptop_mode_wb_timer,
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 39ec563d9a14b..fcb018ce17c3d 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -2040,7 +2040,6 @@ static struct backing_dev_info * __init mtd_bdi_init(char *name)
 	if (!bdi)
 		return ERR_PTR(-ENOMEM);
 
-	bdi->name = name;
 	/*
 	 * We put '-0' suffix to the name to get the same name format as we
 	 * used to get. Since this is called only once, we get a unique name. 
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 76ac9c7d32ec7..d85323607b49f 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -2320,7 +2320,7 @@ void __mark_inode_dirty(struct inode *inode, int flags)
 
 			WARN(bdi_cap_writeback_dirty(wb->bdi) &&
 			     !test_bit(WB_registered, &wb->state),
-			     "bdi-%s not registered\n", wb->bdi->name);
+			     "bdi-%s not registered\n", bdi_dev_name(wb->bdi));
 
 			inode->dirtied_when = jiffies;
 			if (dirtytime)
diff --git a/fs/super.c b/fs/super.c
index dd28fcd706ff5..4991f441988e0 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -1602,8 +1602,6 @@ int super_setup_bdi_name(struct super_block *sb, char *fmt, ...)
 	if (!bdi)
 		return -ENOMEM;
 
-	bdi->name = sb->s_type->name;
-
 	va_start(args, fmt);
 	err = bdi_register_va(bdi, fmt, args);
 	va_end(args);
diff --git a/include/linux/backing-dev-defs.h b/include/linux/backing-dev-defs.h
index 2849bdbb3acbe..011bb8ad0738a 100644
--- a/include/linux/backing-dev-defs.h
+++ b/include/linux/backing-dev-defs.h
@@ -194,8 +194,6 @@ struct backing_dev_info {
 	congested_fn *congested_fn; /* Function pointer if device is md/dm */
 	void *congested_data;	/* Pointer to aux data for congested func */
 
-	const char *name;
-
 	struct kref refcnt;	/* Reference counter for the structure */
 	unsigned int capabilities; /* Device capabilities */
 	unsigned int min_ratio;
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index 1f55d5b8269ff..d382272bcc310 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -15,7 +15,6 @@
 #include <trace/events/writeback.h>
 
 struct backing_dev_info noop_backing_dev_info = {
-	.name		= "noop",
 	.capabilities	= BDI_CAP_NO_ACCT_AND_WRITEBACK,
 };
 EXPORT_SYMBOL_GPL(noop_backing_dev_info);
-- 
2.26.2


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

* PING for Re: bdi: fix use-after-free for dev_name(bdi->dev) v3 (resend)
  2020-05-04 12:47 bdi: fix use-after-free for dev_name(bdi->dev) v3 (resend) Christoph Hellwig
                   ` (8 preceding siblings ...)
  2020-05-04 12:48 ` [PATCH 9/9] bdi: remove the name field in struct backing_dev_info Christoph Hellwig
@ 2020-05-07  6:27 ` Christoph Hellwig
  2020-05-07 14:57   ` Jens Axboe
  2020-05-07  7:44 ` Ming Lei
  10 siblings, 1 reply; 13+ messages in thread
From: Christoph Hellwig @ 2020-05-07  6:27 UTC (permalink / raw)
  To: axboe
  Cc: yuyufen, tj, jack, bvanassche, tytso, hdegoede, gregkh,
	linux-block, linux-kernel

On Mon, May 04, 2020 at 02:47:52PM +0200, Christoph Hellwig wrote:
> Hi Jens,
> 
> can you pick up this series?

ping?  Especially as 1-4 fix a kernel crash and should probably be
5.7 material.

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

* Re: bdi: fix use-after-free for dev_name(bdi->dev) v3 (resend)
  2020-05-04 12:47 bdi: fix use-after-free for dev_name(bdi->dev) v3 (resend) Christoph Hellwig
                   ` (9 preceding siblings ...)
  2020-05-07  6:27 ` PING for Re: bdi: fix use-after-free for dev_name(bdi->dev) v3 (resend) Christoph Hellwig
@ 2020-05-07  7:44 ` Ming Lei
  10 siblings, 0 replies; 13+ messages in thread
From: Ming Lei @ 2020-05-07  7:44 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: axboe, yuyufen, tj, jack, bvanassche, tytso, hdegoede, gregkh,
	linux-block, linux-kernel

On Mon, May 04, 2020 at 02:47:52PM +0200, Christoph Hellwig wrote:
> Hi Jens,
> 
> can you pick up this series?
> 
> the first three patches are my take on the proposal from Yufen Yu
> to fix the use after free of the device name of the bdi device.
> 
> The rest is vaguely related cleanups.
> 
> Changes since v2:
>  - switch vboxsf to a shorter bdi name
> 
> Changes since v1:
>  - use a static dev_name buffer inside struct backing_dev_info
> 

Looks fine:

Reviewed-by: Ming Lei <ming.lei@redhat.com>

-- 
Ming


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

* Re: PING for Re: bdi: fix use-after-free for dev_name(bdi->dev) v3 (resend)
  2020-05-07  6:27 ` PING for Re: bdi: fix use-after-free for dev_name(bdi->dev) v3 (resend) Christoph Hellwig
@ 2020-05-07 14:57   ` Jens Axboe
  0 siblings, 0 replies; 13+ messages in thread
From: Jens Axboe @ 2020-05-07 14:57 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: yuyufen, tj, jack, bvanassche, tytso, hdegoede, gregkh,
	linux-block, linux-kernel

On 5/7/20 12:27 AM, Christoph Hellwig wrote:
> On Mon, May 04, 2020 at 02:47:52PM +0200, Christoph Hellwig wrote:
>> Hi Jens,
>>
>> can you pick up this series?
> 
> ping?  Especially as 1-4 fix a kernel crash and should probably be
> 5.7 material.

I've added 1-4 for 5.7, and the rest for 5.8.

-- 
Jens Axboe


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

end of thread, other threads:[~2020-05-07 14:57 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-04 12:47 bdi: fix use-after-free for dev_name(bdi->dev) v3 (resend) Christoph Hellwig
2020-05-04 12:47 ` [PATCH 1/9] vboxsf: don't use the source name in the bdi name Christoph Hellwig
2020-05-04 12:47 ` [PATCH 2/9] bdi: move bdi_dev_name out of line Christoph Hellwig
2020-05-04 12:47 ` [PATCH 3/9] bdi: use bdi_dev_name() to get device name Christoph Hellwig
2020-05-04 12:47 ` [PATCH 4/9] bdi: add a ->dev_name field to struct backing_dev_info Christoph Hellwig
2020-05-04 12:47 ` [PATCH 5/9] driver core: remove device_create_vargs Christoph Hellwig
2020-05-04 12:47 ` [PATCH 6/9] bdi: unexport bdi_register_va Christoph Hellwig
2020-05-04 12:47 ` [PATCH 7/9] bdi: remove bdi_register_owner Christoph Hellwig
2020-05-04 12:48 ` [PATCH 8/9] bdi: simplify bdi_alloc Christoph Hellwig
2020-05-04 12:48 ` [PATCH 9/9] bdi: remove the name field in struct backing_dev_info Christoph Hellwig
2020-05-07  6:27 ` PING for Re: bdi: fix use-after-free for dev_name(bdi->dev) v3 (resend) Christoph Hellwig
2020-05-07 14:57   ` Jens Axboe
2020-05-07  7:44 ` Ming Lei

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).