aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWolfram Sang <[email protected]>2018-08-28 12:13:47 +0200
committerWim Van Sebroeck <[email protected]>2018-10-02 13:32:24 +0200
commit953b9dd7725bad55a922a35e75bff7bebf7b9978 (patch)
tree21362448aa15c3147f1cb97e5a07863632602e5b
parent3bed02a2966146b5876b366f4489e30af0547c66 (diff)
watchdog: core: fix null pointer dereference when releasing cdev
watchdog_stop() calls watchdog_update_worker() which needs a valid wdd->wd_data pointer. So, when unregistering the cdev, clear the pointers after we call watchdog_stop(), not before. Fixes: bb292ac1c602 ("watchdog: Introduce watchdog_stop_on_unregister helper") Signed-off-by: Wolfram Sang <[email protected]> Reviewed-by: Fabrizio Castro <[email protected]> Reviewed-by: Guenter Roeck <[email protected]> Signed-off-by: Guenter Roeck <[email protected]> Signed-off-by: Wim Van Sebroeck <[email protected]>
-rw-r--r--drivers/watchdog/watchdog_dev.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c
index ffbdc4642ea5..f6c24b22b37c 100644
--- a/drivers/watchdog/watchdog_dev.c
+++ b/drivers/watchdog/watchdog_dev.c
@@ -1019,16 +1019,16 @@ static void watchdog_cdev_unregister(struct watchdog_device *wdd)
old_wd_data = NULL;
}
- mutex_lock(&wd_data->lock);
- wd_data->wdd = NULL;
- wdd->wd_data = NULL;
- mutex_unlock(&wd_data->lock);
-
if (watchdog_active(wdd) &&
test_bit(WDOG_STOP_ON_UNREGISTER, &wdd->status)) {
watchdog_stop(wdd);
}
+ mutex_lock(&wd_data->lock);
+ wd_data->wdd = NULL;
+ wdd->wd_data = NULL;
+ mutex_unlock(&wd_data->lock);
+
hrtimer_cancel(&wd_data->timer);
kthread_cancel_work_sync(&wd_data->work);