diff options
Diffstat (limited to 'drivers/usb/class/cdc-acm.c')
-rw-r--r-- | drivers/usb/class/cdc-acm.c | 54 |
1 files changed, 25 insertions, 29 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 546a17e8ad5b..e78720b59d67 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -1091,6 +1091,7 @@ static int acm_probe(struct usb_interface *intf, | |||
1091 | unsigned long quirks; | 1091 | unsigned long quirks; |
1092 | int num_rx_buf; | 1092 | int num_rx_buf; |
1093 | int i; | 1093 | int i; |
1094 | unsigned int elength = 0; | ||
1094 | int combined_interfaces = 0; | 1095 | int combined_interfaces = 0; |
1095 | struct device *tty_dev; | 1096 | struct device *tty_dev; |
1096 | int rv = -ENOMEM; | 1097 | int rv = -ENOMEM; |
@@ -1136,9 +1137,12 @@ static int acm_probe(struct usb_interface *intf, | |||
1136 | dev_err(&intf->dev, "skipping garbage\n"); | 1137 | dev_err(&intf->dev, "skipping garbage\n"); |
1137 | goto next_desc; | 1138 | goto next_desc; |
1138 | } | 1139 | } |
1140 | elength = buffer[0]; | ||
1139 | 1141 | ||
1140 | switch (buffer[2]) { | 1142 | switch (buffer[2]) { |
1141 | case USB_CDC_UNION_TYPE: /* we've found it */ | 1143 | case USB_CDC_UNION_TYPE: /* we've found it */ |
1144 | if (elength < sizeof(struct usb_cdc_union_desc)) | ||
1145 | goto next_desc; | ||
1142 | if (union_header) { | 1146 | if (union_header) { |
1143 | dev_err(&intf->dev, "More than one " | 1147 | dev_err(&intf->dev, "More than one " |
1144 | "union descriptor, skipping ...\n"); | 1148 | "union descriptor, skipping ...\n"); |
@@ -1147,29 +1151,36 @@ static int acm_probe(struct usb_interface *intf, | |||
1147 | union_header = (struct usb_cdc_union_desc *)buffer; | 1151 | union_header = (struct usb_cdc_union_desc *)buffer; |
1148 | break; | 1152 | break; |
1149 | case USB_CDC_COUNTRY_TYPE: /* export through sysfs*/ | 1153 | case USB_CDC_COUNTRY_TYPE: /* export through sysfs*/ |
1154 | if (elength < sizeof(struct usb_cdc_country_functional_desc)) | ||
1155 | goto next_desc; | ||
1150 | cfd = (struct usb_cdc_country_functional_desc *)buffer; | 1156 | cfd = (struct usb_cdc_country_functional_desc *)buffer; |
1151 | break; | 1157 | break; |
1152 | case USB_CDC_HEADER_TYPE: /* maybe check version */ | 1158 | case USB_CDC_HEADER_TYPE: /* maybe check version */ |
1153 | break; /* for now we ignore it */ | 1159 | break; /* for now we ignore it */ |
1154 | case USB_CDC_ACM_TYPE: | 1160 | case USB_CDC_ACM_TYPE: |
1161 | if (elength < 4) | ||
1162 | goto next_desc; | ||
1155 | ac_management_function = buffer[3]; | 1163 | ac_management_function = buffer[3]; |
1156 | break; | 1164 | break; |
1157 | case USB_CDC_CALL_MANAGEMENT_TYPE: | 1165 | case USB_CDC_CALL_MANAGEMENT_TYPE: |
1166 | if (elength < 5) | ||
1167 | goto next_desc; | ||
1158 | call_management_function = buffer[3]; | 1168 | call_management_function = buffer[3]; |
1159 | call_interface_num = buffer[4]; | 1169 | call_interface_num = buffer[4]; |
1160 | break; | 1170 | break; |
1161 | default: | 1171 | default: |
1162 | /* there are LOTS more CDC descriptors that | 1172 | /* |
1173 | * there are LOTS more CDC descriptors that | ||
1163 | * could legitimately be found here. | 1174 | * could legitimately be found here. |
1164 | */ | 1175 | */ |
1165 | dev_dbg(&intf->dev, "Ignoring descriptor: " | 1176 | dev_dbg(&intf->dev, "Ignoring descriptor: " |
1166 | "type %02x, length %d\n", | 1177 | "type %02x, length %ud\n", |
1167 | buffer[2], buffer[0]); | 1178 | buffer[2], elength); |
1168 | break; | 1179 | break; |
1169 | } | 1180 | } |
1170 | next_desc: | 1181 | next_desc: |
1171 | buflen -= buffer[0]; | 1182 | buflen -= elength; |
1172 | buffer += buffer[0]; | 1183 | buffer += elength; |
1173 | } | 1184 | } |
1174 | 1185 | ||
1175 | if (!union_header) { | 1186 | if (!union_header) { |
@@ -1287,10 +1298,8 @@ made_compressed_probe: | |||
1287 | dev_dbg(&intf->dev, "interfaces are valid\n"); | 1298 | dev_dbg(&intf->dev, "interfaces are valid\n"); |
1288 | 1299 | ||
1289 | acm = kzalloc(sizeof(struct acm), GFP_KERNEL); | 1300 | acm = kzalloc(sizeof(struct acm), GFP_KERNEL); |
1290 | if (acm == NULL) { | 1301 | if (acm == NULL) |
1291 | dev_err(&intf->dev, "out of memory (acm kzalloc)\n"); | ||
1292 | goto alloc_fail; | 1302 | goto alloc_fail; |
1293 | } | ||
1294 | 1303 | ||
1295 | minor = acm_alloc_minor(acm); | 1304 | minor = acm_alloc_minor(acm); |
1296 | if (minor == ACM_TTY_MINORS) { | 1305 | if (minor == ACM_TTY_MINORS) { |
@@ -1329,42 +1338,32 @@ made_compressed_probe: | |||
1329 | acm->quirks = quirks; | 1338 | acm->quirks = quirks; |
1330 | 1339 | ||
1331 | buf = usb_alloc_coherent(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma); | 1340 | buf = usb_alloc_coherent(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma); |
1332 | if (!buf) { | 1341 | if (!buf) |
1333 | dev_err(&intf->dev, "out of memory (ctrl buffer alloc)\n"); | ||
1334 | goto alloc_fail2; | 1342 | goto alloc_fail2; |
1335 | } | ||
1336 | acm->ctrl_buffer = buf; | 1343 | acm->ctrl_buffer = buf; |
1337 | 1344 | ||
1338 | if (acm_write_buffers_alloc(acm) < 0) { | 1345 | if (acm_write_buffers_alloc(acm) < 0) |
1339 | dev_err(&intf->dev, "out of memory (write buffer alloc)\n"); | ||
1340 | goto alloc_fail4; | 1346 | goto alloc_fail4; |
1341 | } | ||
1342 | 1347 | ||
1343 | acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL); | 1348 | acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL); |
1344 | if (!acm->ctrlurb) { | 1349 | if (!acm->ctrlurb) |
1345 | dev_err(&intf->dev, "out of memory (ctrlurb kmalloc)\n"); | ||
1346 | goto alloc_fail5; | 1350 | goto alloc_fail5; |
1347 | } | 1351 | |
1348 | for (i = 0; i < num_rx_buf; i++) { | 1352 | for (i = 0; i < num_rx_buf; i++) { |
1349 | struct acm_rb *rb = &(acm->read_buffers[i]); | 1353 | struct acm_rb *rb = &(acm->read_buffers[i]); |
1350 | struct urb *urb; | 1354 | struct urb *urb; |
1351 | 1355 | ||
1352 | rb->base = usb_alloc_coherent(acm->dev, readsize, GFP_KERNEL, | 1356 | rb->base = usb_alloc_coherent(acm->dev, readsize, GFP_KERNEL, |
1353 | &rb->dma); | 1357 | &rb->dma); |
1354 | if (!rb->base) { | 1358 | if (!rb->base) |
1355 | dev_err(&intf->dev, "out of memory " | ||
1356 | "(read bufs usb_alloc_coherent)\n"); | ||
1357 | goto alloc_fail6; | 1359 | goto alloc_fail6; |
1358 | } | ||
1359 | rb->index = i; | 1360 | rb->index = i; |
1360 | rb->instance = acm; | 1361 | rb->instance = acm; |
1361 | 1362 | ||
1362 | urb = usb_alloc_urb(0, GFP_KERNEL); | 1363 | urb = usb_alloc_urb(0, GFP_KERNEL); |
1363 | if (!urb) { | 1364 | if (!urb) |
1364 | dev_err(&intf->dev, | ||
1365 | "out of memory (read urbs usb_alloc_urb)\n"); | ||
1366 | goto alloc_fail6; | 1365 | goto alloc_fail6; |
1367 | } | 1366 | |
1368 | urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 1367 | urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
1369 | urb->transfer_dma = rb->dma; | 1368 | urb->transfer_dma = rb->dma; |
1370 | if (acm->is_int_ep) { | 1369 | if (acm->is_int_ep) { |
@@ -1389,11 +1388,8 @@ made_compressed_probe: | |||
1389 | struct acm_wb *snd = &(acm->wb[i]); | 1388 | struct acm_wb *snd = &(acm->wb[i]); |
1390 | 1389 | ||
1391 | snd->urb = usb_alloc_urb(0, GFP_KERNEL); | 1390 | snd->urb = usb_alloc_urb(0, GFP_KERNEL); |
1392 | if (snd->urb == NULL) { | 1391 | if (snd->urb == NULL) |
1393 | dev_err(&intf->dev, | ||
1394 | "out of memory (write urbs usb_alloc_urb)\n"); | ||
1395 | goto alloc_fail7; | 1392 | goto alloc_fail7; |
1396 | } | ||
1397 | 1393 | ||
1398 | if (usb_endpoint_xfer_int(epwrite)) | 1394 | if (usb_endpoint_xfer_int(epwrite)) |
1399 | usb_fill_int_urb(snd->urb, usb_dev, | 1395 | usb_fill_int_urb(snd->urb, usb_dev, |