media: drivers/media/usb: fix memory leak in zr364xx_probe
[ Upstream commit 9c39be40c0155c43343f53e3a439290c0fec5542 ] syzbot reported memory leak in zr364xx_probe()[1]. The problem was in invalid error handling order. All error conditions rigth after v4l2_ctrl_handler_init() must call v4l2_ctrl_handler_free(). Reported-by: syzbot+efe9aefc31ae1e6f7675@syzkaller.appspotmail.com Signed-off-by: Pavel Skripkin <paskripkin@gmail.com> 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>
This commit is contained in:

committed by
Sasha Levin

parent
56320b1ad4
commit
ff2fc9e4aa
@@ -1433,7 +1433,7 @@ static int zr364xx_probe(struct usb_interface *intf,
|
|||||||
if (hdl->error) {
|
if (hdl->error) {
|
||||||
err = hdl->error;
|
err = hdl->error;
|
||||||
dev_err(&udev->dev, "couldn't register control\n");
|
dev_err(&udev->dev, "couldn't register control\n");
|
||||||
goto unregister;
|
goto free_hdlr_and_unreg_dev;
|
||||||
}
|
}
|
||||||
/* save the init method used by this camera */
|
/* save the init method used by this camera */
|
||||||
cam->method = id->driver_info;
|
cam->method = id->driver_info;
|
||||||
@@ -1506,7 +1506,7 @@ static int zr364xx_probe(struct usb_interface *intf,
|
|||||||
if (!cam->read_endpoint) {
|
if (!cam->read_endpoint) {
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
dev_err(&intf->dev, "Could not find bulk-in endpoint\n");
|
dev_err(&intf->dev, "Could not find bulk-in endpoint\n");
|
||||||
goto unregister;
|
goto free_hdlr_and_unreg_dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* v4l */
|
/* v4l */
|
||||||
@@ -1518,7 +1518,7 @@ static int zr364xx_probe(struct usb_interface *intf,
|
|||||||
/* load zr364xx board specific */
|
/* load zr364xx board specific */
|
||||||
err = zr364xx_board_init(cam);
|
err = zr364xx_board_init(cam);
|
||||||
if (err)
|
if (err)
|
||||||
goto unregister;
|
goto free_hdlr_and_unreg_dev;
|
||||||
err = v4l2_ctrl_handler_setup(hdl);
|
err = v4l2_ctrl_handler_setup(hdl);
|
||||||
if (err)
|
if (err)
|
||||||
goto board_uninit;
|
goto board_uninit;
|
||||||
@@ -1536,7 +1536,7 @@ static int zr364xx_probe(struct usb_interface *intf,
|
|||||||
err = video_register_device(&cam->vdev, VFL_TYPE_VIDEO, -1);
|
err = video_register_device(&cam->vdev, VFL_TYPE_VIDEO, -1);
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_err(&udev->dev, "video_register_device failed\n");
|
dev_err(&udev->dev, "video_register_device failed\n");
|
||||||
goto free_handler;
|
goto board_uninit;
|
||||||
}
|
}
|
||||||
cam->v4l2_dev.release = zr364xx_release;
|
cam->v4l2_dev.release = zr364xx_release;
|
||||||
|
|
||||||
@@ -1544,11 +1544,10 @@ static int zr364xx_probe(struct usb_interface *intf,
|
|||||||
video_device_node_name(&cam->vdev));
|
video_device_node_name(&cam->vdev));
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
free_handler:
|
|
||||||
v4l2_ctrl_handler_free(hdl);
|
|
||||||
board_uninit:
|
board_uninit:
|
||||||
zr364xx_board_uninit(cam);
|
zr364xx_board_uninit(cam);
|
||||||
unregister:
|
free_hdlr_and_unreg_dev:
|
||||||
|
v4l2_ctrl_handler_free(hdl);
|
||||||
v4l2_device_unregister(&cam->v4l2_dev);
|
v4l2_device_unregister(&cam->v4l2_dev);
|
||||||
free_cam:
|
free_cam:
|
||||||
kfree(cam);
|
kfree(cam);
|
||||||
|
Reference in New Issue
Block a user