Re: [PATCH 37/69] ALSA: usx2y: check for failure of usb_alloc_urb()

From: Jaroslav Kysela
Date: Mon May 03 2021 - 16:34:01 EST


Dne 03. 05. 21 v 13:57 Greg Kroah-Hartman napsal(a):
> While it is almost impossible to hit an error calling usb_alloc_urb(),
> to make systems like syzbot which does error injection, and some static
> analysis tools happy, properly handle errors on this path by unwinding
> the previously allocated urbs and freeing them.

Perhaps, I miss something, but this revert and add the cleanup to the wrong
place makes things worse:

The usb_stream_free() is called when init_urbs() fails (returns an error), so
all urbs are freed there and pointers are reset to NULL. Your code frees urbs
twice on an allocation error.

The reverted code does the job better.

Jaroslav

> Cc: Takashi Iwai <tiwai@xxxxxxx>
> Cc: Jaroslav Kysela <perex@xxxxxxxx>
> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
> ---
> sound/usb/usx2y/usb_stream.c | 21 +++++++++++++++++++--
> 1 file changed, 19 insertions(+), 2 deletions(-)
>
> diff --git a/sound/usb/usx2y/usb_stream.c b/sound/usb/usx2y/usb_stream.c
> index 6bba17bf689a..1091ea96a29a 100644
> --- a/sound/usb/usx2y/usb_stream.c
> +++ b/sound/usb/usx2y/usb_stream.c
> @@ -88,18 +88,35 @@ static int init_urbs(struct usb_stream_kernel *sk, unsigned use_packsize,
> sizeof(struct usb_stream_packet) *
> s->inpackets;
> int u;
> + int i;
> + int err = -ENOMEM;
>
> for (u = 0; u < USB_STREAM_NURBS; ++u) {
> + sk->outurb[u] = NULL;
> sk->inurb[u] = usb_alloc_urb(sk->n_o_ps, GFP_KERNEL);
> + if (!sk->inurb[u])
> + goto error;
> sk->outurb[u] = usb_alloc_urb(sk->n_o_ps, GFP_KERNEL);
> + if (!sk->outurb[u])
> + goto error;
> }
> + u--;
>
> if (init_pipe_urbs(sk, use_packsize, sk->inurb, indata, dev, in_pipe) ||
> init_pipe_urbs(sk, use_packsize, sk->outurb, sk->write_page, dev,
> - out_pipe))
> - return -EINVAL;
> + out_pipe)) {
> + err = -EINVAL;
> + goto error;
> + }
>
> return 0;
> +
> +error:
> + for (i = 0; i <= u; ++i) {
> + usb_free_urb(sk->inurb[i]);
> + usb_free_urb(sk->outurb[i]);
> + }
> + return err;
>

--
Jaroslav Kysela <perex@xxxxxxxx>
Linux Sound Maintainer; ALSA Project; Red Hat, Inc.