Skip to content

Commit

Permalink
USB: whiteheat: fix potential null-deref at probe
Browse files Browse the repository at this point in the history
Fix potential null-pointer dereference at probe by making sure that the
required endpoints are present.

The whiteheat driver assumes there are at least five pairs of bulk
endpoints, of which the final pair is used for the "command port". An
attempt to bind to an interface with fewer bulk endpoints would
currently lead to an oops.

Fixes CVE-2015-5257.

Reported-by: Moein Ghasemzadeh <moein@istuary.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
jhovold authored and gregkh committed Sep 23, 2015
1 parent cc8e4fc commit cbb4be6
Showing 1 changed file with 31 additions and 0 deletions.
31 changes: 31 additions & 0 deletions drivers/usb/serial/whiteheat.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ static int whiteheat_firmware_download(struct usb_serial *serial,
static int whiteheat_firmware_attach(struct usb_serial *serial);

/* function prototypes for the Connect Tech WhiteHEAT serial converter */
static int whiteheat_probe(struct usb_serial *serial,
const struct usb_device_id *id);
static int whiteheat_attach(struct usb_serial *serial);
static void whiteheat_release(struct usb_serial *serial);
static int whiteheat_port_probe(struct usb_serial_port *port);
Expand Down Expand Up @@ -116,6 +118,7 @@ static struct usb_serial_driver whiteheat_device = {
.description = "Connect Tech - WhiteHEAT",
.id_table = id_table_std,
.num_ports = 4,
.probe = whiteheat_probe,
.attach = whiteheat_attach,
.release = whiteheat_release,
.port_probe = whiteheat_port_probe,
Expand Down Expand Up @@ -217,6 +220,34 @@ static int whiteheat_firmware_attach(struct usb_serial *serial)
/*****************************************************************************
* Connect Tech's White Heat serial driver functions
*****************************************************************************/

static int whiteheat_probe(struct usb_serial *serial,
const struct usb_device_id *id)
{
struct usb_host_interface *iface_desc;
struct usb_endpoint_descriptor *endpoint;
size_t num_bulk_in = 0;
size_t num_bulk_out = 0;
size_t min_num_bulk;
unsigned int i;

iface_desc = serial->interface->cur_altsetting;

for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
endpoint = &iface_desc->endpoint[i].desc;
if (usb_endpoint_is_bulk_in(endpoint))
++num_bulk_in;
if (usb_endpoint_is_bulk_out(endpoint))
++num_bulk_out;
}

min_num_bulk = COMMAND_PORT + 1;
if (num_bulk_in < min_num_bulk || num_bulk_out < min_num_bulk)
return -ENODEV;

return 0;
}

static int whiteheat_attach(struct usb_serial *serial)
{
struct usb_serial_port *command_port;
Expand Down

0 comments on commit cbb4be6

Please sign in to comment.