linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/3] net: phy: leds: Fix truncated LED trigger names and crashes
@ 2017-01-25 10:39 Geert Uytterhoeven
  2017-01-25 10:39 ` [PATCH v2 1/3] net: phy: leds: Clear phy_num_led_triggers on failure to avoid crash Geert Uytterhoeven
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Geert Uytterhoeven @ 2017-01-25 10:39 UTC (permalink / raw)
  To: David S. Miller, Florian Fainelli, Zach Brown, Volodymyr Bendiuga
  Cc: Andrew Lunn, Magnus Öberg, netdev, linux-renesas-soc,
	linux-kernel, Geert Uytterhoeven

	Hi David,

I started seeing crashes during s2ram and poweroff on all my ARM boards,
like:

    Unable to handle kernel NULL pointer dereference at virtual address 00000000
    ...
    [<c04116d4>] (__list_del_entry_valid) from [<c05e8948>] (led_trigger_unregister+0x34/0xcc)
    [<c05e8948>] (led_trigger_unregister) from [<c05336c4>] (phy_led_triggers_unregister+0x28/0x34)
    [<c05336c4>] (phy_led_triggers_unregister) from [<c0531d44>] (phy_detach+0x30/0x74)
    [<c0531d44>] (phy_detach) from [<c0538bdc>] (sh_eth_close+0x64/0x9c)
    [<c0538bdc>] (sh_eth_close) from [<c04d4ce0>] (dpm_run_callback+0x48/0xc8)

or:

    list_del corruption. prev->next should be dede6540, but was 2e323931
    ------------[ cut here ]------------
    kernel BUG at lib/list_debug.c:52!
    ...
    [<c02f6d70>] (__list_del_entry_valid) from [<c0425168>] (led_trigger_unregister+0x34/0xcc)
    [<c0425168>] (led_trigger_unregister) from [<c03a05a0>] (phy_led_triggers_unregister+0x28/0x34)
    [<c03a05a0>] (phy_led_triggers_unregister) from [<c039ec04>] (phy_detach+0x30/0x74)
    [<c039ec04>] (phy_detach) from [<c03a4fc0>] (sh_eth_close+0x6c/0xa4)
    [<c03a4fc0>] (sh_eth_close) from [<c0483234>] (__dev_close_many+0xac/0xd0)

As the only clue was a kernel message like

    sh-eth ee700000.ethernet eth0: No phy led trigger registered for speed(100)

I had to bisected this, leading to commit 4567d686f5c6d955 ("phy:
increase size of MII_BUS_ID_SIZE and bus_id").  Reverting that commit
fixed the issue.

More investigation revealed the crashes are due to the combination of
two things:
  - Truncated LED trigger names, leading to duplicate names, and
    registration failures,
  - Bad error handling in case of registration failures.

Both are fixed by this patch series.

Changes compared to v1:
  - Add Reviewed-by,
  - New patch "net: phy: leds: Break dependency of phy.h on
    phy_led_triggers.h",
  - Drop moving the include of <linux/phy_led_triggers.h>, as
    <linux/phy.h> no longer includes it,
  - #include <linux/phy.h> from <linux/phy_led_triggers.h>.

Thanks!

Geert Uytterhoeven (3):
  net: phy: leds: Clear phy_num_led_triggers on failure to avoid crash
  net: phy: leds: Break dependency of phy.h on phy_led_triggers.h
  net: phy: leds: Fix truncated LED trigger names

 drivers/net/phy/phy.c              | 1 +
 drivers/net/phy/phy_led_triggers.c | 9 +++++++--
 include/linux/phy.h                | 1 -
 include/linux/phy_led_triggers.h   | 4 ++--
 4 files changed, 10 insertions(+), 5 deletions(-)

-- 
1.9.1

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v2 1/3] net: phy: leds: Clear phy_num_led_triggers on failure to avoid crash
  2017-01-25 10:39 [PATCH v2 0/3] net: phy: leds: Fix truncated LED trigger names and crashes Geert Uytterhoeven
@ 2017-01-25 10:39 ` Geert Uytterhoeven
  2017-01-25 10:39 ` [PATCH v2 2/3] net: phy: leds: Break dependency of phy.h on phy_led_triggers.h Geert Uytterhoeven
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 7+ messages in thread
From: Geert Uytterhoeven @ 2017-01-25 10:39 UTC (permalink / raw)
  To: David S. Miller, Florian Fainelli, Zach Brown, Volodymyr Bendiuga
  Cc: Andrew Lunn, Magnus Öberg, netdev, linux-renesas-soc,
	linux-kernel, Geert Uytterhoeven

phy_attach_direct() ignores errors returned by
phy_led_triggers_register(). I think that's OK, as LED triggers can be
considered a non-critical feature.

However, this causes problems later:
  - phy_led_trigger_change_speed() will access the array
    phy_device.phy_led_triggers, which has been freed in the error path
    of phy_led_triggers_register(), which may lead to a crash.

  - phy_led_triggers_unregister() will access the same array, leading to
    crashes during s2ram or poweroff, like:

	Unable to handle kernel NULL pointer dereference at virtual address
	00000000
	...
	[<c04116d4>] (__list_del_entry_valid) from [<c05e8948>] (led_trigger_unregister+0x34/0xcc)
	[<c05e8948>] (led_trigger_unregister) from [<c05336c4>] (phy_led_triggers_unregister+0x28/0x34)
	[<c05336c4>] (phy_led_triggers_unregister) from [<c0531d44>] (phy_detach+0x30/0x74)
	[<c0531d44>] (phy_detach) from [<c0538bdc>] (sh_eth_close+0x64/0x9c)
	[<c0538bdc>] (sh_eth_close) from [<c04d4ce0>] (dpm_run_callback+0x48/0xc8)

    or:

	list_del corruption. prev->next should be dede6540, but was 2e323931
	------------[ cut here ]------------
	kernel BUG at lib/list_debug.c:52!
	...
	[<c02f6d70>] (__list_del_entry_valid) from [<c0425168>] (led_trigger_unregister+0x34/0xcc)
	[<c0425168>] (led_trigger_unregister) from [<c03a05a0>] (phy_led_triggers_unregister+0x28/0x34)
	[<c03a05a0>] (phy_led_triggers_unregister) from [<c039ec04>] (phy_detach+0x30/0x74)
	[<c039ec04>] (phy_detach) from [<c03a4fc0>] (sh_eth_close+0x6c/0xa4)
	[<c03a4fc0>] (sh_eth_close) from [<c0483234>] (__dev_close_many+0xac/0xd0)

To fix this, clear phy_device.phy_num_led_triggers in the error path of
phy_led_triggers_register() fails.

Note that the "No phy led trigger registered for speed" message will
still be printed on link speed changes, which is a good cue that
something went wrong with the LED triggers.

Fixes: 2e0bc452f4721520 ("net: phy: leds: add support for led triggers on phy link state change")
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
---
Alternatively, phy_attach_direct() could consider
phy_led_triggers_register() failures as fatal, so
phy_led_trigger_change_speed() and phy_led_triggers_unregister() are
never called afterwards.

Exposed by commit 4567d686f5c6d955 ("phy: increase size of
MII_BUS_ID_SIZE and bus_id"), which caused duplicate trigger names.

v2:
  - Add Reviewed-by.
---
 drivers/net/phy/phy_led_triggers.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/phy/phy_led_triggers.c b/drivers/net/phy/phy_led_triggers.c
index fa62bdf2f52694de..3f619e7371e97d8a 100644
--- a/drivers/net/phy/phy_led_triggers.c
+++ b/drivers/net/phy/phy_led_triggers.c
@@ -102,8 +102,10 @@ int phy_led_triggers_register(struct phy_device *phy)
 					    sizeof(struct phy_led_trigger) *
 						   phy->phy_num_led_triggers,
 					    GFP_KERNEL);
-	if (!phy->phy_led_triggers)
-		return -ENOMEM;
+	if (!phy->phy_led_triggers) {
+		err = -ENOMEM;
+		goto out_clear;
+	}
 
 	for (i = 0; i < phy->phy_num_led_triggers; i++) {
 		err = phy_led_trigger_register(phy, &phy->phy_led_triggers[i],
@@ -120,6 +122,8 @@ int phy_led_triggers_register(struct phy_device *phy)
 	while (i--)
 		phy_led_trigger_unregister(&phy->phy_led_triggers[i]);
 	devm_kfree(&phy->mdio.dev, phy->phy_led_triggers);
+out_clear:
+	phy->phy_num_led_triggers = 0;
 	return err;
 }
 EXPORT_SYMBOL_GPL(phy_led_triggers_register);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 2/3] net: phy: leds: Break dependency of phy.h on phy_led_triggers.h
  2017-01-25 10:39 [PATCH v2 0/3] net: phy: leds: Fix truncated LED trigger names and crashes Geert Uytterhoeven
  2017-01-25 10:39 ` [PATCH v2 1/3] net: phy: leds: Clear phy_num_led_triggers on failure to avoid crash Geert Uytterhoeven
