linux-can.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 6.0 070/157] can: can327: flush TX_work on ldisc .close()
       [not found] <20221212130934.337225088@linuxfoundation.org>
@ 2022-12-12 13:16 ` Greg Kroah-Hartman
  2022-12-12 21:11   ` patchwork-bot+netdevbpf
  2022-12-12 13:16 ` [PATCH 6.0 071/157] can: slcan: fix freed work crash Greg Kroah-Hartman
  1 sibling, 1 reply; 3+ messages in thread
From: Greg Kroah-Hartman @ 2022-12-12 13:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Jiri Slaby (SUSE),
	Max Staudt, Wolfgang Grandegger, Marc Kleine-Budde,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	linux-can, netdev

From: Max Staudt <max@enpas.org>

commit f4a4d121ebecaa6f396f21745ce97de014281ccc upstream.

Additionally, remove it from .ndo_stop().

This ensures that the worker is not called after being freed, and that
the UART TX queue remains active to send final commands when the
netdev is stopped.

Thanks to Jiri Slaby for finding this in slcan:

  https://lore.kernel.org/linux-can/20221201073426.17328-1-jirislaby@kernel.org/

A variant of this patch for slcan, with the flush in .ndo_stop() still
present, has been tested successfully on physical hardware:

  https://bugzilla.suse.com/show_bug.cgi?id=1205597

Fixes: 43da2f07622f ("can: can327: CAN/ldisc driver for ELM327 based OBD-II adapters")
Cc: "Jiri Slaby (SUSE)" <jirislaby@kernel.org>
Cc: Max Staudt <max@enpas.org>
Cc: Wolfgang Grandegger <wg@grandegger.com>
Cc: Marc Kleine-Budde <mkl@pengutronix.de>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: linux-can@vger.kernel.org
Cc: netdev@vger.kernel.org
Cc: stable@vger.kernel.org
Signed-off-by: Max Staudt <max@enpas.org>
Link: https://lore.kernel.org/all/20221202160148.282564-1-max@enpas.org
Cc: stable@vger.kernel.org
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/can/can327.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/drivers/net/can/can327.c b/drivers/net/can/can327.c
index ed3d0b8989a0..dc7192ecb001 100644
--- a/drivers/net/can/can327.c
+++ b/drivers/net/can/can327.c
@@ -796,9 +796,9 @@ static int can327_netdev_close(struct net_device *dev)
 
 	netif_stop_queue(dev);
 
-	/* Give UART one final chance to flush. */
-	clear_bit(TTY_DO_WRITE_WAKEUP, &elm->tty->flags);
-	flush_work(&elm->tx_work);
+	/* We don't flush the UART TX queue here, as we want final stop
+	 * commands (like the above dummy char) to be flushed out.
+	 */
 
 	can_rx_offload_disable(&elm->offload);
 	elm->can.state = CAN_STATE_STOPPED;
@@ -1069,12 +1069,15 @@ static void can327_ldisc_close(struct tty_struct *tty)
 {
 	struct can327 *elm = (struct can327 *)tty->disc_data;
 
-	/* unregister_netdev() calls .ndo_stop() so we don't have to.
-	 * Our .ndo_stop() also flushes the TTY write wakeup handler,
-	 * so we can safely set elm->tty = NULL after this.
-	 */
+	/* unregister_netdev() calls .ndo_stop() so we don't have to. */
 	unregister_candev(elm->dev);
 
+	/* Give UART one final chance to flush.
+	 * No need to clear TTY_DO_WRITE_WAKEUP since .write_wakeup() is
+	 * serialised against .close() and will not be called once we return.
+	 */
+	flush_work(&elm->tx_work);
+
 	/* Mark channel as dead */
 	spin_lock_bh(&elm->lock);
 	tty->disc_data = NULL;
-- 
2.38.1




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

* [PATCH 6.0 071/157] can: slcan: fix freed work crash
       [not found] <20221212130934.337225088@linuxfoundation.org>
  2022-12-12 13:16 ` [PATCH 6.0 070/157] can: can327: flush TX_work on ldisc .close() Greg Kroah-Hartman
