media: gscpa/stv06xx: fix memory leak
authorHans Verkuil <hverkuil-cisco@xs4all.nl>
Thu, 8 Apr 2021 10:31:20 +0000 (12:31 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 11 May 2021 12:47:29 +0000 (14:47 +0200)
[ Upstream commit 4f4e6644cd876c844cdb3bea2dd7051787d5ae25 ]

For two of the supported sensors the stv06xx driver allocates memory which
is stored in sd->sensor_priv. This memory is freed on a disconnect, but if
the probe() fails, then it isn't freed and so this leaks memory.

Add a new probe_error() op that drivers can use to free any allocated
memory in case there was a probe failure.

Thanks to Pavel Skripkin <paskripkin@gmail.com> for discovering the cause
of the memory leak.

Reported-and-tested-by: syzbot+e7f4c64a4248a0340c37@syzkaller.appspotmail.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>
drivers/media/usb/gspca/gspca.c
drivers/media/usb/gspca/gspca.h
drivers/media/usb/gspca/stv06xx/stv06xx.c

index 158c8e2..47d8f28 100644 (file)
@@ -1576,6 +1576,8 @@ out:
 #endif
        v4l2_ctrl_handler_free(gspca_dev->vdev.ctrl_handler);
        v4l2_device_unregister(&gspca_dev->v4l2_dev);
+       if (sd_desc->probe_error)
+               sd_desc->probe_error(gspca_dev);
        kfree(gspca_dev->usb_buf);
        kfree(gspca_dev);
        return ret;
index b0ced2e..a6554d5 100644 (file)
@@ -105,6 +105,7 @@ struct sd_desc {
        cam_cf_op config;       /* called on probe */
        cam_op init;            /* called on probe and resume */
        cam_op init_controls;   /* called on probe */
+       cam_v_op probe_error;   /* called if probe failed, do cleanup here */
        cam_op start;           /* called on stream on after URBs creation */
        cam_pkt_op pkt_scan;
 /* optional operations */
index 95673fc..d9bc2aa 100644 (file)
@@ -529,12 +529,21 @@ static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
 static int stv06xx_config(struct gspca_dev *gspca_dev,
                          const struct usb_device_id *id);
 
+static void stv06xx_probe_error(struct gspca_dev *gspca_dev)
+{
+       struct sd *sd = (struct sd *)gspca_dev;
+
+       kfree(sd->sensor_priv);
+       sd->sensor_priv = NULL;
+}
+
 /* sub-driver description */
 static const struct sd_desc sd_desc = {
        .name = MODULE_NAME,
        .config = stv06xx_config,
        .init = stv06xx_init,
        .init_controls = stv06xx_init_controls,
+       .probe_error = stv06xx_probe_error,
        .start = stv06xx_start,
        .stopN = stv06xx_stopN,
        .pkt_scan = stv06xx_pkt_scan,