2021-05-21 20:26:47

by Christophe JAILLET

[permalink] [raw]
Subject: [PATCH] firmware: stratix10-svc: Fix a resource leak in an error handling path

If an error occurs after a successful 'kfifo_alloc()' call, it must be
undone by a corresponding 'kfifo_free()' call, as already done in the
remove function.

While at it, move the 'platform_device_put()' call to this new error
handling path and explicitly return 0 in the success path.

Fixes: b5dc75c915cd ("firmware: stratix10-svc: extend svc to support new RSU features")
Signed-off-by: Christophe JAILLET <[email protected]>
---
drivers/firmware/stratix10-svc.c | 22 +++++++++++++++-------
1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/drivers/firmware/stratix10-svc.c b/drivers/firmware/stratix10-svc.c
index 3aa489dba30a..2a7687911c09 100644
--- a/drivers/firmware/stratix10-svc.c
+++ b/drivers/firmware/stratix10-svc.c
@@ -1034,24 +1034,32 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev)

/* add svc client device(s) */
svc = devm_kzalloc(dev, sizeof(*svc), GFP_KERNEL);
- if (!svc)
- return -ENOMEM;
+ if (!svc) {
+ ret = -ENOMEM;
+ goto err_free_kfifo;
+ }

svc->stratix10_svc_rsu = platform_device_alloc(STRATIX10_RSU, 0);
if (!svc->stratix10_svc_rsu) {
dev_err(dev, "failed to allocate %s device\n", STRATIX10_RSU);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto err_free_kfifo;
}

ret = platform_device_add(svc->stratix10_svc_rsu);
- if (ret) {
- platform_device_put(svc->stratix10_svc_rsu);
- return ret;
- }
+ if (ret)
+ goto err_put_device;
+
dev_set_drvdata(dev, svc);

pr_info("Intel Service Layer Driver Initialized\n");

+ return 0;
+
+err_put_device:
+ platform_device_put(svc->stratix10_svc_rsu);
+err_free_kfifo:
+ kfifo_free(&controller->svc_fifo);
return ret;
}

--
2.30.2


2021-05-27 00:11:55

by Richard Gong

[permalink] [raw]
Subject: Re: [PATCH] firmware: stratix10-svc: Fix a resource leak in an error handling path


Hi Jaillet,

Thanks!

On 5/21/21 1:22 PM, Christophe JAILLET wrote:
> If an error occurs after a successful 'kfifo_alloc()' call, it must be
> undone by a corresponding 'kfifo_free()' call, as already done in the
> remove function.
>
> While at it, move the 'platform_device_put()' call to this new error
> handling path and explicitly return 0 in the success path.
>
> Fixes: b5dc75c915cd ("firmware: stratix10-svc: extend svc to support new RSU features")
> Signed-off-by: Christophe JAILLET <[email protected]>
> ---
> drivers/firmware/stratix10-svc.c | 22 +++++++++++++++-------
> 1 file changed, 15 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/firmware/stratix10-svc.c b/drivers/firmware/stratix10-svc.c
> index 3aa489dba30a..2a7687911c09 100644
> --- a/drivers/firmware/stratix10-svc.c
> +++ b/drivers/firmware/stratix10-svc.c
> @@ -1034,24 +1034,32 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev)
>
> /* add svc client device(s) */
> svc = devm_kzalloc(dev, sizeof(*svc), GFP_KERNEL);
> - if (!svc)
> - return -ENOMEM;
> + if (!svc) {
> + ret = -ENOMEM;
> + goto err_free_kfifo;
> + }
>
> svc->stratix10_svc_rsu = platform_device_alloc(STRATIX10_RSU, 0);
> if (!svc->stratix10_svc_rsu) {
> dev_err(dev, "failed to allocate %s device\n", STRATIX10_RSU);
> - return -ENOMEM;
> + ret = -ENOMEM;
> + goto err_free_kfifo;
> }
>
> ret = platform_device_add(svc->stratix10_svc_rsu);
> - if (ret) {
> - platform_device_put(svc->stratix10_svc_rsu);
> - return ret;
> - }
> + if (ret)
> + goto err_put_device;
> +
> dev_set_drvdata(dev, svc);
>
> pr_info("Intel Service Layer Driver Initialized\n");
>
> + return 0;
> +
> +err_put_device:
> + platform_device_put(svc->stratix10_svc_rsu);
> +err_free_kfifo:
> + kfifo_free(&controller->svc_fifo);

Need for the allocated memory pool as well,
if (ctrl->genpool)
gen_pool_destroy(ctrl->genpool);

Rename err_free_kfifo to include both.

> return ret;
> }
>
>

Regards,
Richard

2021-05-27 10:41:10

by Dan Carpenter

[permalink] [raw]
Subject: Re: [PATCH] firmware: stratix10-svc: Fix a resource leak in an error handling path

On Wed, May 26, 2021 at 02:13:12PM -0500, Richard Gong wrote:
> > dev_set_drvdata(dev, svc);
> > pr_info("Intel Service Layer Driver Initialized\n");
> > + return 0;
> > +
> > +err_put_device:
> > + platform_device_put(svc->stratix10_svc_rsu);
> > +err_free_kfifo:
> > + kfifo_free(&controller->svc_fifo);
>
> Need for the allocated memory pool as well,
> if (ctrl->genpool)
> gen_pool_destroy(ctrl->genpool);
>

Good point, but there is no need to check, the genpool is not optional
and the "if (ctrl->genpool)" condition could be deleted from the remove
function as well.

err_put_device:
platform_device_put(svc->stratix10_svc_rsu);
err_free_kfifo:
kfifo_free(&controller->svc_fifo);
err_destroy_pool:
gen_pool_destroy(genpool);

return ret;

But the other question is what's on with the &svc_ctrl list? I would
have thought that we needed to remove freed controller from the list as
well, but looking at it now I think the list itself should be removed.
I think there can only be one item in the list at a time. So we could
just make the controller pointer a file scope global or we could find
some other way to go from the client pointer to the controller pointer.

regards,
dan carpenter