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 | |
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')
-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] = |