[PATCH v2] USB: storage: sierra_ms: reject short SWoC responses
From: Jiancheng Huang
Date: Sun Jul 26 2026 - 11:12:08 EST
sierra_get_swoc_info() converts fields in the response after
usb_control_msg() returns, but it does not require the complete swoc_info
structure to have been transferred. A short response can leave fields
in the kmalloc() buffer uninitialized before truinst_show() formats them.
Use usb_control_msg_send() and usb_control_msg_recv() for the vendor
requests. The receive helper rejects short responses with -EREMOTEIO,
and only complete responses are converted before their fields are used.
Fixes: 32fe5e393455 ("USB Storage Sierra: TRU-Install feature update")
Suggested-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
Assisted-by: Codex:gpt-5.6-luna
Signed-off-by: Jiancheng Huang <jchuang@xxxxxxxxxx>
---
Changes in v2:
- Replace the raw usb_control_msg() calls with usb_control_msg_send() and
usb_control_msg_recv(), as suggested by Greg Kroah-Hartman.
- Add the public USB and kernel mailing lists omitted from v1.
- Clarify that testing used a synthetic short-response harness and no
physical or emulated Sierra device.
Testing:
- Tested on v7.2-rc4 with a synthetic KUnit/KMSAN short-response harness.
- The original implementation triggered a KMSAN uninitialized-value report.
- With this patch, usb_control_msg_recv() returned -EREMOTEIO and the test
completed without a KMSAN report.
drivers/usb/storage/sierra_ms.c | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/drivers/usb/storage/sierra_ms.c b/drivers/usb/storage/sierra_ms.c
index c5e3eeeb2..fac38687a 100644
--- a/drivers/usb/storage/sierra_ms.c
+++ b/drivers/usb/storage/sierra_ms.c
@@ -47,17 +47,16 @@ static bool containsFullLinuxPackage(struct swoc_info *swocInfo)
static int sierra_set_ms_mode(struct usb_device *udev, __u16 eSWocMode)
{
- int result;
dev_dbg(&udev->dev, "SWIMS: %s", "DEVICE MODE SWITCH\n");
- result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+ return usb_control_msg_send(udev, 0,
SWIMS_USB_REQUEST_SetSwocMode, /* __u8 request */
USB_TYPE_VENDOR | USB_DIR_OUT, /* __u8 request type */
eSWocMode, /* __u16 value */
0x0000, /* __u16 index */
NULL, /* void *data */
0, /* __u16 size */
- USB_CTRL_SET_TIMEOUT); /* int timeout */
- return result;
+ USB_CTRL_SET_TIMEOUT, /* int timeout */
+ GFP_KERNEL);
}
@@ -68,17 +67,20 @@ static int sierra_get_swoc_info(struct usb_device *udev,
dev_dbg(&udev->dev, "SWIMS: Attempting to get TRU-Install info\n");
- result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+ result = usb_control_msg_recv(udev, 0,
SWIMS_USB_REQUEST_GetSwocInfo, /* __u8 request */
USB_TYPE_VENDOR | USB_DIR_IN, /* __u8 request type */
0, /* __u16 value */
0, /* __u16 index */
- (void *) swocInfo, /* void *data */
+ swocInfo, /* void *data */
sizeof(struct swoc_info), /* __u16 size */
- USB_CTRL_SET_TIMEOUT); /* int timeout */
+ USB_CTRL_SET_TIMEOUT, /* int timeout */
+ GFP_KERNEL);
- swocInfo->LinuxSKU = le16_to_cpu(swocInfo->LinuxSKU);
- swocInfo->LinuxVer = le16_to_cpu(swocInfo->LinuxVer);
+ if (!result) {
+ swocInfo->LinuxSKU = le16_to_cpu(swocInfo->LinuxSKU);
+ swocInfo->LinuxVer = le16_to_cpu(swocInfo->LinuxVer);
+ }
return result;
}
--
2.43.0