Commit a94c8cd5 authored by Michal Kazior's avatar Michal Kazior Committed by Stefan Bader

leds: lp55xx: fix null deref on firmware load failure

BugLink: https://bugs.launchpad.net/bugs/1828420

[ Upstream commit 5ddb0869 ]

I've stumbled upon a kernel crash and the logs
pointed me towards the lp5562 driver:

> <4>[306013.841294] lp5562 0-0030: Direct firmware load for lp5562 failed with error -2
> <4>[306013.894990] lp5562 0-0030: Falling back to user helper
> ...
> <3>[306073.924886] lp5562 0-0030: firmware request failed
> <1>[306073.939456] Unable to handle kernel NULL pointer dereference at virtual address 00000000
> <4>[306074.251011] PC is at _raw_spin_lock+0x1c/0x58
> <4>[306074.255539] LR is at release_firmware+0x6c/0x138
> ...

After taking a look I noticed firmware_release()
could be called with either NULL or a dangling
pointer.

Fixes: 10c06d17 ("leds-lp55xx: support firmware interface")
Signed-off-by: default avatarMichal Kazior <michal@plume.com>
Signed-off-by: default avatarJacek Anaszewski <jacek.anaszewski@gmail.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarKleber Sacilotto de Souza <kleber.souza@canonical.com>
Signed-off-by: default avatarStefan Bader <stefan.bader@canonical.com>
parent 28507838
...@@ -200,7 +200,7 @@ static void lp55xx_firmware_loaded(const struct firmware *fw, void *context) ...@@ -200,7 +200,7 @@ static void lp55xx_firmware_loaded(const struct firmware *fw, void *context)
if (!fw) { if (!fw) {
dev_err(dev, "firmware request failed\n"); dev_err(dev, "firmware request failed\n");
goto out; return;
} }
/* handling firmware data is chip dependent */ /* handling firmware data is chip dependent */
...@@ -213,9 +213,9 @@ static void lp55xx_firmware_loaded(const struct firmware *fw, void *context) ...@@ -213,9 +213,9 @@ static void lp55xx_firmware_loaded(const struct firmware *fw, void *context)
mutex_unlock(&chip->lock); mutex_unlock(&chip->lock);
out:
/* firmware should be released for other channel use */ /* firmware should be released for other channel use */
release_firmware(chip->fw); release_firmware(chip->fw);
chip->fw = NULL;
} }
static int lp55xx_request_firmware(struct lp55xx_chip *chip) static int lp55xx_request_firmware(struct lp55xx_chip *chip)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment