[PATCH] nvme: Fix memory leak in nvme_init_ctrl error path
Sagi Grimberg
sagi at grimberg.me
Wed May 17 00:08:56 PDT 2023
>> - if (!ctrl->discard_page) {
>> - ret = -ENOMEM;
>> - goto out;
>> - }
>> + if (!ctrl->discard_page)
>> + return -ENOMEM;
>
> Can we please pre-load these cleanups in a separate patch?
OK.
>> -out:
>> - if (ctrl->discard_page)
>> - __free_page(ctrl->discard_page);
>> + ctrl->instance = NVME_CTRL_INSTANCE_UNINITIALIZED;
>> + /* pairs with device_initialize .release method will cleanup */
>> + nvme_put_ctrl(ctrl);
>
> Err, no. We should not go through .release with a partial
> initialization.
But that is already the case, even if nvme_init_ctrl completes,
it can subsequently fail in nvme_init_ctrl_finish() and the
drivers already simply release the final reference on the
device and go through .release on a partly initialized dev.
> Please do proper unwinding before the device
> is added, and make sure everything is in a proper state by the
> time ->release can be called.
I don't see how that is possible.
The reason the .release is used in the patch is because device_add
allocates internal resources that are freed when it is released
(see device_private_init called, which is exactly the memleak
addressed in this patch).
So we can't know from nvme what to unwind. The only alternative
I see is to move device_private_init() from device_add to
device_initialize() and introduce device_uninitialize() to
unwind.
More information about the Linux-nvme
mailing list