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>
This commit is contained in:
parent
2a4340c577
commit
738d9edcfd
|
@ -1282,6 +1282,7 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi *umidi,
|
|||
unsigned int pipe;
|
||||
int length;
|
||||
unsigned int i;
|
||||
int err;
|
||||
|
||||
rep->in = NULL;
|
||||
ep = kzalloc(sizeof(*ep), GFP_KERNEL);
|
||||
|
@ -1292,8 +1293,8 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi *umidi,
|
|||
for (i = 0; i < INPUT_URBS; ++i) {
|
||||
ep->urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (!ep->urbs[i]) {
|
||||
snd_usbmidi_in_endpoint_delete(ep);
|
||||
return -ENOMEM;
|
||||
err = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
if (ep_info->in_interval)
|
||||
|
@ -1305,8 +1306,8 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi *umidi,
|
|||
buffer = usb_alloc_coherent(umidi->dev, length, GFP_KERNEL,
|
||||
&ep->urbs[i]->transfer_dma);
|
||||
if (!buffer) {
|
||||
snd_usbmidi_in_endpoint_delete(ep);
|
||||
return -ENOMEM;
|
||||
err = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
if (ep_info->in_interval)
|
||||
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,
|
|||
pipe, buffer, length,
|
||||
snd_usbmidi_in_urb_complete, ep);
|
||||
ep->urbs[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
|
||||
err = usb_urb_ep_type_check(ep->urbs[i]);
|
||||
if (err < 0) {
|
||||
dev_err(&umidi->dev->dev, "invalid MIDI in EP %x\n",
|
||||
ep_info->in_ep);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
rep->in = ep;
|
||||
return 0;
|
||||
|
||||
error:
|
||||
snd_usbmidi_in_endpoint_delete(ep);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1357,6 +1368,7 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi *umidi,
|
|||
unsigned int i;
|
||||
unsigned int pipe;
|
||||
void *buffer;
|
||||
int err;
|
||||
|
||||
rep->out = NULL;
|
||||
ep = kzalloc(sizeof(*ep), GFP_KERNEL);
|
||||
|
@ -1367,8 +1379,8 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi *umidi,
|
|||
for (i = 0; i < OUTPUT_URBS; ++i) {
|
||||
ep->urbs[i].urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (!ep->urbs[i].urb) {
|
||||
snd_usbmidi_out_endpoint_delete(ep);
|
||||
return -ENOMEM;
|
||||
err = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
ep->urbs[i].ep = ep;
|
||||
}
|
||||
|
@ -1406,8 +1418,8 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi *umidi,
|
|||
ep->max_transfer, GFP_KERNEL,
|
||||
&ep->urbs[i].urb->transfer_dma);
|
||||
if (!buffer) {
|
||||
snd_usbmidi_out_endpoint_delete(ep);
|
||||
return -ENOMEM;
|
||||
err = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
if (ep_info->out_interval)
|
||||
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,
|
|||
pipe, buffer, ep->max_transfer,
|
||||
snd_usbmidi_out_urb_complete,
|
||||
&ep->urbs[i]);
|
||||
err = usb_urb_ep_type_check(ep->urbs[i].urb);
|
||||
if (err < 0) {
|
||||
dev_err(&umidi->dev->dev, "invalid MIDI out EP %x\n",
|
||||
ep_info->out_ep);
|
||||
goto error;
|
||||
}
|
||||
ep->urbs[i].urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
|
||||
}
|
||||
|
||||
|
@ -1437,6 +1455,10 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi *umidi,
|
|||
|
||||
rep->out = ep;
|
||||
return 0;
|
||||
|
||||
error:
|
||||
snd_usbmidi_out_endpoint_delete(ep);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue