[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20181031231206.29509-22-sashal@kernel.org>
Date: Wed, 31 Oct 2018 19:12:06 -0400
From: Sasha Levin <sashal@...nel.org>
To: stable@...r.kernel.org, linux-kernel@...r.kernel.org
Cc: Alexandre Belloni <alexandre.belloni@...tlin.com>,
Lee Jones <lee.jones@...aro.org>,
Sasha Levin <sashal@...nel.org>
Subject: [PATCH AUTOSEL 3.18 22/22] mfd: menelaus: Fix possible race condition and leak
From: Alexandre Belloni <alexandre.belloni@...tlin.com>
[ Upstream commit 9612f8f503804d2fd2f63aa6ba1e58bba4612d96 ]
The IRQ work is added 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 calling menelaus_add_irq_work.
Also, this solves a possible leak as the RTC is never released.
Signed-off-by: Alexandre Belloni <alexandre.belloni@...tlin.com>
Signed-off-by: Lee Jones <lee.jones@...aro.org>
Signed-off-by: Sasha Levin <sashal@...nel.org>
---
drivers/mfd/menelaus.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index 9f01aef539dd..8fcb503daae1 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -1121,6 +1121,7 @@ static void menelaus_rtc_alarm_work(struct menelaus_chip *m)
static inline void menelaus_rtc_init(struct menelaus_chip *m)
{
int alarm = (m->client->irq > 0);
+ int err;
/* assume 32KDETEN pin is pulled high */
if (!(menelaus_read_reg(MENELAUS_OSC_CTRL) & 0x80)) {
@@ -1128,6 +1129,12 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
return;
}
+ m->rtc = devm_rtc_allocate_device(&m->client->dev);
+ if (IS_ERR(m->rtc))
+ return;
+
+ m->rtc->ops = &menelaus_rtc_ops;
+
/* support RTC alarm; it can issue wakeups */
if (alarm) {
if (menelaus_add_irq_work(MENELAUS_RTCALM_IRQ,
@@ -1152,10 +1159,8 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m)
menelaus_write_reg(MENELAUS_RTC_CTRL, m->rtc_control);
}
- m->rtc = rtc_device_register(DRIVER_NAME,
- &m->client->dev,
- &menelaus_rtc_ops, THIS_MODULE);
- if (IS_ERR(m->rtc)) {
+ err = rtc_register_device(m->rtc);
+ if (err) {
if (alarm) {
menelaus_remove_irq_work(MENELAUS_RTCALM_IRQ);
device_init_wakeup(&m->client->dev, 0);
--
2.17.1
Powered by blists - more mailing lists