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 3B3464FD786; Tue, 13 Oct 2026 12:41:16 +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=1791895277; cv=none; b=mM0OEgC3FW2ZODzJokB7RBs4GbRZGZ1841GGYCZwCMhAF7S5uv0Q5iLJJ88ZpXwckkWhjq+qTxMka3ASGzVWD0CGiD06sNPYPEv0iwKR5sr6cMojKiEY8xpz7BJiR+2UmeG6atew0DrJuaGRmXisL38MhAjj1J1VkqDLCr4oG4s= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791895277; c=relaxed/simple; bh=0rOW9Q75scAa2UmUZ6LdM+cztcJmVIGQf3SdYmblgRk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kKWK2zERY1LkVgmllCYPot7l4x3VyuJGXg3u1HTdfN1SeQ35arjHuuIdtyVHUAT1NQkJA4FhdDzcxMaPvlaIxdqR0KyZMmexRPIlWPwIeiWM6KNMq4DVQlI2c7rFkCs+TGFdRA5E0OSEhrpL+taivB152UG1OZIqJezk4pnO6ds= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=YVJKy3yj; 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="YVJKy3yj" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8EFEA1F000FF; Tue, 13 Oct 2026 12:41:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1791895276; bh=FEXXtbpRHjYUamxgU5loa0Pd0ZUtJsUo/ICYQdI2jB8=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=YVJKy3yjj+W0O/rRZpQoxC2981QGBlnD63zyJxFMnSuZ57x8rZHUlDodfaw53HtG3 Ov3TIEy0Qa9xFGlzN/P/s1+5irAzObsv9IWQSYefu+n5y7edJcctVnJ6442I88Hh+W l5OIFbIXTKMHrGJLpmFcqT8jMaWrvPEa/LbPhC3E= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Alan Stern , Johan Hovold Subject: [PATCH 6.12 218/497] USB: serial: fix driver deregistration order Date: Tue, 13 Oct 2026 13:36:25 +0200 Message-ID: <20261013112913.068899985@linuxfoundation.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261013112907.864180619@linuxfoundation.org> References: <20261013112907.864180619@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.12-stable review patch. If anyone has any objections, please let me know. ------------------ From: Johan Hovold commit 646e5b28b4fdbc1b828a2398d6ced2c1dd308a46 upstream. USB serial driver modules register one driver for the USB bus and one or more drivers for the ports on the USB serial bus. When unloading a driver module, the USB driver must be deregistered before the USB serial bus drivers so that I/O is stopped before unbinding the ports to avoid use-after-free in completion handlers accessing port data. Note that the "new_id" attributes must first be removed to prevent new ids from being added and triggering a probe of the USB driver after it has been deregistered. Fixes: 765e0ba62613 ("usb-serial: new API for driver registration") Cc: stable@vger.kernel.org # 3.4 Cc: Alan Stern Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/bus.c | 4 ++++ drivers/usb/serial/usb-serial.c | 21 ++++++++++++++++++--- include/linux/usb/serial.h | 1 + 3 files changed, 23 insertions(+), 3 deletions(-) --- a/drivers/usb/serial/bus.c +++ b/drivers/usb/serial/bus.c @@ -169,3 +169,7 @@ void usb_serial_bus_deregister(struct us free_dynids(driver); } +void usb_serial_bus_remove_new_id(struct usb_serial_driver *driver) +{ + driver_remove_file(&driver->driver, &driver_attr_new_id); +} --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -1472,7 +1472,7 @@ int __usb_serial_register_drivers(struct { int rc; struct usb_driver *udriver; - struct usb_serial_driver * const *sd; + struct usb_serial_driver * const *sd, * const *s; /* * udriver must be registered before any of the serial drivers, @@ -1525,9 +1525,11 @@ int __usb_serial_register_drivers(struct return 0; err_deregister_drivers: + for (s = serial_drivers; s < sd; ++s) + usb_serial_bus_remove_new_id(*s); + usb_deregister(udriver); while (sd-- > serial_drivers) usb_serial_deregister(*sd); - usb_deregister(udriver); err_free_driver: kfree(udriver); return rc; @@ -1545,10 +1547,23 @@ EXPORT_SYMBOL_GPL(__usb_serial_register_ void usb_serial_deregister_drivers(struct usb_serial_driver *const serial_drivers[]) { struct usb_driver *udriver = (*serial_drivers)->usb_driver; + struct usb_serial_driver * const *sd; + + /* + * udriver must be deregistered before the serial drivers so that + * I/O is stopped before unbinding the ports. + * + * Remove the new_id attributes to prevent ids from being added and + * triggering a probe of udriver after it has been deregistered. + */ + for (sd = serial_drivers; *sd; ++sd) + usb_serial_bus_remove_new_id(*sd); + + usb_deregister(udriver); for (; *serial_drivers; ++serial_drivers) usb_serial_deregister(*serial_drivers); - usb_deregister(udriver); + kfree(udriver); } EXPORT_SYMBOL_GPL(usb_serial_deregister_drivers); --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -380,6 +380,7 @@ void usb_serial_handle_dcd_change(struct int usb_serial_bus_register(struct usb_serial_driver *device); void usb_serial_bus_deregister(struct usb_serial_driver *device); +void usb_serial_bus_remove_new_id(struct usb_serial_driver *driver); extern const struct bus_type usb_serial_bus_type; extern struct tty_driver *usb_serial_tty_driver;