diff options
author | Takashi Iwai <tiwai@suse.de> | 2017-10-04 11:22:05 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2017-10-11 09:14:51 -0400 |
commit | 738d9edcfd44f154924692e54109fb439fcf8bdd (patch) | |
tree | 0a1a1681acb0576176c90dca28fac2fa14684d81 | |
parent | 2a4340c57717162c6bf07a0860d05711d4de994b (diff) |
ALSA: usb-audio: Add sanity checks for invalid EPs
USB-audio driver may set up a URB containing the fixed EP without
validating its presence for some non-class-compliant devices. This
may end up with an oops-like kernel warning when submitted.
For avoiding it, this patch adds the call of the new sanity-check
helper for URBs. The checks are needed only for MIDI I/O as the other
places have already some other checks.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | sound/usb/midi.c | 38 |
1 files changed, 30 insertions, 8 deletions
diff --git a/sound/usb/midi.c b/sound/usb/midi.c index a92e2b2a91ec..7ab25de5ca0a 100644 --- a/sound/usb/midi.c +++ b/sound/usb/midi.c | |||
@@ -1282,6 +1282,7 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi *umidi, | |||
1282 | unsigned int pipe; | 1282 | unsigned int pipe; |
1283 | int length; | 1283 | int length; |
1284 | unsigned int i; | 1284 | unsigned int i; |
1285 | int err; | ||
1285 | 1286 | ||
1286 | rep->in = NULL; | 1287 | rep->in = NULL; |
1287 | ep = kzalloc(sizeof(*ep), GFP_KERNEL); | 1288 | ep = kzalloc(sizeof(*ep), GFP_KERNEL); |
@@ -1292,8 +1293,8 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi *umidi, | |||
1292 | for (i = 0; i < INPUT_URBS; ++i) { | 1293 | for (i = 0; i < INPUT_URBS; ++i) { |
1293 | ep->urbs[i] = usb_alloc_urb(0, GFP_KERNEL); | 1294 | ep->urbs[i] = usb_alloc_urb(0, GFP_KERNEL); |
1294 | if (!ep->urbs[i]) { | 1295 | if (!ep->urbs[i]) { |
1295 | snd_usbmidi_in_endpoint_delete(ep); | 1296 | err = -ENOMEM; |
1296 | return -ENOMEM; | 1297 | goto error; |
1297 | } | 1298 | } |
1298 | } | 1299 | } |
1299 | if (ep_info->in_interval) | 1300 | if (ep_info->in_interval) |
@@ -1305,8 +1306,8 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi *umidi, | |||
1305 | buffer = usb_alloc_coherent(umidi->dev, length, GFP_KERNEL, | 1306 | buffer = usb_alloc_coherent(umidi->dev, length, GFP_KERNEL, |
1306 | &ep->urbs[i]->transfer_dma); | 1307 | &ep->urbs[i]->transfer_dma); |
1307 | if (!buffer) { | 1308 | if (!buffer) { |
1308 | snd_usbmidi_in_endpoint_delete(ep); | 1309 | err = -ENOMEM; |
1309 | return -ENOMEM; | 1310 | goto error; |
1310 | } | 1311 | } |
1311 | if (ep_info->in_interval) | 1312 | if (ep_info->in_interval) |
1312 | usb_fill_int_urb(ep->urbs[i], umidi->dev, | 1313 | usb_fill_int_urb(ep->urbs[i], umidi->dev, |
@@ -1318,10 +1319,20 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi *umidi, | |||
1318 | pipe, buffer, length, | 1319 | pipe, buffer, length, |
1319 | snd_usbmidi_in_urb_complete, ep); | 1320 | snd_usbmidi_in_urb_complete, ep); |
1320 | ep->urbs[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP; | 1321 | ep->urbs[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP; |
1322 | err = usb_urb_ep_type_check(ep->urbs[i]); | ||
1323 | if (err < 0) { | ||
1324 | dev_err(&umidi->dev->dev, "invalid MIDI in EP %x\n", | ||
1325 | ep_info->in_ep); | ||
1326 | goto error; | ||
1327 | } | ||
1321 | } | 1328 | } |
1322 | 1329 | ||
1323 | rep->in = ep; | 1330 | rep->in = ep; |
1324 | return 0; | 1331 | return 0; |
1332 | |||
1333 | error: | ||
1334 | snd_usbmidi_in_endpoint_delete(ep); | ||
1335 | return -ENOMEM; | ||
1325 | } | 1336 | } |
1326 | 1337 | ||
1327 | /* | 1338 | /* |
@@ -1357,6 +1368,7 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi *umidi, | |||
1357 | unsigned int i; | 1368 | unsigned int i; |
1358 | unsigned int pipe; | 1369 | unsigned int pipe; |
1359 | void *buffer; | 1370 | void *buffer; |
1371 | int err; | ||
1360 | 1372 | ||
1361 | rep->out = NULL; | 1373 | rep->out = NULL; |
1362 | ep = kzalloc(sizeof(*ep), GFP_KERNEL); | 1374 | ep = kzalloc(sizeof(*ep), GFP_KERNEL); |
@@ -1367,8 +1379,8 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi *umidi, | |||
1367 | for (i = 0; i < OUTPUT_URBS; ++i) { | 1379 | for (i = 0; i < OUTPUT_URBS; ++i) { |
1368 | ep->urbs[i].urb = usb_alloc_urb(0, GFP_KERNEL); | 1380 | ep->urbs[i].urb = usb_alloc_urb(0, GFP_KERNEL); |
1369 | if (!ep->urbs[i].urb) { | 1381 | if (!ep->urbs[i].urb) { |
1370 | snd_usbmidi_out_endpoint_delete(ep); | 1382 | err = -ENOMEM; |
1371 | return -ENOMEM; | 1383 | goto error; |
1372 | } | 1384 | } |
1373 | ep->urbs[i].ep = ep; | 1385 | ep->urbs[i].ep = ep; |
1374 | } | 1386 | } |
@@ -1406,8 +1418,8 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi *umidi, | |||
1406 | ep->max_transfer, GFP_KERNEL, | 1418 | ep->max_transfer, GFP_KERNEL, |
1407 | &ep->urbs[i].urb->transfer_dma); | 1419 | &ep->urbs[i].urb->transfer_dma); |
1408 | if (!buffer) { | 1420 | if (!buffer) { |
1409 | snd_usbmidi_out_endpoint_delete(ep); | 1421 | err = -ENOMEM; |
1410 | return -ENOMEM; | 1422 | goto error; |
1411 | } | 1423 | } |
1412 | if (ep_info->out_interval) | 1424 | if (ep_info->out_interval) |
1413 | usb_fill_int_urb(ep->urbs[i].urb, umidi->dev, | 1425 | usb_fill_int_urb(ep->urbs[i].urb, umidi->dev, |
@@ -1419,6 +1431,12 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi *umidi, | |||
1419 | pipe, buffer, ep->max_transfer, | 1431 | pipe, buffer, ep->max_transfer, |
1420 | snd_usbmidi_out_urb_complete, | 1432 | snd_usbmidi_out_urb_complete, |
1421 | &ep->urbs[i]); | 1433 | &ep->urbs[i]); |
1434 | err = usb_urb_ep_type_check(ep->urbs[i].urb); | ||
1435 | if (err < 0) { | ||
1436 | dev_err(&umidi->dev->dev, "invalid MIDI out EP %x\n", | ||
1437 | ep_info->out_ep); | ||
1438 | goto error; | ||
1439 | } | ||
1422 | ep->urbs[i].urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; | 1440 | ep->urbs[i].urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; |
1423 | } | 1441 | } |
1424 | 1442 | ||
@@ -1437,6 +1455,10 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi *umidi, | |||
1437 | 1455 | ||
1438 | rep->out = ep; | 1456 | rep->out = ep; |
1439 | return 0; | 1457 | return 0; |
1458 | |||
1459 | error: | ||
1460 | snd_usbmidi_out_endpoint_delete(ep); | ||
1461 | return err; | ||
1440 | } | 1462 | } |
1441 | 1463 | ||
1442 | /* | 1464 | /* |