lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:   Wed, 5 May 2021 09:14:15 +0200
From:   Frieder Schrempf <frieder.schrempf@...tron.de>
To:     Marc Kleine-Budde <mkl@...gutronix.de>,
        Vincent Mailhol <mailhol.vincent@...adoo.fr>,
        Oliver Hartkopp <socketcan@...tkopp.net>,
        Frieder Schrempf <frieder.schrempf@...tron.de>,
        "Gustavo A. R. Silva" <gustavoars@...nel.org>,
        Timo Schlüßler <schluessler@...use.de>,
        Andy Shevchenko <andriy.shevchenko@...ux.intel.com>,
        Tim Harvey <tharvey@...eworks.com>
Cc:     stable@...r.kernel.org, linux-can@...r.kernel.org,
        netdev@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: [PATCH v2] can: mcp251x: Fix resume from sleep before interface was
 brought up

From: Frieder Schrempf <frieder.schrempf@...tron.de>

Since 8ce8c0abcba3 the driver queues work via priv->restart_work when
resuming after suspend, even when the interface was not previously
enabled. This causes a null dereference error as the workqueue is
only allocated and initialized in mcp251x_open().

To fix this we move the workqueue init to mcp251x_can_probe() as
there is no reason to do it later and repeat it whenever
mcp251x_open() is called.

Fixes: 8ce8c0abcba3 ("can: mcp251x: only reset hardware as required")
Cc: stable@...r.kernel.org
Signed-off-by: Frieder Schrempf <frieder.schrempf@...tron.de>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@...ux.intel.com>
---
Changes in v2:
  * Remove the out_clean label in mcp251x_open()
  * Add Andy's R-b tag
  * Add 'From' tag

Hi Marc, I'm sending a v2 mainly because I noticed that v1 is missing
the 'From' tag and as my company's mailserver always sends my name
reversed this causes incorrect author information in git. So if possible
you could fix this up. If this is too much work, just leave it as is.
Thanks! 
---
 drivers/net/can/spi/mcp251x.c | 26 ++++++++++++++------------
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/drivers/net/can/spi/mcp251x.c b/drivers/net/can/spi/mcp251x.c
index a57da43680d8..6f888b771589 100644
--- a/drivers/net/can/spi/mcp251x.c
+++ b/drivers/net/can/spi/mcp251x.c
@@ -956,8 +956,6 @@ static int mcp251x_stop(struct net_device *net)
 
 	priv->force_quit = 1;
 	free_irq(spi->irq, priv);
-	destroy_workqueue(priv->wq);
-	priv->wq = NULL;
 
 	mutex_lock(&priv->mcp_lock);
 
@@ -1224,15 +1222,6 @@ static int mcp251x_open(struct net_device *net)
 		goto out_close;
 	}
 
-	priv->wq = alloc_workqueue("mcp251x_wq", WQ_FREEZABLE | WQ_MEM_RECLAIM,
-				   0);
-	if (!priv->wq) {
-		ret = -ENOMEM;
-		goto out_clean;
-	}
-	INIT_WORK(&priv->tx_work, mcp251x_tx_work_handler);
-	INIT_WORK(&priv->restart_work, mcp251x_restart_work_handler);
-
 	ret = mcp251x_hw_wake(spi);
 	if (ret)
 		goto out_free_wq;
@@ -1252,7 +1241,6 @@ static int mcp251x_open(struct net_device *net)
 
 out_free_wq:
 	destroy_workqueue(priv->wq);
-out_clean:
 	free_irq(spi->irq, priv);
 	mcp251x_hw_sleep(spi);
 out_close:
@@ -1373,6 +1361,15 @@ static int mcp251x_can_probe(struct spi_device *spi)
 	if (ret)
 		goto out_clk;
 
+	priv->wq = alloc_workqueue("mcp251x_wq", WQ_FREEZABLE | WQ_MEM_RECLAIM,
+				   0);
+	if (!priv->wq) {
+		ret = -ENOMEM;
+		goto out_clk;
+	}
+	INIT_WORK(&priv->tx_work, mcp251x_tx_work_handler);
+	INIT_WORK(&priv->restart_work, mcp251x_restart_work_handler);
+
 	priv->spi = spi;
 	mutex_init(&priv->mcp_lock);
 
@@ -1417,6 +1414,8 @@ static int mcp251x_can_probe(struct spi_device *spi)
 	return 0;
 
 error_probe:
+	destroy_workqueue(priv->wq);
+	priv->wq = NULL;
 	mcp251x_power_enable(priv->power, 0);
 
 out_clk:
@@ -1438,6 +1437,9 @@ static int mcp251x_can_remove(struct spi_device *spi)
 
 	mcp251x_power_enable(priv->power, 0);
 
+	destroy_workqueue(priv->wq);
+	priv->wq = NULL;
+
 	clk_disable_unprepare(priv->clk);
 
 	free_candev(net);
-- 
2.25.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