In the Linux kernel, the following vulnerability has been resolved:
USB: idmouse: fix use-after-free on disconnect race
mutex_unlock() may access the mutex structure after releasing the lock
and therefore cannot be used to manage lifetime of objects directly
(unlike spinlocks and refcounts). [1][2]
Use a kref to release the driver data to avoid use-after-free in
mutex_unlock() when release() races with disconnect().
[1] a51749ab34d9 ("locking/mutex: Document that mutex_unlock() is
non-atomic")
[2] 2b9d9e0a9ba0 ("locking/mutex: Clarify that mutex_unlock(), and most
other sleeping locks, can still use the lock object
after it's unlocked")
In the Linux kernel, the following vulnerability has been resolved:
usb: gadget: f_printer: take kref only for successful open
printer_open() returns -EBUSY when the character device is already
open, but it increments dev->kref regardless of the return value. VFS
does not call ->release() for a failed open, so every rejected second
open permanently leaks one reference.
Move kref_get() into the successful-open branch.
In the Linux kernel, the following vulnerability has been resolved:
usb: gadget: composite: fix dead empty check in the USB_DT_OTG handler
The OTG branch of composite_setup() falls back to the first
configuration when none is selected:
if (cdev->config)
config = cdev->config;
else
config = list_first_entry(&cdev->configs,
struct usb_configuration, list);
if (!config)
goto done;
...
memcpy(req->buf, config->descriptors[0], value);
list_first_entry() never returns NULL. On an empty list it returns
container_of() of the list head. So the "if (!config)" check is dead.
When cdev->configs is empty, config points at the head inside struct
usb_composite_dev. config->descriptors[0] reads whatever sits at that
offset. The memcpy copies up to w_length bytes of it into the response
buffer.
cdev->configs can be empty in two cases. One is a teardown race on
gadget unbind with a control transfer in flight. The other is a driver
that sets is_otg before it adds a config. A reproducer that holds
cdev->configs empty triggers a KASAN fault in this branch.
Use list_first_entry_or_null() so the existing check does its job.
In the Linux kernel, the following vulnerability has been resolved:
USB: serial: digi_acceleport: fix write buffer corruption
The digi_write_inb_command() is supposed to wait for the write urb to
become available or return an error, but instead it updates the transfer
buffer and tries to resubmit the urb on timeout.
To make things worse, for commands like break control where no timeout
is used, the driver would corrupt the urb immediately due to a broken
jiffies comparison (on 32-bit machines this takes five minutes of uptime
to trigger due to INITIAL_JIFFIES).
Fix this by adding the missing return on timeout and waiting
indefinitely when no timeout has been specified as intended.
This issue was (sort of) flagged by Sashiko when reviewing an unrelated
change to the driver.
In the Linux kernel, the following vulnerability has been resolved:
USB: serial: digi_acceleport: fix hard lockup on disconnect
If submitting the OOB write urb fails persistently (e.g if the device is
being disconnected) the driver would loop indefinitely with interrupts
disabled.
Check for urb submission errors when sending OOB commands to avoid
hanging if, for example, open(), set_termios() or close() races with a
physical disconnect.
This is issue was flagged by Sashiko when reviewing an unrelated change
to the driver.
In the Linux kernel, the following vulnerability has been resolved:
USB: serial: digi_acceleport: fix broken rx after throttle
If the port is closed while throttled, the read urb is never resubmitted
and the port will not receive any further data until the device is
reconnected (or the driver is rebound).
Clear the throttle flags and submit the urb if needed when opening the
port.
In the Linux kernel, the following vulnerability has been resolved:
usb: mtu3: unmap request DMA on queue failure
mtu3_gadget_queue() maps the request before checking whether
the QMU GPD ring can accept another transfer. the request is
returned with -EAGAIN before it is linked on the endpoint
request list if mtu3_prepare_transfer() fails.
Normal completion and dequeue paths unmap requests from
mtu3_req_complete(), but this error path never reaches that
helper, so the DMA mapping is left active. Unmap the request
before returning from the failed queue path.
In the Linux kernel, the following vulnerability has been resolved:
USB: legousbtower: fix use-after-free on disconnect race
mutex_unlock() may access the mutex structure after releasing the lock
and therefore cannot be used to manage lifetime of objects directly
(unlike spinlocks and refcounts). [1][2]
Use a kref to release the driver data to avoid use-after-free in
mutex_unlock() when release() races with disconnect().
[1] a51749ab34d9 ("locking/mutex: Document that mutex_unlock() is
non-atomic")
[2] 2b9d9e0a9ba0 ("locking/mutex: Clarify that mutex_unlock(), and most
other sleeping locks, can still use the lock object
after it's unlocked")
In the Linux kernel, the following vulnerability has been resolved:
usb: typec: tcpm: Validate SVID index in svdm_consume_modes()
In svdm_consume_modes(), the SVID value is read from pmdata->svids using
pmdata->svid_index as an array index without bounds validation:
paltmode->svid = pmdata->svids[pmdata->svid_index];
If pmdata->svid_index is driven beyond SVID_DISCOVERY_MAX (16), it results
in an out-of-bounds read of the pmdata->svids array. Because pd_mode_data
is embedded inside struct tcpm_port, indexing past svids reads into
adjacent fields. In particular:
- At index 16, it reads the altmodes count.
- At index 18 and beyond, it reads into altmode_desc[], which contains
partner-supplied SVDM Discovery Modes VDOs.
By injecting a chosen SVID into altmode_desc[0].vdo and driving svid_index
to 20, the partner can force paltmode->svid to be loaded with an arbitrary,
partner- chosen SVID, which is then registered via
typec_partner_register_altmode().
Fix this by validating that pmdata->svid_index is non-negative and strictly
less than pmdata->nsvids before accessing the pmdata->svids array inside
svdm_consume_modes().
In the Linux kernel, the following vulnerability has been resolved:
usbip: vudc: fix NULL deref in vep_dequeue()
vep_alloc_request() wasn't initializing vrequest->udc, so cancellations
on the FunctionFS AIO path were arriving in vep_dequeue without a valid
UDC reference.
Since vrequest->udc is never actually properly used anywhere, we opt to
remove it, and update vep_dequeue to obtain a reference to the udc with
ep_to_vudc(), consistent with the other vep_ ops.
AFAICT this bug has existed for ~10 years. Seems that nobody has really
stressed the FunctionFS AIO path on usbip's vudc.
I tested this fix in a QEMU aarch64 guest driving FunctionFS endpoints
via AIO. Before the fix, running `usbip attach` from the host would
cause the guest to oops with the following backtrace:
Call trace:
vep_dequeue+0x1c/0xe4 (P)
usb_ep_dequeue+0x14/0x20
ffs_aio_cancel+0x24/0x34
__arm64_sys_io_cancel+0xb0/0x124
do_el0_svc+0x68/0x100
el0_svc+0x18/0x5c
el0t_64_sync_handler+0x98/0xdc
el0t_64_sync+0x154/0x158