There is no deallocation of fmc memory, allocated at ff_dev_create() by kmemdup(), and no check on kmemdup() success.
The patch adds deallocation into ff_dev_release() and adds check on allocation success. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Anton Vasilyev <vasil...@ispras.ru> --- drivers/fmc/fmc-fakedev.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/fmc/fmc-fakedev.c b/drivers/fmc/fmc-fakedev.c index 941d0930969a..ede589f4e8e5 100644 --- a/drivers/fmc/fmc-fakedev.c +++ b/drivers/fmc/fmc-fakedev.c @@ -244,7 +244,10 @@ static struct fmc_operations ff_fmc_operations = { /* This device is kmalloced: release it */ static void ff_dev_release(struct device *dev) { + int i; struct ff_dev *ff = container_of(dev, struct ff_dev, dev); + for (i = 0; i < ff_nr_dev; i++) + kfree(ff->fmc[i]); kfree(ff); } @@ -273,15 +276,17 @@ static struct ff_dev *ff_dev_create(void) ff->dev.release = ff_dev_release; ret = device_register(&ff->dev); - if (ret < 0) { - put_device(&ff->dev); - return ERR_PTR(ret); - } + if (ret < 0) + goto err; /* Create fmc structures that refer to this new "hw" device */ for (i = 0; i < ff_nr_dev; i++) { fmc = kmemdup(&ff_template_fmc, sizeof(ff_template_fmc), GFP_KERNEL); + if (!fmc) { + ret = -ENOMEM; + goto err; + } fmc->hwdev = &ff->dev; fmc->carrier_data = ff; fmc->nr_slots = ff_nr_dev; @@ -294,6 +299,10 @@ static struct ff_dev *ff_dev_create(void) ff_template_fmc.device_id++; } return ff; + +err: + put_device(&ff->dev); + return ERR_PTR(ret); } /* init and exit */ -- 2.18.0