@ 2017-01-25 10:39 ` Geert Uytterhoeven
  2017-01-25 12:50   ` Andrew Lunn
  2017-01-25 10:39 ` [PATCH v2 3/3] net: phy: leds: Fix truncated LED trigger names Geert Uytterhoeven
  2017-01-25 19:40 ` [PATCH v2 0/3] net: phy: leds: Fix truncated LED trigger names and crashes David Miller
  3 siblings, 1 reply; 7+ messages in thread
From: Geert Uytterhoeven @ 2017-01-25 10:39 UTC (permalink / raw)
  To: David S. Miller, Florian Fainelli, Zach Brown, Volodymyr Bendiuga
  Cc: Andrew Lunn, Magnus Öberg, netdev, linux-renesas-soc,
	linux-kernel, Geert Uytterhoeven

<linux/phy.h> includes <linux/phy_led_triggers.h>, which is not really
needed.  Drop the include from <linux/phy.h>, and add it to all users
that didn't include it explicitly.

Suggested-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v2:
  - New.
---
 drivers/net/phy/phy.c              | 1 +
 drivers/net/phy/phy_led_triggers.c | 1 +
 include/linux/phy.h                | 1 -
 3 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 48da6e93c3f783e0..807abd6e331f8aa2 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -29,6 +29,7 @@
 #include <linux/mii.h>
 #include <linux/ethtool.h>
 #include <linux/phy.h>
