12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455 |
- From 12ce20e02e532f101b725d71c52a36c5cc8ad1e6 Mon Sep 17 00:00:00 2001
- From: Christian Marangi <[email protected]>
- Date: Sun, 4 Feb 2024 00:54:01 +0100
- Subject: [PATCH] leds: trigger: netdev: Fix kernel panic on interface rename
- trig notify
- Commit d5e01266e7f5 ("leds: trigger: netdev: add additional specific link
- speed mode") in the various changes, reworked the way to set the LINKUP
- mode in commit cee4bd16c319 ("leds: trigger: netdev: Recheck
- NETDEV_LED_MODE_LINKUP on dev rename") and moved it to a generic function.
- This changed the logic where, in the previous implementation the dev
- from the trigger event was used to check if the carrier was ok, but in
- the new implementation with the generic function, the dev in
- trigger_data is used instead.
- This is problematic and cause a possible kernel panic due to the fact
- that the dev in the trigger_data still reference the old one as the
- new one (passed from the trigger event) still has to be hold and saved
- in the trigger_data struct (done in the NETDEV_REGISTER case).
- On calling of get_device_state(), an invalid net_dev is used and this
- cause a kernel panic.
- To handle this correctly, move the call to get_device_state() after the
- new net_dev is correctly set in trigger_data (in the NETDEV_REGISTER
- case) and correctly parse the new dev.
- Fixes: d5e01266e7f5 ("leds: trigger: netdev: add additional specific link speed mode")
- Cc: [email protected]
- Signed-off-by: Christian Marangi <[email protected]>
- Reviewed-by: Andrew Lunn <[email protected]>
- Link: https://lore.kernel.org/r/[email protected]
- Signed-off-by: Lee Jones <[email protected]>
- ---
- drivers/leds/trigger/ledtrig-netdev.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
- --- a/drivers/leds/trigger/ledtrig-netdev.c
- +++ b/drivers/leds/trigger/ledtrig-netdev.c
- @@ -489,12 +489,12 @@ static int netdev_trig_notify(struct not
- trigger_data->duplex = DUPLEX_UNKNOWN;
- switch (evt) {
- case NETDEV_CHANGENAME:
- - get_device_state(trigger_data);
- - fallthrough;
- case NETDEV_REGISTER:
- dev_put(trigger_data->net_dev);
- dev_hold(dev);
- trigger_data->net_dev = dev;
- + if (evt == NETDEV_CHANGENAME)
- + get_device_state(trigger_data);
- break;
- case NETDEV_UNREGISTER:
- dev_put(trigger_data->net_dev);
|