diff options
author | Pavel Skripkin <paskripkin@gmail.com> | 2021-04-21 21:43:45 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-07-20 16:22:32 +0200 |
commit | 0ee999c20f18b9849ac2a18307a55be2569824c2 (patch) | |
tree | fb12f3ca98bb30f79018d6c50ca63041f3400660 /drivers | |
parent | f715d669c8983d3429e6fdee1388941bf169e70d (diff) |
media: cpia2: fix memory leak in cpia2_usb_probe
[ Upstream commit be8656e62e9e791837b606a027802b504a945c97 ]
syzbot reported leak in cpia2 usb driver. The problem was
in invalid error handling.
v4l2_device_register() is called in cpia2_init_camera_struct(), but
all error cases after cpia2_init_camera_struct() did not call the
v4l2_device_unregister()
Reported-by: syzbot+d1e69c888f0d3866ead4@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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/usb/cpia2/cpia2.h | 1 | ||||
-rw-r--r-- | drivers/media/usb/cpia2/cpia2_core.c | 12 | ||||
-rw-r--r-- | drivers/media/usb/cpia2/cpia2_usb.c | 13 |
3 files changed, 20 insertions, 6 deletions
diff --git a/drivers/media/usb/cpia2/cpia2.h b/drivers/media/usb/cpia2/cpia2.h index cdef677d57ec..80a7af6482ae 100644 --- a/drivers/media/usb/cpia2/cpia2.h +++ b/drivers/media/usb/cpia2/cpia2.h @@ -442,6 +442,7 @@ int cpia2_send_command(struct camera_data *cam, struct cpia2_command *cmd); int cpia2_do_command(struct camera_data *cam, unsigned int command, unsigned char direction, unsigned char param); +void cpia2_deinit_camera_struct(struct camera_data *cam, struct usb_interface *intf); struct camera_data *cpia2_init_camera_struct(struct usb_interface *intf); int cpia2_init_camera(struct camera_data *cam); int cpia2_allocate_buffers(struct camera_data *cam); diff --git a/drivers/media/usb/cpia2/cpia2_core.c b/drivers/media/usb/cpia2/cpia2_core.c index 187012ce444b..35c9e00267d5 100644 --- a/drivers/media/usb/cpia2/cpia2_core.c +++ b/drivers/media/usb/cpia2/cpia2_core.c @@ -2162,6 +2162,18 @@ static void reset_camera_struct(struct camera_data *cam) * * cpia2_init_camera_struct * + * Deinitialize camera struct + *****************************************************************************/ +void cpia2_deinit_camera_struct(struct camera_data *cam, struct usb_interface *intf) +{ + v4l2_device_unregister(&cam->v4l2_dev); + kfree(cam); +} + +/****************************************************************************** + * + * cpia2_init_camera_struct + * * Initializes camera struct, does not call reset to fill in defaults. *****************************************************************************/ struct camera_data *cpia2_init_camera_struct(struct usb_interface *intf) diff --git a/drivers/media/usb/cpia2/cpia2_usb.c b/drivers/media/usb/cpia2/cpia2_usb.c index 76b9cb940b87..7bd50feadfe4 100644 --- a/drivers/media/usb/cpia2/cpia2_usb.c +++ b/drivers/media/usb/cpia2/cpia2_usb.c @@ -835,15 +835,13 @@ static int cpia2_usb_probe(struct usb_interface *intf, ret = set_alternate(cam, USBIF_CMDONLY); if (ret < 0) { ERR("%s: usb_set_interface error (ret = %d)\n", __func__, ret); - kfree(cam); - return ret; + goto alt_err; } if((ret = cpia2_init_camera(cam)) < 0) { ERR("%s: failed to initialize cpia2 camera (ret = %d)\n", __func__, ret); - kfree(cam); - return ret; + goto alt_err; } LOG(" CPiA Version: %d.%02d (%d.%d)\n", cam->params.version.firmware_revision_hi, @@ -863,11 +861,14 @@ static int cpia2_usb_probe(struct usb_interface *intf, ret = cpia2_register_camera(cam); if (ret < 0) { ERR("%s: Failed to register cpia2 camera (ret = %d)\n", __func__, ret); - kfree(cam); - return ret; + goto alt_err; } return 0; + +alt_err: + cpia2_deinit_camera_struct(cam, intf); + return ret; } /****************************************************************************** |