+#include <linux/phy_led_triggers.h>
 #include <linux/timer.h>
 #include <linux/workqueue.h>
 #include <linux/mdio.h>
diff --git a/drivers/net/phy/phy_led_triggers.c b/drivers/net/phy/phy_led_triggers.c
index 3f619e7371e97d8a..94ca42e630bbead0 100644
--- a/drivers/net/phy/phy_led_triggers.c
+++ b/drivers/net/phy/phy_led_triggers.c
@@ -12,6 +12,7 @@
  */
 #include <linux/leds.h>
 #include <linux/phy.h>
+#include <linux/phy_led_triggers.h>
 #include <linux/netdevice.h>
 
 static struct phy_led_trigger *phy_speed_to_led_trigger(struct phy_device *phy,
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 5c9d2529685fe215..43474f39ef6523c5 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -25,7 +25,6 @@
 #include <linux/timer.h>
 #include <linux/workqueue.h>
 #include <linux/mod_devicetable.h>
-#include <linux/phy_led_triggers.h>
 
 #include <linux/atomic.h>
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 3/3] net: phy: leds: Fix truncated LED trigger names
  2017-01-25 10:39 [PATCH v2 0/3] net: phy: leds: Fix truncated LED trigger names and crashes Geert Uytterhoeven
  2017-01-25 10:39 ` [PATCH v2 1/3] net: phy: leds: Clear phy_num_led_triggers on failure to avoid crash Geert Uytterhoeven
  2017-01-25 10:39 ` [PATCH v2 2/3] net: phy: leds: Break dependency of phy.h on phy_led_triggers.h Geert Uytterhoeven
