Commit e79375c9 authored by Li Lingfeng's avatar Li Lingfeng
Browse files

block: don't get gendisk if queue has not been registered

hulk inclusion
category: bugfix
bugzilla: 189153, https://gitee.com/openeuler/kernel/issues/I7XTQH


CVE: NA

----------------------------------------

Creating and using dm device at same time may trigger null-ptr-deref or
deadlock.
Some resources have not been initialized after calling add_disk in the
process of creating dm device, which means users can get device and use
some uninitialized resources.
Using uninitialized resources may trigger null-ptr-deref directly.
What's more, IO can't be finished by waiting specific resources to be
initialized and the resources can't be initialized since IO is inflight,
which triggers deadlock.

Don't get gendisk if queue has not been registered to fix this.

Signed-off-by: default avatarLi Lingfeng <lilingfeng3@huawei.com>
parent 4a26557b
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -976,7 +976,7 @@ int blk_register_queue(struct gendisk *disk)
	blk_queue_flag_set(QUEUE_FLAG_REGISTERED, q);
	wbt_enable_default(q);
	blk_throtl_register_queue(q);
	blk_queue_flag_set(QUEUE_FLAG_THROTL_INIT_DONE, q);
	blk_queue_flag_set(QUEUE_FLAG_REGISTER_DONE, q);

	/* Now everything is ready and send out KOBJ_ADD uevent */
	kobject_uevent(&q->kobj, KOBJ_ADD);
@@ -1025,7 +1025,7 @@ void blk_unregister_queue(struct gendisk *disk)
	if (!test_bit(QUEUE_FLAG_REGISTERED, &q->queue_flags))
		return;

	blk_queue_flag_clear(QUEUE_FLAG_THROTL_INIT_DONE, q);
	blk_queue_flag_clear(QUEUE_FLAG_REGISTER_DONE, q);
	/*
	 * Since sysfs_remove_dir() prevents adding new directory entries
	 * before removal of existing entries starts, protect against
+1 −1
Original line number Diff line number Diff line
@@ -1493,7 +1493,7 @@ static void tg_conf_updated(struct throtl_grp *tg, u64 *old_limits, bool global)

static inline int throtl_check_init_done(struct request_queue *q)
{
	if (test_bit(QUEUE_FLAG_THROTL_INIT_DONE, &q->queue_flags))
	if (test_bit(QUEUE_FLAG_REGISTER_DONE, &q->queue_flags))
		return 0;

	return blk_queue_dying(q) ? -ENODEV : -EBUSY;
+6 −0
Original line number Diff line number Diff line
@@ -1173,6 +1173,12 @@ static struct gendisk *bdev_get_gendisk(struct block_device *bdev, int *partno)

	if (!disk)
		return NULL;

	if (!test_bit(QUEUE_FLAG_REGISTER_DONE, &disk->queue->queue_flags)) {
		put_disk_and_module(disk);
		return NULL;
	}

	/*
	 * Now that we hold gendisk reference we make sure bdev we looked up is
	 * not stale. If it is, it means device got removed and created before
+1 −1
Original line number Diff line number Diff line
@@ -713,7 +713,7 @@ struct request_queue {
#define QUEUE_FLAG_NOMERGES     5	/* disable merge attempts */
#define QUEUE_FLAG_SAME_COMP	6	/* complete on same CPU-group */
#define QUEUE_FLAG_FAIL_IO	7	/* fake timeout */
#define QUEUE_FLAG_THROTL_INIT_DONE 8	/* io throttle can be online */
#define QUEUE_FLAG_REGISTER_DONE 8	/* blkdev can be opened */
#define QUEUE_FLAG_NONROT	9	/* non-rotational device (SSD) */
#define QUEUE_FLAG_VIRT        QUEUE_FLAG_NONROT /* paravirt device */
#define QUEUE_FLAG_IO_STAT     10	/* do IO stats */