Re: [PATCH v2] md: fix kobject reference leak in md_import_device()

Su Yue
2026-04-14T14:10:38Z

On Tue 14 Apr 2026 at 19:32, Guangshuo Li
<lgs201920130244@gmail.com> wrote:

> Hi Su,
>
> Thanks for reviewing.
>
> On Tue, 14 Apr 2026 at 09:29, Su Yue <l@damenly.org> wrote:
>> Why not just:
>>
>> out_blkdev_put:
>> kobject_put(&rdev->kobj);
>> fput(rdev->bdev_file);
>> out_clear_rdev:
>> md_rdev_clear(rdev);
>> out_free_rdev:
>> kfree(rdev);
>> return ERR_PTR(err);
>>
>> --
>> Su
>
> I wonder if that ordering might cause a problem.
>
> After kobject_init(&rdev->kobj, &rdev_ktype),
> kobject_put(&rdev->kobj)
> may immediately drop the last reference and run the release
> callback
> from rdev_ktype:
>
> static const struct kobj_type rdev_ktype = {
> .release = rdev_free,
> .sysfs_ops = &rdev_sysfs_ops,
> .default_groups = rdev_default_groups,
> };
>
> static void rdev_free(struct kobject *ko)
> {
> struct md_rdev *rdev = container_of(ko, struct md_rdev,
> kobj);
> kfree(rdev);
> }
>
> So in:
>
> out_blkdev_put:
> kobject_put(&rdev->kobj);
> fput(rdev->bdev_file);
>
> it seems possible that kobject_put() would already free rdev via
> rdev_free(), and then fput(rdev->bdev_file) would dereference
> rdev
> after free.
>
> That was why I changed it to:
>
> out_blkdev_put:
> fput(rdev->bdev_file);
> md_rdev_clear(rdev);
> kobject_put(&rdev->kobj);
> return ERR_PTR(err);
>
> so that the cleanup which still needs rdev is done before
> kobject_put(), and this path returns directly instead of falling
> through to the old kfree(rdev) path.
>
> Please let me know if I overlooked something.
>
Thanks for your detailed explanation. It's totally correct.

--
Su

> Thanks,
> Guangshuo