summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMadhuparna Bhowmik <madhuparnabhowmik10@gmail.com>2020-08-07 16:59:02 +0530
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-11-10 10:23:54 +0100
commite92df84c4f742231fe718430da7b7dae38fc4289 (patch)
treef4e1fa27aedcf507e3e77f82115d73955d93d6de /drivers
parentff4a198542591c9d9c349c3974c8a3dfbb3c5a93 (diff)
downloadlinux-stable-e92df84c4f742231fe718430da7b7dae38fc4289.tar.gz
linux-stable-e92df84c4f742231fe718430da7b7dae38fc4289.tar.bz2
linux-stable-e92df84c4f742231fe718430da7b7dae38fc4289.zip
drivers: watchdog: rdc321x_wdt: Fix race condition bugs
[ Upstream commit 4b2e7f99cdd314263c9d172bc17193b8b6bba463 ] In rdc321x_wdt_probe(), rdc321x_wdt_device.queue is initialized after misc_register(), hence if ioctl is called before its initialization which can call rdc321x_wdt_start() function, it will see an uninitialized value of rdc321x_wdt_device.queue, hence initialize it before misc_register(). Also, rdc321x_wdt_device.default_ticks is accessed in reset() function called from write callback, thus initialize it before misc_register(). Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Madhuparna Bhowmik <madhuparnabhowmik10@gmail.com> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Link: https://lore.kernel.org/r/20200807112902.28764-1-madhuparnabhowmik10@gmail.com Signed-off-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/watchdog/rdc321x_wdt.c5
1 files changed, 2 insertions, 3 deletions
diff --git a/drivers/watchdog/rdc321x_wdt.c b/drivers/watchdog/rdc321x_wdt.c
index 47a8f1b1087d..4568af9a165b 100644
--- a/drivers/watchdog/rdc321x_wdt.c
+++ b/drivers/watchdog/rdc321x_wdt.c
@@ -244,6 +244,8 @@ static int rdc321x_wdt_probe(struct platform_device *pdev)
rdc321x_wdt_device.sb_pdev = pdata->sb_pdev;
rdc321x_wdt_device.base_reg = r->start;
+ rdc321x_wdt_device.queue = 0;
+ rdc321x_wdt_device.default_ticks = ticks;
err = misc_register(&rdc321x_wdt_misc);
if (err < 0) {
@@ -258,14 +260,11 @@ static int rdc321x_wdt_probe(struct platform_device *pdev)
rdc321x_wdt_device.base_reg, RDC_WDT_RST);
init_completion(&rdc321x_wdt_device.stop);
- rdc321x_wdt_device.queue = 0;
clear_bit(0, &rdc321x_wdt_device.inuse);
setup_timer(&rdc321x_wdt_device.timer, rdc321x_wdt_trigger, 0);
- rdc321x_wdt_device.default_ticks = ticks;
-
dev_info(&pdev->dev, "watchdog init success\n");
return 0;