@ 2017-01-25 10:39 ` Geert Uytterhoeven
  2017-01-25 12:51   ` Andrew Lunn
  2017-01-25 19:40 ` [PATCH v2 0/3] net: phy: leds: Fix truncated LED trigger names and crashes David Miller
  3 siblings, 1 reply; 7+ messages in thread
From: Geert Uytterhoeven @ 2017-01-25 10:39 UTC (permalink / raw)
  To: David S. Miller, Florian Fainelli, Zach Brown, Volodymyr Bendiuga
  Cc: Andrew Lunn, Magnus Öberg, netdev, linux-renesas-soc,
	linux-kernel, Geert Uytterhoeven

Commit 4567d686f5c6d955 ("phy: increase size of MII_BUS_ID_SIZE and
bus_id") increased the size of MII bus IDs, but forgot to update the
private definition in <linux/phy_led_triggers.h>.
This may cause:
  1. Truncation of LED trigger names,
  2. Duplicate LED trigger names,
  3. Failures registering LED triggers,
  4. Crashes due to bad error handling in the LED trigger failure path.

To fix this, and prevent the definitions going out of sync again in the
future, let the PHY LED trigger code use the existing MII_BUS_ID_SIZE
definition.

Example:
  - Before I had triggers "ee700000.etherne:01:100Mbps" and
    "ee700000.etherne:01:10Mbps",
  - After the increase of MII_BUS_ID_SIZE, both became
    "ee700000.ethernet-ffffffff:01:" => FAIL,
  - Now, the triggers are "ee700000.ethernet-ffffffff:01:100Mbps" and
    "ee700000.ethernet-ffffffff:01:10Mbps", which are unique again.

Fixes: 4567d686f5c6d955 ("phy: increase size of MII_BUS_ID_SIZE and bus_id")
Fixes: 2e0bc452f4721520 ("net: phy: leds: add support for led triggers on phy link state change")
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v2:
  - Drop moving the include of <linux/phy_led_triggers.h>, as
    <linux/phy.h> no longer includes it,
  - #include <linux/phy.h> from <linux/phy_led_triggers.h>.
---
 include/linux/phy_led_triggers.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/linux/phy_led_triggers.h b/include/linux/phy_led_triggers.h
index a2daea0a37d2ae14..b37b05bfd1a6dd8a 100644
--- a/include/linux/phy_led_triggers.h
+++ b/include/linux/phy_led_triggers.h
@@ -18,11 +18,11 @@
 #ifdef CONFIG_LED_TRIGGER_PHY
 
 #include <linux/leds.h>
+#include <linux/phy.h>
 
 #define PHY_LED_TRIGGER_SPEED_SUFFIX_SIZE	10
-#define PHY_MII_BUS_ID_SIZE	(20 - 3)
 
-#define PHY_LINK_LED_TRIGGER_NAME_SIZE (PHY_MII_BUS_ID_SIZE + \
+#define PHY_LINK_LED_TRIGGER_NAME_SIZE (MII_BUS_ID_SIZE + \
 				       FIELD_SIZEOF(struct mdio_device, addr)+\
 				       PHY_LED_TRIGGER_SPEED_SUFFIX_SIZE)
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 2/3] net: phy: leds: Break dependency of phy.h on phy_led_triggers.h
  2017-01-25 10:39 ` [PATCH v2 2/3] net: phy: leds: Break dependency of phy.h on phy_led_triggers.h Geert Uytterhoeven
@ 2017-01-25 12:50   ` Andrew Lunn
  0 siblings, 0 replies; 7+ messages in thread
From: Andrew Lunn @ 2017-01-25 12:50 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: David S. Miller, Florian Fainelli, Zach Brown,
	Volodymyr Bendiuga, Magnus Öberg, netdev, linux-renesas-soc,
	linux-kernel

On Wed, Jan 25, 2017 at 11:39:49AM +0100, Geert Uytterhoeven wrote:
> <linux/phy.h> includes <linux/phy_led_triggers.h>, which is not really
> needed.  Drop the include from <linux/phy.h>, and add it to all users
> that didn't include it explicitly.
> 
> Suggested-by: Andrew Lunn <andrew@lunn.ch>
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 3/3] net: phy: leds: Fix truncated LED trigger names
  2017-01-25 10:39 ` [PATCH v2 3/3] net: phy: leds: Fix truncated LED trigger names Geert Uytterhoeven
@ 2017-01-25 12:51   ` Andrew Lunn
  0 siblings, 0 replies; 7+ messages in thread
From: Andrew Lunn @ 2017-01-25 12:51 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: David S. Miller, Florian Fainelli, Zach Brown,
	Volodymyr Bendiuga, Magnus Öberg, netdev, linux-renesas-soc,
	linux-kernel

On Wed, Jan 25, 2017 at 11:39:50AM +0100, Geert Uytterhoeven wrote:
> Commit 4567d686f5c6d955 ("phy: increase size of MII_BUS_ID_SIZE and
> bus_id") increased the size of MII bus IDs, but forgot to update the
> private definition in <linux/phy_led_triggers.h>.
> This may cause:
>   1. Truncation of LED trigger names,
>   2. Duplicate LED trigger names,
>   3. Failures registering LED triggers,
>   4. Crashes due to bad error handling in the LED trigger failure path.
> 
> To fix this, and prevent the definitions going out of sync again in the
> future, let the PHY LED trigger code use the existing MII_BUS_ID_SIZE
> definition.
> 
> Example:
>   - Before I had triggers "ee700000.etherne:01:100Mbps" and
>     "ee700000.etherne:01:10Mbps",
>   - After the increase of MII_BUS_ID_SIZE, both became
>     "ee700000.ethernet-ffffffff:01:" => FAIL,
>   - Now, the triggers are "ee700000.ethernet-ffffffff:01:100Mbps" and
>     "ee700000.ethernet-ffffffff:01:10Mbps", which are unique again.
> 
> Fixes: 4567d686f5c6d955 ("phy: increase size of MII_BUS_ID_SIZE and bus_id")
> Fixes: 2e0bc452f4721520 ("net: phy: leds: add support for led triggers on phy link state change")
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 0/3] net: phy: leds: Fix truncated LED trigger names and crashes
  2017-01-25 10:39 [PATCH v2 0/3] net: phy: leds: Fix truncated LED trigger names and crashes Geert Uytterhoeven
                   ` (2 preceding siblings ...)
  2017-01-25 10:39 ` [PATCH v2 3/3] net: phy: leds: Fix truncated LED trigger names Geert Uytterhoeven
@ 2017-01-25 19:40 ` David Miller
  3 siblings, 0 replies; 7+ messages in thread
