From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E100B3382C7; Sat, 17 Oct 2026 17:07:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792256877; cv=none; b=NWmyiZ9GxQC55MF3G+ZhV8Mwoi7Sb1s3HWKlY9FBUU7C9yqL2MqZcU1VjjXg9HIoo4lKGu4I2EdGW70e5w90P/XBMetnw6sq7OIqDMaNfdA+HADjMWRz81dUbsNhZZ3OusEIoY3hEqOxKJ4xLHbD/EOD8l49dN3O0XtE0Wh3Nu4= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792256877; c=relaxed/simple; bh=RmM++VydgN5/OW6ONRJagGVfgxv2IjsAoWMh26t7bpc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=N68tmsyw1zPDQJyDF5ncHjfxAKLcq7EV+iNh8YVXrKq1td0sE5JKb+4Slbm3kmTpxzOqhuw0ZIGHXfVvnVc2GIbDulCMizA7biSJzQD/aeO7K1O2NBsePJY42iIGO9yXsUYUAiIrZYGGcxnBclJ+EGFRIb7ZFrp23n3eQkDWeDY= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=aXvw2yim; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="aXvw2yim" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 30EAC1F000C4; Sat, 17 Oct 2026 17:07:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1792256875; bh=KQhu7A4t6WI2WGhiBepBZsiQenmJJfeDCA5NDXompr4=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=aXvw2yim/Cna/4UVPeBA+aB5uX+kI/zgYjT05o3vhfUIrR0JtJsNsAR/QUHSUcH7x WK4imTk81vYinZuv5Gb1NpJWFkmsYXw9x7PGSe7Z/oBW13FAE6hC4/hf/sFbt9ntiM USwel/mE/TCx+XgopDF0KJrpOC+MUqYROCF+/s+4= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Chengfeng Ye , Johan Hovold , Sasha Levin , stable@kernel.org Subject: [PATCH 6.6 0379/1674] tty: fix saved termios reset race Date: Sat, 17 Oct 2026 17:44:11 +0200 Message-ID: <20261017160440.842910791@linuxfoundation.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261017160431.119607952@linuxfoundation.org> References: <20261017160431.119607952@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.6-stable review patch. If anyone has any objections, please let me know. ------------------ From: Johan Hovold [ 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. Fixes: 93857edd9829 ("tty: reset termios state on device registration") Reported-by: Chengfeng Ye Link: https://lore.kernel.org/20260926184154.3017929-1-nicoyip.dev@gmail.com Cc: stable@kernel.org # 4.12 Signed-off-by: Johan Hovold Link: https://patch.msgid.link/20260930131845.1809256-1-johan@kernel.org Signed-off-by: Greg Kroah-Hartman [ sashal: Adapted TTY_DRIVER_RESET_SAVED_TERMIOS to the existing macro-based driver flag setup. ] Signed-off-by: Sasha Levin --- 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 | 6 ++++++ 5 files changed, 21 insertions(+), 11 deletions(-) diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c index 526573556cda6..f067f26fefcb3 100644 --- a/drivers/staging/greybus/uart.c +++ b/drivers/staging/greybus/uart.c @@ -954,7 +954,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; diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 6be960c6c6339..84fc068cdd745 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -3273,14 +3273,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); diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 59b039c524413..7c6ea7d1d6d77 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -2145,7 +2145,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", diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index c9f66b7e68757..e2c78e4225707 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -1375,7 +1375,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); diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index b4f99f6a5385a..91aa2d5b15da6 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h @@ -542,6 +542,11 @@ static inline void tty_set_operations(struct tty_driver *driver, * Do not create numbered ``/dev`` nodes. For example, 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 @@ -551,6 +556,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 -- 2.53.0