Skip to content

Commit 54eaecf

Browse files
committed
USB: serial: mos7840: fix crash on resume
jira LE-3201 cve CVE-2024-42244 Rebuild_History Non-Buildable kernel-rt-4.18.0-553.27.1.rt7.368.el8_10 commit-author Dmitry Smirnov <[email protected]> commit c15a688 Since commit c49cfa9 ("USB: serial: use generic method if no alternative is provided in usb serial layer"), USB serial core calls the generic resume implementation when the driver has not provided one. This can trigger a crash on resume with mos7840 since support for multiple read URBs was added back in 2011. Specifically, both port read URBs are now submitted on resume for open ports, but the context pointer of the second URB is left set to the core rather than mos7840 port structure. Fix this by implementing dedicated suspend and resume functions for mos7840. Tested with Delock 87414 USB 2.0 to 4x serial adapter. Signed-off-by: Dmitry Smirnov <[email protected]> [ johan: analyse crash and rewrite commit message; set busy flag on resume; drop bulk-in check; drop unnecessary usb_kill_urb() ] Fixes: d83b405 ("USB: serial: add support for multiple read urbs") Cc: [email protected] # 3.3 Signed-off-by: Johan Hovold <[email protected]> (cherry picked from commit c15a688) Signed-off-by: Jonathan Maple <[email protected]>
1 parent 39260d3 commit 54eaecf

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

drivers/usb/serial/mos7840.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1740,6 +1740,49 @@ static void mos7840_port_remove(struct usb_serial_port *port)
17401740
kfree(mos7840_port);
17411741
}
17421742

1743+
static int mos7840_suspend(struct usb_serial *serial, pm_message_t message)
1744+
{
1745+
struct moschip_port *mos7840_port;
1746+
struct usb_serial_port *port;
1747+
int i;
1748+
1749+
for (i = 0; i < serial->num_ports; ++i) {
1750+
port = serial->port[i];
1751+
if (!tty_port_initialized(&port->port))
1752+
continue;
1753+
1754+
mos7840_port = usb_get_serial_port_data(port);
1755+
1756+
usb_kill_urb(mos7840_port->read_urb);
1757+
mos7840_port->read_urb_busy = false;
1758+
}
1759+
1760+
return 0;
1761+
}
1762+
1763+
static int mos7840_resume(struct usb_serial *serial)
1764+
{
1765+
struct moschip_port *mos7840_port;
1766+
struct usb_serial_port *port;
1767+
int res;
1768+
int i;
1769+
1770+
for (i = 0; i < serial->num_ports; ++i) {
1771+
port = serial->port[i];
1772+
if (!tty_port_initialized(&port->port))
1773+
continue;
1774+
1775+
mos7840_port = usb_get_serial_port_data(port);
1776+
1777+
mos7840_port->read_urb_busy = true;
1778+
res = usb_submit_urb(mos7840_port->read_urb, GFP_NOIO);
1779+
if (res)
1780+
mos7840_port->read_urb_busy = false;
1781+
}
1782+
1783+
return 0;
1784+
}
1785+
17431786
static struct usb_serial_driver moschip7840_4port_device = {
17441787
.driver = {
17451788
.owner = THIS_MODULE,
@@ -1767,6 +1810,8 @@ static struct usb_serial_driver moschip7840_4port_device = {
17671810
.port_probe = mos7840_port_probe,
17681811
.port_remove = mos7840_port_remove,
17691812
.read_bulk_callback = mos7840_bulk_in_callback,
1813+
.suspend = mos7840_suspend,
1814+
.resume = mos7840_resume,
17701815
};
17711816

17721817
static struct usb_serial_driver * const serial_drivers[] = {

0 commit comments

Comments
 (0)