diff options
| author | Johan Hovold <johan@kernel.org> | 2017-03-13 08:53:56 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-05-25 09:44:42 -0400 |
| commit | 2338de43e234d7144c1dff900bf3422b1523ac00 (patch) | |
| tree | 5ad1f029571617d6c3f02d8e327a3b91098fa6dd /drivers/media | |
| parent | 8ebb884009b60f662024630a6df8e565ed5956f1 (diff) | |
cx231xx-cards: fix NULL-deref at probe
commit 0cd273bb5e4d1828efaaa8dfd11b7928131ed149 upstream.
Make sure to check the number of endpoints to avoid dereferencing a
NULL-pointer or accessing memory beyond the endpoint array should a
malicious device lack the expected endpoints.
Fixes: e0d3bafd0258 ("V4L/DVB (10954): Add cx231xx USB driver")
Cc: Sri Deevi <Srinivasa.Deevi@conexant.com>
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/media')
| -rw-r--r-- | drivers/media/usb/cx231xx/cx231xx-cards.c | 45 |
1 files changed, 40 insertions, 5 deletions
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index 36bc25494319..be9e3335dcb7 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c | |||
| @@ -1397,6 +1397,9 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, | |||
| 1397 | 1397 | ||
| 1398 | uif = udev->actconfig->interface[idx]; | 1398 | uif = udev->actconfig->interface[idx]; |
| 1399 | 1399 | ||
| 1400 | if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1) | ||
| 1401 | return -ENODEV; | ||
| 1402 | |||
| 1400 | dev->video_mode.end_point_addr = uif->altsetting[0].endpoint[isoc_pipe].desc.bEndpointAddress; | 1403 | dev->video_mode.end_point_addr = uif->altsetting[0].endpoint[isoc_pipe].desc.bEndpointAddress; |
| 1401 | dev->video_mode.num_alt = uif->num_altsetting; | 1404 | dev->video_mode.num_alt = uif->num_altsetting; |
| 1402 | 1405 | ||
| @@ -1410,7 +1413,12 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, | |||
| 1410 | return -ENOMEM; | 1413 | return -ENOMEM; |
| 1411 | 1414 | ||
| 1412 | for (i = 0; i < dev->video_mode.num_alt; i++) { | 1415 | for (i = 0; i < dev->video_mode.num_alt; i++) { |
| 1413 | u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.wMaxPacketSize); | 1416 | u16 tmp; |
| 1417 | |||
| 1418 | if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1) | ||
| 1419 | return -ENODEV; | ||
| 1420 | |||
| 1421 | tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.wMaxPacketSize); | ||
| 1414 | dev->video_mode.alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); | 1422 | dev->video_mode.alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); |
| 1415 | dev_dbg(dev->dev, | 1423 | dev_dbg(dev->dev, |
| 1416 | "Alternate setting %i, max size= %i\n", i, | 1424 | "Alternate setting %i, max size= %i\n", i, |
| @@ -1427,6 +1435,9 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, | |||
| 1427 | } | 1435 | } |
| 1428 | uif = udev->actconfig->interface[idx]; | 1436 | uif = udev->actconfig->interface[idx]; |
| 1429 | 1437 | ||
| 1438 | if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1) | ||
| 1439 | return -ENODEV; | ||
| 1440 | |||
| 1430 | dev->vbi_mode.end_point_addr = | 1441 | dev->vbi_mode.end_point_addr = |
| 1431 | uif->altsetting[0].endpoint[isoc_pipe].desc. | 1442 | uif->altsetting[0].endpoint[isoc_pipe].desc. |
| 1432 | bEndpointAddress; | 1443 | bEndpointAddress; |
| @@ -1443,8 +1454,12 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, | |||
| 1443 | return -ENOMEM; | 1454 | return -ENOMEM; |
| 1444 | 1455 | ||
| 1445 | for (i = 0; i < dev->vbi_mode.num_alt; i++) { | 1456 | for (i = 0; i < dev->vbi_mode.num_alt; i++) { |
| 1446 | u16 tmp = | 1457 | u16 tmp; |
| 1447 | le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe]. | 1458 | |
| 1459 | if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1) | ||
| 1460 | return -ENODEV; | ||
| 1461 | |||
| 1462 | tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe]. | ||
| 1448 | desc.wMaxPacketSize); | 1463 | desc.wMaxPacketSize); |
| 1449 | dev->vbi_mode.alt_max_pkt_size[i] = | 1464 | dev->vbi_mode.alt_max_pkt_size[i] = |
| 1450 | (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); | 1465 | (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); |
| @@ -1464,6 +1479,9 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, | |||
| 1464 | } | 1479 | } |
| 1465 | uif = udev->actconfig->interface[idx]; | 1480 | uif = udev->actconfig->interface[idx]; |
| 1466 | 1481 | ||
| 1482 | if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1) | ||
| 1483 | return -ENODEV; | ||
| 1484 | |||
| 1467 | dev->sliced_cc_mode.end_point_addr = | 1485 | dev->sliced_cc_mode.end_point_addr = |
| 1468 | uif->altsetting[0].endpoint[isoc_pipe].desc. | 1486 | uif->altsetting[0].endpoint[isoc_pipe].desc. |
| 1469 | bEndpointAddress; | 1487 | bEndpointAddress; |
| @@ -1478,7 +1496,12 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, | |||
| 1478 | return -ENOMEM; | 1496 | return -ENOMEM; |
| 1479 | 1497 | ||
| 1480 | for (i = 0; i < dev->sliced_cc_mode.num_alt; i++) { | 1498 | for (i = 0; i < dev->sliced_cc_mode.num_alt; i++) { |
| 1481 | u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe]. | 1499 | u16 tmp; |
| 1500 | |||
| 1501 | if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1) | ||
| 1502 | return -ENODEV; | ||
| 1503 | |||
| 1504 | tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe]. | ||
| 1482 | desc.wMaxPacketSize); | 1505 | desc.wMaxPacketSize); |
| 1483 | dev->sliced_cc_mode.alt_max_pkt_size[i] = | 1506 | dev->sliced_cc_mode.alt_max_pkt_size[i] = |
| 1484 | (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); | 1507 | (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); |
| @@ -1647,6 +1670,11 @@ static int cx231xx_usb_probe(struct usb_interface *interface, | |||
| 1647 | } | 1670 | } |
| 1648 | uif = udev->actconfig->interface[idx]; | 1671 | uif = udev->actconfig->interface[idx]; |
| 1649 | 1672 | ||
| 1673 | if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1) { | ||
| 1674 | retval = -ENODEV; | ||
| 1675 | goto err_video_alt; | ||
| 1676 | } | ||
| 1677 | |||
| 1650 | dev->ts1_mode.end_point_addr = | 1678 | dev->ts1_mode.end_point_addr = |
| 1651 | uif->altsetting[0].endpoint[isoc_pipe]. | 1679 | uif->altsetting[0].endpoint[isoc_pipe]. |
| 1652 | desc.bEndpointAddress; | 1680 | desc.bEndpointAddress; |
| @@ -1664,7 +1692,14 @@ static int cx231xx_usb_probe(struct usb_interface *interface, | |||
| 1664 | } | 1692 | } |
| 1665 | 1693 | ||
| 1666 | for (i = 0; i < dev->ts1_mode.num_alt; i++) { | 1694 | for (i = 0; i < dev->ts1_mode.num_alt; i++) { |
| 1667 | u16 tmp = le16_to_cpu(uif->altsetting[i]. | 1695 | u16 tmp; |
| 1696 | |||
| 1697 | if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1) { | ||
| 1698 | retval = -ENODEV; | ||
| 1699 | goto err_video_alt; | ||
| 1700 | } | ||
| 1701 | |||
| 1702 | tmp = le16_to_cpu(uif->altsetting[i]. | ||
| 1668 | endpoint[isoc_pipe].desc. | 1703 | endpoint[isoc_pipe].desc. |
| 1669 | wMaxPacketSize); | 1704 | wMaxPacketSize); |
| 1670 | dev->ts1_mode.alt_max_pkt_size[i] = | 1705 | dev->ts1_mode.alt_max_pkt_size[i] = |
