Skip to content

Commit

Permalink
USB: serial: metro-usb: add missing interrupt-out endpoint check
Browse files Browse the repository at this point in the history
One class of "unidirectional" devices managed by this driver uses an
interrupt-out endpoint to send control messages at open and close. Due
to a missing endpoint sanity check, this could result in an interrupt
URB being submitted to endpoint 0 instead. This would be caught by
USB core (without a WARN dump), but let's verify that the expected
endpoints are present at probe rather than when a port is later opened.

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Johan Hovold <johan@kernel.org>
  • Loading branch information
Johan Hovold committed Oct 13, 2017
1 parent 6f792f4 commit ee13a25
Showing 1 changed file with 17 additions and 5 deletions.
22 changes: 17 additions & 5 deletions drivers/usb/serial/metro-usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,21 +53,33 @@ MODULE_DEVICE_TABLE(usb, id_table);
#define UNI_CMD_OPEN 0x80
#define UNI_CMD_CLOSE 0xFF

static inline int metrousb_is_unidirectional_mode(struct usb_serial_port *port)
static int metrousb_is_unidirectional_mode(struct usb_serial *serial)
{
__u16 product_id = le16_to_cpu(
port->serial->dev->descriptor.idProduct);
u16 product_id = le16_to_cpu(serial->dev->descriptor.idProduct);

return product_id == FOCUS_PRODUCT_ID_UNI;
}

static int metrousb_calc_num_ports(struct usb_serial *serial,
struct usb_serial_endpoints *epds)
{
if (metrousb_is_unidirectional_mode(serial)) {
if (epds->num_interrupt_out == 0) {
dev_err(&serial->interface->dev, "interrupt-out endpoint missing\n");
return -ENODEV;
}
}

return 1;
}

static int metrousb_send_unidirectional_cmd(u8 cmd, struct usb_serial_port *port)
{
int ret;
int actual_len;
u8 *buffer_cmd = NULL;

if (!metrousb_is_unidirectional_mode(port))
if (!metrousb_is_unidirectional_mode(port->serial))
return 0;

buffer_cmd = kzalloc(sizeof(cmd), GFP_KERNEL);
Expand Down Expand Up @@ -334,8 +346,8 @@ static struct usb_serial_driver metrousb_device = {
},
.description = "Metrologic USB to Serial",
.id_table = id_table,
.num_ports = 1,
.num_interrupt_in = 1,
.calc_num_ports = metrousb_calc_num_ports,
.open = metrousb_open,
.close = metrousb_cleanup,
.read_int_callback = metrousb_read_int_callback,
Expand Down

0 comments on commit ee13a25

Please sign in to comment.