block: fix error unwinding in device_add_disk
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>
This commit is contained in:
parent
37e11c3616
commit
99d8690aae
|
@ -442,10 +442,6 @@ int __must_check device_add_disk(struct device *parent, struct gendisk *disk,
|
|||
disk->first_minor = ret;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
@ -456,7 +452,12 @@ int __must_check 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));
|
||||
|
@ -538,8 +539,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);
|
||||
|
|
Loading…
Reference in New Issue