@ 2022-12-12 13:16 ` Greg Kroah-Hartman
  1 sibling, 0 replies; 3+ messages in thread
From: Greg Kroah-Hartman @ 2022-12-12 13:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Richard Palethorpe, Petr Vorel,
	Dario Binacchi, Wolfgang Grandegger, Marc Kleine-Budde,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	linux-can, netdev, Max Staudt, Jiri Slaby (SUSE)

From: Jiri Slaby (SUSE) <jirislaby@kernel.org>

commit fb855e9f3b6b42c72af3f1eb0b288998fe0d5ebb upstream.

The LTP test pty03 is causing a crash in slcan:
  BUG: kernel NULL pointer dereference, address: 0000000000000008
  #PF: supervisor read access in kernel mode
  #PF: error_code(0x0000) - not-present page
  PGD 0 P4D 0
  Oops: 0000 [#1] PREEMPT SMP NOPTI
  CPU: 0 PID: 348 Comm: kworker/0:3 Not tainted 6.0.8-1-default #1 openSUSE Tumbleweed 9d20364b934f5aab0a9bdf84e8f45cfdfae39dab
  Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.15.0-0-g2dd4b9b-rebuilt.opensuse.org 04/01/2014
  Workqueue:  0x0 (events)
  RIP: 0010:process_one_work (/home/rich/kernel/linux/kernel/workqueue.c:706 /home/rich/kernel/linux/kernel/workqueue.c:2185)
  Code: 49 89 ff 41 56 41 55 41 54 55 53 48 89 f3 48 83 ec 10 48 8b 06 48 8b 6f 48 49 89 c4 45 30 e4 a8 04 b8 00 00 00 00 4c 0f 44 e0 <49> 8b 44 24 08 44 8b a8 00 01 00 00 41 83 e5 20 f6 45 10 04 75 0e
  RSP: 0018:ffffaf7b40f47e98 EFLAGS: 00010046
  RAX: 0000000000000000 RBX: ffff9d644e1b8b48 RCX: ffff9d649e439968
  RDX: 00000000ffff8455 RSI: ffff9d644e1b8b48 RDI: ffff9d64764aa6c0
  RBP: ffff9d649e4335c0 R08: 0000000000000c00 R09: ffff9d64764aa734
  R10: 0000000000000007 R11: 0000000000000001 R12: 0000000000000000
  R13: ffff9d649e4335e8 R14: ffff9d64490da780 R15: ffff9d64764aa6c0
  FS:  0000000000000000(0000) GS:ffff9d649e400000(0000) knlGS:0000000000000000
  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
  CR2: 0000000000000008 CR3: 0000000036424000 CR4: 00000000000006f0
  Call Trace:
   <TASK>
  worker_thread (/home/rich/kernel/linux/kernel/workqueue.c:2436)
  kthread (/home/rich/kernel/linux/kernel/kthread.c:376)
  ret_from_fork (/home/rich/kernel/linux/arch/x86/entry/entry_64.S:312)

Apparently, the slcan's tx_work is freed while being scheduled. While
slcan_netdev_close() (netdev side) calls flush_work(&sl->tx_work),
slcan_close() (tty side) does not. So when the netdev is never set UP,
but the tty is stuffed with bytes and forced to wakeup write, the work
is scheduled, but never flushed.

So add an additional flush_work() to slcan_close() to be sure the work
is flushed under all circumstances.

The Fixes commit below moved flush_work() from slcan_close() to
slcan_netdev_close(). What was the rationale behind it? Maybe we can
drop the one in slcan_netdev_close()?

I see the same pattern in can327. So it perhaps needs the very same fix.

Fixes: cfcb4465e992 ("can: slcan: remove legacy infrastructure")
Link: https://bugzilla.suse.com/show_bug.cgi?id=1205597
Reported-by: Richard Palethorpe <richard.palethorpe@suse.com>
Tested-by: Petr Vorel <petr.vorel@suse.com>
Cc: Dario Binacchi <dario.binacchi@amarulasolutions.com>
Cc: Wolfgang Grandegger <wg@grandegger.com>
Cc: Marc Kleine-Budde <mkl@pengutronix.de>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: linux-can@vger.kernel.org
Cc: netdev@vger.kernel.org
Cc: stable@vger.kernel.org
Cc: Max Staudt <max@enpas.org>
Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
Reviewed-by: Max Staudt <max@enpas.org>
Link: https://lore.kernel.org/all/20221201073426.17328-1-jirislaby@kernel.org
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/can/slcan/slcan-core.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/net/can/slcan/slcan-core.c b/drivers/net/can/slcan/slcan-core.c
index fbb34139daa1..f4db77007c13 100644
--- a/drivers/net/can/slcan/slcan-core.c
+++ b/drivers/net/can/slcan/slcan-core.c
@@ -864,12 +864,14 @@ static void slcan_close(struct tty_struct *tty)
 {
 	struct slcan *sl = (struct slcan *)tty->disc_data;
 
-	/* unregister_netdev() calls .ndo_stop() so we don't have to.
-	 * Our .ndo_stop() also flushes the TTY write wakeup handler,
-	 * so we can safely set sl->tty = NULL after this.
-	 */
 	unregister_candev(sl->dev);
 
+	/*
+	 * The netdev needn't be UP (so .ndo_stop() is not called). Hence make
+	 * sure this is not running before freeing it up.
+	 */
+	flush_work(&sl->tx_work);
+
 	/* Mark channel as dead */
 	spin_lock_bh(&sl->lock);
 	tty->disc_data = NULL;
-- 
2.38.1




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

* Re: [PATCH 6.0 070/157] can: can327: flush TX_work on ldisc .close()
  2022-12-12 13:16 ` [PATCH 6.0 070/157] can: can327: flush TX_work on ldisc .close() Greg Kroah-Hartman
