forked from mirror/openwrt
These formally pending patches were merged into upstream Linux some time ago. Move them to the backports folder and add the kernel version they were added to the file name. Link: https://github.com/openwrt/openwrt/pull/21366 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
73 lines
2.7 KiB
Diff
73 lines
2.7 KiB
Diff
From c72e455b89f216b43cd0dbb518036ec4c98f5c46 Mon Sep 17 00:00:00 2001
|
|
From: Manuel Fombuena <fombuena@outlook.com>
|
|
Date: Tue, 25 Feb 2025 22:01:02 +0000
|
|
Subject: leds: leds-st1202: Fix NULL pointer access on race condition
|
|
|
|
st1202_dt_init() calls devm_led_classdev_register_ext() before the
|
|
internal data structures are properly set up, so the LEDs become visible
|
|
to user space while being partially initialized, leading to a window
|
|
where trying to access them causes a NULL pointer access.
|
|
|
|
Move devm_led_classdev_register_ext() from DT initialization
|
|
to the end of the probe function when DT and hardware are fully
|
|
initialized and ready to interact with user space.
|
|
|
|
Fixes: 259230378c65 ("leds: Add LED1202 I2C driver")
|
|
Signed-off-by: Manuel Fombuena <fombuena@outlook.com>
|
|
Link: https://lore.kernel.org/r/CWLP123MB54732771AC0CE5491B3C84DCC5C32@CWLP123MB5473.GBRP123.PROD.OUTLOOK.COM
|
|
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
---
|
|
drivers/leds/leds-st1202.c | 21 ++++++++++-----------
|
|
1 file changed, 10 insertions(+), 11 deletions(-)
|
|
|
|
--- a/drivers/leds/leds-st1202.c
|
|
+++ b/drivers/leds/leds-st1202.c
|
|
@@ -261,8 +261,6 @@ static int st1202_dt_init(struct st1202_
|
|
int err, reg;
|
|
|
|
for_each_available_child_of_node_scoped(dev_of_node(dev), child) {
|
|
- struct led_init_data init_data = {};
|
|
-
|
|
err = of_property_read_u32(child, "reg", ®);
|
|
if (err)
|
|
return dev_err_probe(dev, err, "Invalid register\n");
|
|
@@ -276,15 +274,6 @@ static int st1202_dt_init(struct st1202_
|
|
led->led_cdev.pattern_set = st1202_led_pattern_set;
|
|
led->led_cdev.pattern_clear = st1202_led_pattern_clear;
|
|
led->led_cdev.default_trigger = "pattern";
|
|
-
|
|
- init_data.fwnode = led->fwnode;
|
|
- init_data.devicename = "st1202";
|
|
- init_data.default_label = ":";
|
|
-
|
|
- err = devm_led_classdev_register_ext(dev, &led->led_cdev, &init_data);
|
|
- if (err < 0)
|
|
- return dev_err_probe(dev, err, "Failed to register LED class device\n");
|
|
-
|
|
led->led_cdev.brightness_set = st1202_brightness_set;
|
|
led->led_cdev.brightness_get = st1202_brightness_get;
|
|
}
|
|
@@ -368,6 +357,7 @@ static int st1202_probe(struct i2c_clien
|
|
return ret;
|
|
|
|
for (int i = 0; i < ST1202_MAX_LEDS; i++) {
|
|
+ struct led_init_data init_data = {};
|
|
led = &chip->leds[i];
|
|
led->chip = chip;
|
|
led->led_num = i;
|
|
@@ -384,6 +374,15 @@ static int st1202_probe(struct i2c_clien
|
|
if (ret < 0)
|
|
return dev_err_probe(&client->dev, ret,
|
|
"Failed to clear LED pattern\n");
|
|
+
|
|
+ init_data.fwnode = led->fwnode;
|
|
+ init_data.devicename = "st1202";
|
|
+ init_data.default_label = ":";
|
|
+
|
|
+ ret = devm_led_classdev_register_ext(&client->dev, &led->led_cdev, &init_data);
|
|
+ if (ret < 0)
|
|
+ return dev_err_probe(&client->dev, ret,
|
|
+ "Failed to register LED class device\n");
|
|
}
|
|
|
|
return 0;
|