[PATCH net-next] r8169: keep LED device name valid after setup

Zhixing Chen <[email protected]>
Newsgroups gmane.linux.network
Message-ID <[email protected]>
rtl8168_setup_ldev() and rtl8125_setup_led_ldev() build the LED device
name in a stack buffer and assign it to led_cdev->name.

The LED class device registration path reads led_cdev->name after it has
been assigned, and struct led_classdev stores the name as part of the LED
class device state. Do not keep a pointer to a setup function's stack
buffer there.

Store the name in struct r8169_led_classdev instead, so it remains valid
for the lifetime of the LED class device.

Signed-off-by: Zhixing Chen <[email protected]>
---

I noticed this while reviewing the r8169 driver code. The LED name is
stored in led_cdev->name, but the current buffer lifetime does not match
the LED class device lifetime.

I have not seen a crash from this, but led_cdev->name points to a stack
buffer after setup returns. Storing the name in the per-LED private object
keeps the pointer lifetime aligned with the LED class device.

---
 drivers/net/ethernet/realtek/r8169_leds.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/realtek/r8169_leds.c b/drivers/net/ethernet/realtek/r8169_leds.c
index 1999e81f0bca..5a2067be3095 100644
--- a/drivers/net/ethernet/realtek/r8169_leds.c
+++ b/drivers/net/ethernet/realtek/r8169_leds.c
@@ -31,6 +31,7 @@ struct r8169_led_classdev {
 	struct led_classdev led;
 	struct net_device *ndev;
 	int index;
+	char name[LED_MAX_NAME_SIZE];
 };
 
 #define lcdev_to_r8169_ldev(lcdev) container_of(lcdev, struct r8169_led_classdev, led)
@@ -131,13 +132,12 @@ static void rtl8168_setup_ldev(struct r8169_led_classdev *ldev,
 {
 	struct rtl8169_private *tp = netdev_priv(ndev);
 	struct led_classdev *led_cdev = &ldev->led;
-	char led_name[LED_MAX_NAME_SIZE];
 
 	ldev->ndev = ndev;
 	ldev->index = index;
 
-	r8169_get_led_name(tp, index, led_name, LED_MAX_NAME_SIZE);
-	led_cdev->name = led_name;
+	r8169_get_led_name(tp, index, ldev->name, sizeof(ldev->name));
+	led_cdev->name = ldev->name;
 	led_cdev->hw_control_trigger = "netdev";
 	led_cdev->flags |= LED_RETAIN_AT_SHUTDOWN;
 	led_cdev->hw_control_is_supported = rtl8168_led_hw_control_is_supported;
@@ -230,13 +230,12 @@ static void rtl8125_setup_led_ldev(struct r8169_led_classdev *ldev,
 {
 	struct rtl8169_private *tp = netdev_priv(ndev);
 	struct led_classdev *led_cdev = &ldev->led;
-	char led_name[LED_MAX_NAME_SIZE];
 
 	ldev->ndev = ndev;
 	ldev->index = index;
 
-	r8169_get_led_name(tp, index, led_name, LED_MAX_NAME_SIZE);
-	led_cdev->name = led_name;
+	r8169_get_led_name(tp, index, ldev->name, sizeof(ldev->name));
+	led_cdev->name = ldev->name;
 	led_cdev->hw_control_trigger = "netdev";
 	led_cdev->flags |= LED_RETAIN_AT_SHUTDOWN;
 	led_cdev->hw_control_is_supported = rtl8125_led_hw_control_is_supported;

base-commit: f6057f06ef7afa9893ed33603f7917fa39d237b5
-- 
2.34.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.