]>
Commit | Line | Data |
---|---|---|
dcfe13a2 GKH |
1 | From 0cd273bb5e4d1828efaaa8dfd11b7928131ed149 Mon Sep 17 00:00:00 2001 |
2 | From: Johan Hovold <johan@kernel.org> | |
3 | Date: Mon, 13 Mar 2017 09:53:56 -0300 | |
4 | Subject: [media] cx231xx-cards: fix NULL-deref at probe | |
5 | ||
6 | From: Johan Hovold <johan@kernel.org> | |
7 | ||
8 | commit 0cd273bb5e4d1828efaaa8dfd11b7928131ed149 upstream. | |
9 | ||
10 | Make sure to check the number of endpoints to avoid dereferencing a | |
11 | NULL-pointer or accessing memory beyond the endpoint array should a | |
12 | malicious device lack the expected endpoints. | |
13 | ||
14 | Fixes: e0d3bafd0258 ("V4L/DVB (10954): Add cx231xx USB driver") | |
15 | ||
16 | Cc: Sri Deevi <Srinivasa.Deevi@conexant.com> | |
17 | Signed-off-by: Johan Hovold <johan@kernel.org> | |
18 | Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> | |
19 | Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com> | |
20 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
21 | ||
22 | --- | |
23 | drivers/media/usb/cx231xx/cx231xx-cards.c | 45 ++++++++++++++++++++++++++---- | |
24 | 1 file changed, 40 insertions(+), 5 deletions(-) | |
25 | ||
26 | --- a/drivers/media/usb/cx231xx/cx231xx-cards.c | |
27 | +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c | |
28 | @@ -1397,6 +1397,9 @@ static int cx231xx_init_v4l2(struct cx23 | |
29 | ||
30 | uif = udev->actconfig->interface[idx]; | |
31 | ||
32 | + if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1) | |
33 | + return -ENODEV; | |
34 | + | |
35 | dev->video_mode.end_point_addr = uif->altsetting[0].endpoint[isoc_pipe].desc.bEndpointAddress; | |
36 | dev->video_mode.num_alt = uif->num_altsetting; | |
37 | ||
38 | @@ -1410,7 +1413,12 @@ static int cx231xx_init_v4l2(struct cx23 | |
39 | return -ENOMEM; | |
40 | ||
41 | for (i = 0; i < dev->video_mode.num_alt; i++) { | |
42 | - u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.wMaxPacketSize); | |
43 | + u16 tmp; | |
44 | + | |
45 | + if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1) | |
46 | + return -ENODEV; | |
47 | + | |
48 | + tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.wMaxPacketSize); | |
49 | dev->video_mode.alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); | |
50 | dev_dbg(dev->dev, | |
51 | "Alternate setting %i, max size= %i\n", i, | |
52 | @@ -1427,6 +1435,9 @@ static int cx231xx_init_v4l2(struct cx23 | |
53 | } | |
54 | uif = udev->actconfig->interface[idx]; | |
55 | ||
56 | + if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1) | |
57 | + return -ENODEV; | |
58 | + | |
59 | dev->vbi_mode.end_point_addr = | |
60 | uif->altsetting[0].endpoint[isoc_pipe].desc. | |
61 | bEndpointAddress; | |
62 | @@ -1443,8 +1454,12 @@ static int cx231xx_init_v4l2(struct cx23 | |
63 | return -ENOMEM; | |
64 | ||
65 | for (i = 0; i < dev->vbi_mode.num_alt; i++) { | |
66 | - u16 tmp = | |
67 | - le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe]. | |
68 | + u16 tmp; | |
69 | + | |
70 | + if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1) | |
71 | + return -ENODEV; | |
72 | + | |
73 | + tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe]. | |
74 | desc.wMaxPacketSize); | |
75 | dev->vbi_mode.alt_max_pkt_size[i] = | |
76 | (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); | |
77 | @@ -1464,6 +1479,9 @@ static int cx231xx_init_v4l2(struct cx23 | |
78 | } | |
79 | uif = udev->actconfig->interface[idx]; | |
80 | ||
81 | + if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1) | |
82 | + return -ENODEV; | |
83 | + | |
84 | dev->sliced_cc_mode.end_point_addr = | |
85 | uif->altsetting[0].endpoint[isoc_pipe].desc. | |
86 | bEndpointAddress; | |
87 | @@ -1478,7 +1496,12 @@ static int cx231xx_init_v4l2(struct cx23 | |
88 | return -ENOMEM; | |
89 | ||
90 | for (i = 0; i < dev->sliced_cc_mode.num_alt; i++) { | |
91 | - u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe]. | |
92 | + u16 tmp; | |
93 | + | |
94 | + if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1) | |
95 | + return -ENODEV; | |
96 | + | |
97 | + tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe]. | |
98 | desc.wMaxPacketSize); | |
99 | dev->sliced_cc_mode.alt_max_pkt_size[i] = | |
100 | (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); | |
101 | @@ -1647,6 +1670,11 @@ static int cx231xx_usb_probe(struct usb_ | |
102 | } | |
103 | uif = udev->actconfig->interface[idx]; | |
104 | ||
105 | + if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1) { | |
106 | + retval = -ENODEV; | |
107 | + goto err_video_alt; | |
108 | + } | |
109 | + | |
110 | dev->ts1_mode.end_point_addr = | |
111 | uif->altsetting[0].endpoint[isoc_pipe]. | |
112 | desc.bEndpointAddress; | |
113 | @@ -1664,7 +1692,14 @@ static int cx231xx_usb_probe(struct usb_ | |
114 | } | |
115 | ||
116 | for (i = 0; i < dev->ts1_mode.num_alt; i++) { | |
117 | - u16 tmp = le16_to_cpu(uif->altsetting[i]. | |
118 | + u16 tmp; | |
119 | + | |
120 | + if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1) { | |
121 | + retval = -ENODEV; | |
122 | + goto err_video_alt; | |
123 | + } | |
124 | + | |
125 | + tmp = le16_to_cpu(uif->altsetting[i]. | |
126 | endpoint[isoc_pipe].desc. | |
127 | wMaxPacketSize); | |
128 | dev->ts1_mode.alt_max_pkt_size[i] = |