> On 8/23/20 12:13 AM, Dinghao Liu wrote: > > When misc_register() fails, wd_data will be released by the > > release callback function watchdog_core_data_release(), so > > we don't need to free it again. But when watchdog_kworker is > > NULL, we should free wd_data to prevent memleak. > > > > Fixes: cb36e29bb0e4b ("watchdog: initialize device before misc_register") > > Signed-off-by: Dinghao Liu <dinghao.liu@xxxxxxxxxx> > > --- > > drivers/watchdog/watchdog_dev.c | 5 +++-- > > 1 file changed, 3 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c > > index 6798addabd5a..8ee78e26feb1 100644 > > --- a/drivers/watchdog/watchdog_dev.c > > +++ b/drivers/watchdog/watchdog_dev.c > > @@ -994,8 +994,10 @@ static int watchdog_cdev_register(struct watchdog_device *wdd) > > wd_data->wdd = wdd; > > wdd->wd_data = wd_data; > > > > - if (IS_ERR_OR_NULL(watchdog_kworker)) > > + if (IS_ERR_OR_NULL(watchdog_kworker)) { > > + kfree(wd_data); > > This should be a separate patch, with > > Fixes: 664a39236e718 ("watchdog: Introduce hardware maximum heartbeat in watchdog core") > Thank you for your advice. I will send a new patch to fix this soon. > > return -ENODEV; > > + } > > > > device_initialize(&wd_data->dev); > > wd_data->dev.devt = MKDEV(MAJOR(watchdog_devt), wdd->id); > > @@ -1021,7 +1023,6 @@ static int watchdog_cdev_register(struct watchdog_device *wdd) > > pr_err("%s: a legacy watchdog module is probably present.\n", > > wdd->info->identity); > > old_wd_data = NULL; > > - kfree(wd_data); > > Are you sure about this ? put_device() isn't called on &wd_data->dev > (unlike the code further below). How do you trigger the double free, > or, in other words, how is watchdog_core_data_release() ever called > in this code path ? > > device_initialize() says: > NOTE: Use put_device() to give up your reference instead of freeing > @dev directly once you have called this function. > so it looks like put_device() should be called instead of kfree(). > You are right. The callback will free wd_data->dev after all references have gone away. So we should use put_device() here. I will fix this soon. Regards, Dinghao