From: Evgeny Novikov novikov@ispras.ru
[ 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 | 31 ++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-)
diff --git a/drivers/media/usb/zr364xx/zr364xx.c b/drivers/media/usb/zr364xx/zr364xx.c index c5513f55e64e0..8c8c4c9858507 100644 --- a/drivers/media/usb/zr364xx/zr364xx.c +++ b/drivers/media/usb/zr364xx/zr364xx.c @@ -1357,6 +1357,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)); @@ -1390,9 +1391,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;
@@ -1407,9 +1407,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, @@ -1608,10 +1616,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