aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hovold <johan@kernel.org>2015-09-23 14:41:42 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-09-23 15:15:19 -0400
commitcbb4be652d374f64661137756b8f357a1827d6a4 (patch)
tree762454d9669951c2cd6b8f23cc1bd6192c8f42d3
parentcc8e4fc0c3b5e8340bc8358990515d116a3c274c (diff)
USB: whiteheat: fix potential null-deref at probe
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>
-rw-r--r--drivers/usb/serial/whiteheat.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index 6c3734d2b45a..d3ea90bef84d 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -80,6 +80,8 @@ static int whiteheat_firmware_download(struct usb_serial *serial,
80static int whiteheat_firmware_attach(struct usb_serial *serial); 80static int whiteheat_firmware_attach(struct usb_serial *serial);
81 81
82/* function prototypes for the Connect Tech WhiteHEAT serial converter */ 82/* function prototypes for the Connect Tech WhiteHEAT serial converter */
83static int whiteheat_probe(struct usb_serial *serial,
84 const struct usb_device_id *id);
83static int whiteheat_attach(struct usb_serial *serial); 85static int whiteheat_attach(struct usb_serial *serial);
84static void whiteheat_release(struct usb_serial *serial); 86static void whiteheat_release(struct usb_serial *serial);
85static int whiteheat_port_probe(struct usb_serial_port *port); 87static int whiteheat_port_probe(struct usb_serial_port *port);
@@ -116,6 +118,7 @@ static struct usb_serial_driver whiteheat_device = {
116 .description = "Connect Tech - WhiteHEAT", 118 .description = "Connect Tech - WhiteHEAT",
117 .id_table = id_table_std, 119 .id_table = id_table_std,
118 .num_ports = 4, 120 .num_ports = 4,
121 .probe = whiteheat_probe,
119 .attach = whiteheat_attach, 122 .attach = whiteheat_attach,
120 .release = whiteheat_release, 123 .release = whiteheat_release,
121 .port_probe = whiteheat_port_probe, 124 .port_probe = whiteheat_port_probe,
@@ -217,6 +220,34 @@ static int whiteheat_firmware_attach(struct usb_serial *serial)
217/***************************************************************************** 220/*****************************************************************************
218 * Connect Tech's White Heat serial driver functions 221 * Connect Tech's White Heat serial driver functions
219 *****************************************************************************/ 222 *****************************************************************************/
223
224static int whiteheat_probe(struct usb_serial *serial,
225 const struct usb_device_id *id)
226{
227 struct usb_host_interface *iface_desc;
228 struct usb_endpoint_descriptor *endpoint;
229 size_t num_bulk_in = 0;
230 size_t num_bulk_out = 0;
231 size_t min_num_bulk;
232 unsigned int i;
233
234 iface_desc = serial->interface->cur_altsetting;
235
236 for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
237 endpoint = &iface_desc->endpoint[i].desc;
238 if (usb_endpoint_is_bulk_in(endpoint))
239 ++num_bulk_in;
240 if (usb_endpoint_is_bulk_out(endpoint))
241 ++num_bulk_out;
242 }
243
244 min_num_bulk = COMMAND_PORT + 1;
245 if (num_bulk_in < min_num_bulk || num_bulk_out < min_num_bulk)
246 return -ENODEV;
247
248 return 0;
249}
250
220static int whiteheat_attach(struct usb_serial *serial) 251static int whiteheat_attach(struct usb_serial *serial)
221{ 252{
222 struct usb_serial_port *command_port; 253 struct usb_serial_port *command_port;