media: cpia2_usb: first wake up, then free in disconnect [Linux 4.14.136]

This Linux kernel change "media: cpia2_usb: first wake up, then free in disconnect" is included in the Linux 4.14.136 release. This change is authored by Oliver Neukum <oneukum [at] suse.com> on Thu May 9 04:57:09 2019 -0400. The commit for this change in Linux stable tree is 3566a98 (patch) which is from upstream commit eff73de. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream eff73de.

media: cpia2_usb: first wake up, then free in disconnect

commit eff73de2b1600ad8230692f00bc0ab49b166512a upstream.

Kasan reported a use after free in cpia2_usb_disconnect()
It first freed everything and then woke up those waiting.
The reverse order is correct.

Fixes: 6c493f8b28c67 ("[media] cpia2: major overhaul to get it in a working state again")

Signed-off-by: Oliver Neukum <oneukum@suse.com>
Reported-by: syzbot+0c90fc937c84f97d0aa6@syzkaller.appspotmail.com
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

There are 3 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 drivers/media/usb/cpia2/cpia2_usb.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/media/usb/cpia2/cpia2_usb.c b/drivers/media/usb/cpia2/cpia2_usb.c
index 6089036..0964ff5 100644
--- a/drivers/media/usb/cpia2/cpia2_usb.c
+++ b/drivers/media/usb/cpia2/cpia2_usb.c
@@ -901,7 +901,6 @@ static void cpia2_usb_disconnect(struct usb_interface *intf)
    cpia2_unregister_camera(cam);
    v4l2_device_disconnect(&cam->v4l2_dev);
    mutex_unlock(&cam->v4l2_lock);
-   v4l2_device_put(&cam->v4l2_dev);

    if(cam->buffers) {
        DBG("Wakeup waiting processes\n");
@@ -913,6 +912,8 @@ static void cpia2_usb_disconnect(struct usb_interface *intf)
    DBG("Releasing interface\n");
    usb_driver_release_interface(&cpia2_driver, intf);

+   v4l2_device_put(&cam->v4l2_dev);
+
    LOG("CPiA2 camera disconnected.\n");
 }

Leave a Reply

Your email address will not be published. Required fields are marked *