Skip to content

Commit 2374bf7

Browse files
billauergregkh
authored andcommitted
char: xillybus: Check USB endpoints when probing device
Ensure, as the driver probes the device, that all endpoints that the driver may attempt to access exist and are of the correct type. All XillyUSB devices must have a Bulk IN and Bulk OUT endpoint at address 1. This is verified in xillyusb_setup_base_eps(). On top of that, a XillyUSB device may have additional Bulk OUT endpoints. The information about these endpoints' addresses is deduced from a data structure (the IDT) that the driver fetches from the device while probing it. These endpoints are checked in setup_channels(). A XillyUSB device never has more than one IN endpoint, as all data towards the host is multiplexed in this single Bulk IN endpoint. This is why setup_channels() only checks OUT endpoints. Reported-by: [email protected] Cc: stable <[email protected]> Closes: https://lore.kernel.org/all/[email protected]/T/ Fixes: a53d120 ("char: xillybus: Add driver for XillyUSB (Xillybus variant for USB)"). Signed-off-by: Eli Billauer <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent ad899c3 commit 2374bf7

File tree

1 file changed

+20
-2
lines changed

1 file changed

+20
-2
lines changed

drivers/char/xillybus/xillyusb.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1903,6 +1903,13 @@ static const struct file_operations xillyusb_fops = {
19031903

19041904
static int xillyusb_setup_base_eps(struct xillyusb_dev *xdev)
19051905
{
1906+
struct usb_device *udev = xdev->udev;
1907+
1908+
/* Verify that device has the two fundamental bulk in/out endpoints */
1909+
if (usb_pipe_type_check(udev, usb_sndbulkpipe(udev, MSG_EP_NUM)) ||
1910+
usb_pipe_type_check(udev, usb_rcvbulkpipe(udev, IN_EP_NUM)))
1911+
return -ENODEV;
1912+
19061913
xdev->msg_ep = endpoint_alloc(xdev, MSG_EP_NUM | USB_DIR_OUT,
19071914
bulk_out_work, 1, 2);
19081915
if (!xdev->msg_ep)
@@ -1932,14 +1939,15 @@ static int setup_channels(struct xillyusb_dev *xdev,
19321939
__le16 *chandesc,
19331940
int num_channels)
19341941
{
1935-
struct xillyusb_channel *chan;
1942+
struct usb_device *udev = xdev->udev;
1943+
struct xillyusb_channel *chan, *new_channels;
19361944
int i;
19371945

19381946
chan = kcalloc(num_channels, sizeof(*chan), GFP_KERNEL);
19391947
if (!chan)
19401948
return -ENOMEM;
19411949

1942-
xdev->channels = chan;
1950+
new_channels = chan;
19431951

19441952
for (i = 0; i < num_channels; i++, chan++) {
19451953
unsigned int in_desc = le16_to_cpu(*chandesc++);
@@ -1968,6 +1976,15 @@ static int setup_channels(struct xillyusb_dev *xdev,
19681976
*/
19691977

19701978
if ((out_desc & 0x80) && i < 14) { /* Entry is valid */
1979+
if (usb_pipe_type_check(udev,
1980+
usb_sndbulkpipe(udev, i + 2))) {
1981+
dev_err(xdev->dev,
1982+
"Missing BULK OUT endpoint %d\n",
1983+
i + 2);
1984+
kfree(new_channels);
1985+
return -ENODEV;
1986+
}
1987+
19711988
chan->writable = 1;
19721989
chan->out_synchronous = !!(out_desc & 0x40);
19731990
chan->out_seekable = !!(out_desc & 0x20);
@@ -1977,6 +1994,7 @@ static int setup_channels(struct xillyusb_dev *xdev,
19771994
}
19781995
}
19791996

1997+
xdev->channels = new_channels;
19801998
return 0;
19811999
}
19822000

0 commit comments

Comments
 (0)