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: Li Lingfeng lilingfeng3@huawei.com --- block/blk-sysfs.c | 4 ++-- block/blk-throttle.c | 2 +- fs/block_dev.c | 6 ++++++ include/linux/blkdev.h | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index 1b00c8f5c9d6..1c4d795bbdc4 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c @@ -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 diff --git a/block/blk-throttle.c b/block/blk-throttle.c index 1c5ac48a9de8..598191286557 100644 --- a/block/blk-throttle.c +++ b/block/blk-throttle.c @@ -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; diff --git a/fs/block_dev.c b/fs/block_dev.c index d8a10f477558..e072d1ef16ef 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -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 diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 41d235ee579a..c848f4205729 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -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 */
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/1958 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/N...
FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/1958 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/N...