diff options
author | Alexandre Belloni <alexandre.belloni@bootlin.com> | 2018-05-17 16:18:58 -0400 |
---|---|---|
committer | Alexandre Belloni <alexandre.belloni@bootlin.com> | 2018-05-17 16:23:18 -0400 |
commit | 661eb89a11c5f39249d8d0d50b4e538ef7bdd9d6 (patch) | |
tree | 9c759dbfa77c1ddfdd7952cd1722ee7c62813a40 | |
parent | ba78d51bdf97e67d6ae37075fa34c75068c2938e (diff) |
rtc: 88pm80x: fix possible race condition
The IRQ is requested before the struct rtc is allocated and registered, but
this struct is used in the IRQ handler. This may lead to a NULL pointer
dereference.
Switch to devm_rtc_allocate_device/rtc_register_device to allocate the rtc
before requesting the IRQ.
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
-rw-r--r-- | drivers/rtc/rtc-88pm80x.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/drivers/rtc/rtc-88pm80x.c b/drivers/rtc/rtc-88pm80x.c index f60c0d73c2f3..dae527f8c58e 100644 --- a/drivers/rtc/rtc-88pm80x.c +++ b/drivers/rtc/rtc-88pm80x.c | |||
@@ -290,6 +290,10 @@ static int pm80x_rtc_probe(struct platform_device *pdev) | |||
290 | info->dev = &pdev->dev; | 290 | info->dev = &pdev->dev; |
291 | dev_set_drvdata(&pdev->dev, info); | 291 | dev_set_drvdata(&pdev->dev, info); |
292 | 292 | ||
293 | info->rtc_dev = devm_rtc_allocate_device(&pdev->dev); | ||
294 | if (IS_ERR(info->rtc_dev)) | ||
295 | return PTR_ERR(info->rtc_dev); | ||
296 | |||
293 | ret = pm80x_request_irq(chip, info->irq, rtc_update_handler, | 297 | ret = pm80x_request_irq(chip, info->irq, rtc_update_handler, |
294 | IRQF_ONESHOT, "rtc", info); | 298 | IRQF_ONESHOT, "rtc", info); |
295 | if (ret < 0) { | 299 | if (ret < 0) { |
@@ -298,10 +302,10 @@ static int pm80x_rtc_probe(struct platform_device *pdev) | |||
298 | goto out; | 302 | goto out; |
299 | } | 303 | } |
300 | 304 | ||
301 | info->rtc_dev = devm_rtc_device_register(&pdev->dev, "88pm80x-rtc", | 305 | info->rtc_dev->ops = &pm80x_rtc_ops; |
302 | &pm80x_rtc_ops, THIS_MODULE); | 306 | |
303 | if (IS_ERR(info->rtc_dev)) { | 307 | ret = rtc_register_device(info->rtc_dev); |
304 | ret = PTR_ERR(info->rtc_dev); | 308 | if (ret) { |
305 | dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); | 309 | dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); |
306 | goto out_rtc; | 310 | goto out_rtc; |
307 | } | 311 | } |