FAILED: patch "[PATCH] tty: fix saved termios reset race" failed to apply to 5.15-stable tree
Subsystems (8)
[email protected]
maintainerThe patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y
git checkout FETCH_HEAD
git cherry-pick -x 8df07fe93573e9e548d6645273e9bcb6eb74059e
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026100544-flannels-eclipse-ffc7@gregkh' --subject-prefix 'PATCH 5.15.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 8df07fe93573e9e548d6645273e9bcb6eb74059e Mon Sep 17 00:00:00 2001
From: Johan Hovold <[email protected]>
Date: Wed, 30 Sep 2026 15:18:45 +0200
Subject: [PATCH] tty: fix saved termios reset race
Resetting saved termios state on device registration is needed where a minor number can be reused for an entirely different device and where the old settings may prevent the port from even being opened (e.g. when CLOCAL is not set).
Not all TTY drivers guarantee that the minor number is no longer in use when registering devices however, something which can lead to a use-after-free when closing a TTY (and saving its termios) races with re-registration.
Add a new TTY_DRIVER_RESET_SAVED_TERMIOS flag to request that any saved termios state is reset on registration and only set it for drivers that make sure that the minor number is no longer in use.
drivers/staging/greybus/uart.c +2 -1
@@ -948,7 +948,8 @@ static int gb_tty_init(void)int retval =0 ; gb_tty_driver =tty_alloc_driver (GB_NUM_MINORS ,TTY_DRIVER_REAL_RAW | -TTY_DRIVER_DYNAMIC_DEV ); +TTY_DRIVER_DYNAMIC_DEV | +TTY_DRIVER_RESET_SAVED_TERMIOS );if (IS_ERR (gb_tty_driver)) {pr_err ("Can not allocate tty driver\n" ); retval =PTR_ERR (gb_tty_driver);
drivers/tty/tty_io.c +10 -8
@@ -3256,14 +3256,16 @@ struct device *tty_register_device_attr(struct tty_driver *driver, goto err_put;if (!(driver->flags &TTY_DRIVER_DYNAMIC_ALLOC )) { -/* -* Free any saved termios data so that the termios state is -* reset when reusing a minor number. -*/ - tp = driver->termios[index]; -if (tp) { - driver->termios[index] =NULL ; -kfree (tp); +if (driver->flags &TTY_DRIVER_RESET_SAVED_TERMIOS ) { +/* +* Free any saved termios data so that the termios +* state is reset when reusing a minor number. +*/ + tp = driver->termios[index]; +if (tp) { + driver->termios[index] =NULL ; +kfree (tp); + } } retval =tty_cdev_add (driver, devt, index,1 );
drivers/usb/class/cdc-acm.c +1 -1
@@ -2140,7 +2140,7 @@ static int __init acm_init(void) {int retval; acm_tty_driver =tty_alloc_driver (ACM_TTY_MINORS ,TTY_DRIVER_REAL_RAW | -TTY_DRIVER_DYNAMIC_DEV ); +TTY_DRIVER_DYNAMIC_DEV |TTY_DRIVER_RESET_SAVED_TERMIOS );if (IS_ERR (acm_tty_driver))return PTR_ERR (acm_tty_driver); acm_tty_driver->driver_name = "acm",
drivers/usb/serial/usb-serial.c +2 -1
@@ -1313,7 +1313,8 @@ static int __init usb_serial_init(void)int result; usb_serial_tty_driver =tty_alloc_driver (USB_SERIAL_TTY_MINORS , -TTY_DRIVER_REAL_RAW |TTY_DRIVER_DYNAMIC_DEV ); +TTY_DRIVER_REAL_RAW |TTY_DRIVER_DYNAMIC_DEV | +TTY_DRIVER_RESET_SAVED_TERMIOS );if (IS_ERR (usb_serial_tty_driver))return PTR_ERR (usb_serial_tty_driver);
include/linux/tty_driver.h +6 -0
@@ -73,6 +73,11 @@ struct serial_struct;* @TTY_DRIVER_NO_WORKQUEUE: * Do not create workqueue when tty_register_driver(). Whenever set, flip * buffer workqueue can be set by tty_port_link_wq() for every port. +* +* @TTY_DRIVER_RESET_SAVED_TERMIOS +* Reset any saved termios settings on device registration when reusing a +* minor number. Must only be set by drivers that guarantee that the minor +* number is no longer in use. */ enum tty_driver_flag {TTY_DRIVER_INSTALLED =BIT (0 ),
@@ -84,6 +89,7 @@ enum tty_driver_flag {TTY_DRIVER_DYNAMIC_ALLOC =BIT (6 ),TTY_DRIVER_UNNUMBERED_NODE =BIT (7 ),TTY_DRIVER_NO_WORKQUEUE =BIT (8 ), + TTY_DRIVER_RESET_SAVED_TERMIOS = BIT(9), }; enum tty_driver_type {
Sasha Levin
maintainerPATCH 1/1 tty: fix saved termios reset race
From: Johan Hovold <[email protected]>
[ Upstream commit 8df07fe93573e9e548d6645273e9bcb6eb74059e ]
Resetting saved termios state on device registration is needed where a minor number can be reused for an entirely different device and where the old settings may prevent the port from even being opened (e.g. when CLOCAL is not set).
Not all TTY drivers guarantee that the minor number is no longer in use when registering devices however, something which can lead to a use-after-free when closing a TTY (and saving its termios) races with re-registration.
Add a new TTY_DRIVER_RESET_SAVED_TERMIOS flag to request that any saved termios state is reset on registration and only set it for drivers that make sure that the minor number is no longer in use.
--- drivers/staging/greybus/uart.c | 3 ++- drivers/tty/tty_io.c | 18 ++++++++++-------- drivers/usb/class/cdc-acm.c | 2 +- drivers/usb/serial/usb-serial.c | 3 ++- include/linux/tty_driver.h | 5 +++++ 5 files changed, 20 insertions(+), 11 deletions(-)
drivers/staging/greybus/uart.c +2 -1
@@ -960,7 +960,8 @@ static int gb_tty_init(void) gb_tty_driver->minor_start =0 ; gb_tty_driver->type =TTY_DRIVER_TYPE_SERIAL ; gb_tty_driver->subtype =SERIAL_TYPE_NORMAL ; - gb_tty_driver->flags =TTY_DRIVER_REAL_RAW |TTY_DRIVER_DYNAMIC_DEV ; + gb_tty_driver->flags =TTY_DRIVER_REAL_RAW |TTY_DRIVER_DYNAMIC_DEV | +TTY_DRIVER_RESET_SAVED_TERMIOS ; gb_tty_driver->init_termios = tty_std_termios; gb_tty_driver->init_termios.c_cflag =B9600 |CS8 |CREAD |HUPCL |CLOCAL ;
drivers/tty/tty_io.c +10 -8
@@ -3294,14 +3294,16 @@ struct device *tty_register_device_attr(struct tty_driver *driver, goto err_put;if (!(driver->flags &TTY_DRIVER_DYNAMIC_ALLOC )) { -/* -* Free any saved termios data so that the termios state is -* reset when reusing a minor number. -*/ - tp = driver->termios[index]; -if (tp) { - driver->termios[index] =NULL ; -kfree (tp); +if (driver->flags &TTY_DRIVER_RESET_SAVED_TERMIOS ) { +/* +* Free any saved termios data so that the termios +* state is reset when reusing a minor number. +*/ + tp = driver->termios[index]; +if (tp) { + driver->termios[index] =NULL ; +kfree (tp); + } } retval =tty_cdev_add (driver, devt, index,1 );
drivers/usb/class/cdc-acm.c +1 -1
@@ -2084,7 +2084,7 @@ static int __init acm_init(void) {int retval; acm_tty_driver =tty_alloc_driver (ACM_TTY_MINORS ,TTY_DRIVER_REAL_RAW | -TTY_DRIVER_DYNAMIC_DEV ); +TTY_DRIVER_DYNAMIC_DEV |TTY_DRIVER_RESET_SAVED_TERMIOS );if (IS_ERR (acm_tty_driver))return PTR_ERR (acm_tty_driver); acm_tty_driver->driver_name = "acm",
drivers/usb/serial/usb-serial.c +2 -1
@@ -1325,7 +1325,8 @@ static int __init usb_serial_init(void)int result; usb_serial_tty_driver =tty_alloc_driver (USB_SERIAL_TTY_MINORS , -TTY_DRIVER_REAL_RAW |TTY_DRIVER_DYNAMIC_DEV ); +TTY_DRIVER_REAL_RAW |TTY_DRIVER_DYNAMIC_DEV | +TTY_DRIVER_RESET_SAVED_TERMIOS );if (IS_ERR (usb_serial_tty_driver))return PTR_ERR (usb_serial_tty_driver);
include/linux/tty_driver.h +5 -0
@@ -395,6 +395,10 @@ static inline void tty_set_operations(struct tty_driver *driver,* other words create /dev/ttyprintk and not /dev/ttyprintk0. * Applicable only when a driver for a single tty device is * being allocated. +* +* TTY_DRIVER_RESET_SAVED_TERMIOS -- reset any saved termios settings on +* device registration when reusing a minor number. Must only be set by +* drivers that guarantee that the minor number is no longer in use. */ #define TTY_DRIVER_INSTALLED 0x0001#define TTY_DRIVER_RESET_TERMIOS 0x0002
@@ -404,6 +408,7 @@ static inline void tty_set_operations(struct tty_driver *driver,#define TTY_DRIVER_HARDWARE_BREAK 0x0020#define TTY_DRIVER_DYNAMIC_ALLOC 0x0040#define TTY_DRIVER_UNNUMBERED_NODE 0x0080 +#define TTY_DRIVER_RESET_SAVED_TERMIOS 0x0200/* tty driver types */ #define TTY_DRIVER_TYPE_SYSTEM 0x0001
Signature · 1 line
2.53.0