]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blobdiff - queue-6.8/serial-core-clearing-the-circular-buffer-before-nullifying-it.patch
6.8-stable patches
[thirdparty/kernel/stable-queue.git] / queue-6.8 / serial-core-clearing-the-circular-buffer-before-nullifying-it.patch
diff --git a/queue-6.8/serial-core-clearing-the-circular-buffer-before-nullifying-it.patch b/queue-6.8/serial-core-clearing-the-circular-buffer-before-nullifying-it.patch
new file mode 100644 (file)
index 0000000..9658b39
--- /dev/null
@@ -0,0 +1,55 @@
+From 9cf7ea2eeb745213dc2a04103e426b960e807940 Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Date: Thu, 4 Apr 2024 17:59:26 +0300
+Subject: serial: core: Clearing the circular buffer before NULLifying it
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+commit 9cf7ea2eeb745213dc2a04103e426b960e807940 upstream.
+
+The circular buffer is NULLified in uart_tty_port_shutdown()
+under the spin lock. However, the PM or other timer based callbacks
+may still trigger after this event without knowning that buffer pointer
+is not valid. Since the serial code is a bit inconsistent in checking
+the buffer state (some rely on the head-tail positions, some on the
+buffer pointer), it's better to have both aligned, i.e. buffer pointer
+to be NULL and head-tail possitions to be the same, meaning it's empty.
+This will prevent asynchronous calls to dereference NULL pointer as
+reported recently in 8250 case:
+
+  BUG: kernel NULL pointer dereference, address: 00000cf5
+  Workqueue: pm pm_runtime_work
+  EIP: serial8250_tx_chars (drivers/tty/serial/8250/8250_port.c:1809)
+  ...
+  ? serial8250_tx_chars (drivers/tty/serial/8250/8250_port.c:1809)
+  __start_tx (drivers/tty/serial/8250/8250_port.c:1551)
+  serial8250_start_tx (drivers/tty/serial/8250/8250_port.c:1654)
+  serial_port_runtime_suspend (include/linux/serial_core.h:667 drivers/tty/serial/serial_port.c:63)
+  __rpm_callback (drivers/base/power/runtime.c:393)
+  ? serial_port_remove (drivers/tty/serial/serial_port.c:50)
+  rpm_suspend (drivers/base/power/runtime.c:447)
+
+The proposed change will prevent ->start_tx() to be called during
+suspend on shut down port.
+
+Fixes: 43066e32227e ("serial: port: Don't suspend if the port is still busy")
+Cc: stable <stable@kernel.org>
+Reported-by: kernel test robot <oliver.sang@intel.com>
+Closes: https://lore.kernel.org/oe-lkp/202404031607.2e92eebe-lkp@intel.com
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/20240404150034.41648-1-andriy.shevchenko@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/serial_core.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/tty/serial/serial_core.c
++++ b/drivers/tty/serial/serial_core.c
+@@ -1788,6 +1788,7 @@ static void uart_tty_port_shutdown(struc
+        * Free the transmit buffer.
+        */
+       uart_port_lock_irq(uport);
++      uart_circ_clear(&state->xmit);
+       buf = state->xmit.buf;
+       state->xmit.buf = NULL;
+       uart_port_unlock_irq(uport);