block: fix error unwinding in device_add_disk
[ Upstream commit99d8690aae
] One device_add is called disk->ev will be freed by disk_release, so we should free it twice. Fix this by allocating disk->ev after device_add so that the extra local unwinding can be removed entirely. Based on an earlier patch from Tetsuo Handa. Reported-by: syzbot <syzbot+28a66a9fbc621c939000@syzkaller.appspotmail.com> Tested-by: syzbot <syzbot+28a66a9fbc621c939000@syzkaller.appspotmail.com> Fixes:83cbce9574
("block: add error handling for device_add_disk / add_disk") Signed-off-by: Christoph Hellwig <hch@lst.de> Link: https://lore.kernel.org/r/20211221161851.788424-1-hch@lst.de Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Родитель
6c1d0447bf
Коммит
7be5c25e31
|
@ -432,10 +432,6 @@ int device_add_disk(struct device *parent, struct gendisk *disk,
|
|||
disk->flags |= GENHD_FL_EXT_DEVT;
|
||||
}
|
||||
|
||||
ret = disk_alloc_events(disk);
|
||||
if (ret)
|
||||
goto out_free_ext_minor;
|
||||
|
||||
/* delay uevents, until we scanned partition table */
|
||||
dev_set_uevent_suppress(ddev, 1);
|
||||
|
||||
|
@ -446,7 +442,12 @@ int device_add_disk(struct device *parent, struct gendisk *disk,
|
|||
ddev->devt = MKDEV(disk->major, disk->first_minor);
|
||||
ret = device_add(ddev);
|
||||
if (ret)
|
||||
goto out_disk_release_events;
|
||||
goto out_free_ext_minor;
|
||||
|
||||
ret = disk_alloc_events(disk);
|
||||
if (ret)
|
||||
goto out_device_del;
|
||||
|
||||
if (!sysfs_deprecated) {
|
||||
ret = sysfs_create_link(block_depr, &ddev->kobj,
|
||||
kobject_name(&ddev->kobj));
|
||||
|
@ -534,8 +535,6 @@ out_del_block_link:
|
|||
sysfs_remove_link(block_depr, dev_name(ddev));
|
||||
out_device_del:
|
||||
device_del(ddev);
|
||||
out_disk_release_events:
|
||||
disk_release_events(disk);
|
||||
out_free_ext_minor:
|
||||
if (disk->major == BLOCK_EXT_MAJOR)
|
||||
blk_free_ext_minor(disk->first_minor);
|
||||
|
|
Загрузка…
Ссылка в новой задаче