@ 2022-12-12 21:11   ` patchwork-bot+netdevbpf
  0 siblings, 0 replies; 3+ messages in thread
From: patchwork-bot+netdevbpf @ 2022-12-12 21:11 UTC (permalink / raw)
  To: Greg KH
  Cc: stable, patches, jirislaby, max, wg, mkl, davem, edumazet, kuba,
	pabeni, linux-can, netdev

Hello:

This series was applied to bpf/bpf-next.git (master)
by Marc Kleine-Budde <mkl@pengutronix.de>:

On Mon, 12 Dec 2022 14:16:58 +0100 you wrote:
> From: Max Staudt <max@enpas.org>
> 
> commit f4a4d121ebecaa6f396f21745ce97de014281ccc upstream.
> 
> Additionally, remove it from .ndo_stop().
> 
> This ensures that the worker is not called after being freed, and that
> the UART TX queue remains active to send final commands when the
> netdev is stopped.
> 
> [...]

Here is the summary with links:
  - [6.0,070/157] can: can327: flush TX_work on ldisc .close()
    https://git.kernel.org/bpf/bpf-next/c/f4a4d121ebec
  - [6.0,071/157] can: slcan: fix freed work crash
    https://git.kernel.org/bpf/bpf-next/c/fb855e9f3b6b

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



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

end of thread, other threads:[~2022-12-12 21:11 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20221212130934.337225088@linuxfoundation.org>
2022-12-12 13:16 ` [PATCH 6.0 070/157] can: can327: flush TX_work on ldisc .close() Greg Kroah-Hartman
2022-12-12 21:11   ` patchwork-bot+netdevbpf
2022-12-12 13:16 ` [PATCH 6.0 071/157] can: slcan: fix freed work crash Greg Kroah-Hartman

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).