From: David Miller @ 2017-01-25 19:40 UTC (permalink / raw)
  To: geert+renesas
  Cc: f.fainelli, zach.brown, volodymyr.bendiuga, andrew, magnus.oberg,
	netdev, linux-renesas-soc, linux-kernel

From: Geert Uytterhoeven <geert+renesas@glider.be>
Date: Wed, 25 Jan 2017 11:39:47 +0100

> I started seeing crashes during s2ram and poweroff on all my ARM boards,
> like:
> 
>     Unable to handle kernel NULL pointer dereference at virtual address 00000000
>     ...
>     [<c04116d4>] (__list_del_entry_valid) from [<c05e8948>] (led_trigger_unregister+0x34/0xcc)
>     [<c05e8948>] (led_trigger_unregister) from [<c05336c4>] (phy_led_triggers_unregister+0x28/0x34)
>     [<c05336c4>] (phy_led_triggers_unregister) from [<c0531d44>] (phy_detach+0x30/0x74)
>     [<c0531d44>] (phy_detach) from [<c0538bdc>] (sh_eth_close+0x64/0x9c)
>     [<c0538bdc>] (sh_eth_close) from [<c04d4ce0>] (dpm_run_callback+0x48/0xc8)
> 
> or:
> 
>     list_del corruption. prev->next should be dede6540, but was 2e323931
>     ------------[ cut here ]------------
>     kernel BUG at lib/list_debug.c:52!
>     ...
>     [<c02f6d70>] (__list_del_entry_valid) from [<c0425168>] (led_trigger_unregister+0x34/0xcc)
>     [<c0425168>] (led_trigger_unregister) from [<c03a05a0>] (phy_led_triggers_unregister+0x28/0x34)
>     [<c03a05a0>] (phy_led_triggers_unregister) from [<c039ec04>] (phy_detach+0x30/0x74)
>     [<c039ec04>] (phy_detach) from [<c03a4fc0>] (sh_eth_close+0x6c/0xa4)
>     [<c03a4fc0>] (sh_eth_close) from [<c0483234>] (__dev_close_many+0xac/0xd0)
> 
> As the only clue was a kernel message like
> 
>     sh-eth ee700000.ethernet eth0: No phy led trigger registered for speed(100)
> 
> I had to bisected this, leading to commit 4567d686f5c6d955 ("phy:
> increase size of MII_BUS_ID_SIZE and bus_id").  Reverting that commit
> fixed the issue.
> 
> More investigation revealed the crashes are due to the combination of
> two things:
>   - Truncated LED trigger names, leading to duplicate names, and
>     registration failures,
>   - Bad error handling in case of registration failures.
> 
> Both are fixed by this patch series.

Thanks for tracking this down and fixing it.

Series applied, thanks.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2017-01-25 19:40 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-25 10:39 [PATCH v2 0/3] net: phy: leds: Fix truncated LED trigger names and crashes Geert Uytterhoeven
2017-01-25 10:39 ` [PATCH v2 1/3] net: phy: leds: Clear phy_num_led_triggers on failure to avoid crash Geert Uytterhoeven
2017-01-25 10:39 ` [PATCH v2 2/3] net: phy: leds: Break dependency of phy.h on phy_led_triggers.h Geert Uytterhoeven
2017-01-25 12:50   ` Andrew Lunn
2017-01-25 10:39 ` [PATCH v2 3/3] net: phy: leds: Fix truncated LED trigger names Geert Uytterhoeven
2017-01-25 12:51   ` Andrew Lunn
2017-01-25 19:40 ` [PATCH v2 0/3] net: phy: leds: Fix truncated LED trigger names and crashes David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).