media: zr364xx: propagate errors from zr364xx_start_readpipe()
authorEvgeny Novikov <novikov@ispras.ru>
Tue, 6 Oct 2020 17:21:22 +0000 (19:21 +0200)
committerSasha Levin <sashal@kernel.org>
Thu, 26 Aug 2021 12:35:33 +0000 (08:35 -0400)
[ Upstream commit af0321a5be3e5647441eb6b79355beaa592df97a ]

zr364xx_start_readpipe() can fail but callers do not care about that.
This can result in various negative consequences. The patch adds missed
error handling.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Evgeny Novikov <novikov@ispras.ru>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/media/usb/zr364xx/zr364xx.c

index 1b79053..5c8997d 100644 (file)
@@ -1328,6 +1328,7 @@ static int zr364xx_board_init(struct zr364xx_camera *cam)
 {
        struct zr364xx_pipeinfo *pipe = cam->pipe;
        unsigned long i;
+       int err;
 
        DBG("board init: %p\n", cam);
        memset(pipe, 0, sizeof(*pipe));
@@ -1360,9 +1361,8 @@ static int zr364xx_board_init(struct zr364xx_camera *cam)
 
        if (i == 0) {
                printk(KERN_INFO KBUILD_MODNAME ": out of memory. Aborting\n");
-               kfree(cam->pipe->transfer_buffer);
-               cam->pipe->transfer_buffer = NULL;
-               return -ENOMEM;
+               err = -ENOMEM;
+               goto err_free;
        } else
                cam->buffer.dwFrames = i;
 
@@ -1377,9 +1377,17 @@ static int zr364xx_board_init(struct zr364xx_camera *cam)
        /*** end create system buffers ***/
 
        /* start read pipe */
-       zr364xx_start_readpipe(cam);
+       err = zr364xx_start_readpipe(cam);
+       if (err)
+               goto err_free;
+
        DBG(": board initialized\n");
        return 0;
+
+err_free:
+       kfree(cam->pipe->transfer_buffer);
+       cam->pipe->transfer_buffer = NULL;
+       return err;
 }
 
 static int zr364xx_probe(struct usb_interface *intf,
@@ -1576,10 +1584,19 @@ static int zr364xx_resume(struct usb_interface *intf)
        if (!cam->was_streaming)
                return 0;
 
-       zr364xx_start_readpipe(cam);
+       res = zr364xx_start_readpipe(cam);
+       if (res)
+               return res;
+
        res = zr364xx_prepare(cam);
-       if (!res)
-               zr364xx_start_acquire(cam);
+       if (res)
+               goto err_prepare;
+
+       zr364xx_start_acquire(cam);
+       return 0;
+
+err_prepare:
+       zr364xx_stop_readpipe(cam);
        return res;
 }
 #endif