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

Guangshuo Li
2026-04-14T11:32:15Z

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,
Guangshuo