diff mbox series

net: Fix memory corruption in eth_halt() if the stop handler frees the priv member

Message ID 20221212204411.2247170-1-bero@baylibre.com
State Superseded
Delegated to: Tom Rini
Headers show
Series net: Fix memory corruption in eth_halt() if the stop handler frees the priv member | expand

Commit Message

Bernhard Rosenkränzer Dec. 12, 2022, 8:44 p.m. UTC
Calling eth_halt() could result in memory corruption if the stop()
handler frees or modifies the priv member.

A stored value of dev_get_uclass_priv() is assumed to remain valid
after the stop() handler has been called, which is not always the
case (e.g. rndis over usb gadget).

Re-check the priv pointer after calling the stop() handler.

Signed-off-by: Bernhard Rosenkränzer <bero@baylibre.com>
---
 net/eth-uclass.c | 5 +++++
 1 file changed, 5 insertions(+)

Comments

Fabio Estevam Dec. 12, 2022, 9:19 p.m. UTC | #1
Hi Bernhard,

On Mon, Dec 12, 2022 at 6:12 PM Bernhard Rosenkränzer <bero@baylibre.com> wrote:
>
> Calling eth_halt() could result in memory corruption if the stop()
> handler frees or modifies the priv member.
>
> A stored value of dev_get_uclass_priv() is assumed to remain valid
> after the stop() handler has been called, which is not always the
> case (e.g. rndis over usb gadget).
>
> Re-check the priv pointer after calling the stop() handler.
>
> Signed-off-by: Bernhard Rosenkränzer <bero@baylibre.com>
> ---
>  net/eth-uclass.c | 5 +++++
>  1 file changed, 5 insertions(+)
>
> diff --git a/net/eth-uclass.c b/net/eth-uclass.c
> index f41da4b37b..410f3310c7 100644
> --- a/net/eth-uclass.c
> +++ b/net/eth-uclass.c
> @@ -343,6 +343,11 @@ void eth_halt(void)
>                 return;
>
>         eth_get_ops(current)->stop(current);
> +
> +       priv = dev_get_uclass_priv(current);
> +       if (!priv || !priv->running)
> +               return;
> +

Niel submitted the same fix:
https://lists.denx.de/pipermail/u-boot/2022-December/502055.html
diff mbox series

Patch

diff --git a/net/eth-uclass.c b/net/eth-uclass.c
index f41da4b37b..410f3310c7 100644
--- a/net/eth-uclass.c
+++ b/net/eth-uclass.c
@@ -343,6 +343,11 @@  void eth_halt(void)
 		return;
 
 	eth_get_ops(current)->stop(current);
+
+	priv = dev_get_uclass_priv(current);
+	if (!priv || !priv->running)
+		return;
+
 	priv->state = ETH_STATE_PASSIVE;
 	priv->running = false;
 }