usb: gadget: uvc: preserve the address passed to kfree()
authorAndrzej Pietrasiewicz <andrzej.p@samsung.com>
Fri, 16 Jan 2015 14:14:27 +0000 (15:14 +0100)
committerFelipe Balbi <balbi@ti.com>
Mon, 19 Jan 2015 18:54:22 +0000 (12:54 -0600)
__uvcg_fill_strm() called from __uvcg_iter_stream_cls()
might have advanced the "data" even if __uvcg_iter_stream_cls()
returns an error, so use a backup copy as an argument to kfree().

Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
drivers/usb/gadget/function/uvc_configfs.c

index cc2a6139b2c8314f8c15e75b7467be707ab5352d..49f25e806e386fd1b83ed9cadade9c1b3a4a1747 100644 (file)
@@ -2086,7 +2086,7 @@ static int uvcg_streaming_class_allow_link(struct config_item *src,
        struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
        struct uvc_descriptor_header ***class_array, **cl_arr;
        struct uvcg_streaming_header *target_hdr;
-       void *data;
+       void *data, *data_save;
        size_t size = 0, count = 0;
        int ret = -EINVAL;
 
@@ -2119,7 +2119,7 @@ static int uvcg_streaming_class_allow_link(struct config_item *src,
                goto unlock;
        }
 
-       data = kzalloc(size, GFP_KERNEL);
+       data = data_save = kzalloc(size, GFP_KERNEL);
        if (!data) {
                kfree(*class_array);
                *class_array = NULL;
@@ -2132,7 +2132,11 @@ static int uvcg_streaming_class_allow_link(struct config_item *src,
        if (ret) {
                kfree(*class_array);
                *class_array = NULL;
-               kfree(data);
+               /*
+                * __uvcg_fill_strm() called from __uvcg_iter_stream_cls()
+                * might have advanced the "data", so use a backup copy
+                */
+               kfree(data_save);
                goto unlock;
        }
        *cl_arr = (struct uvc_descriptor_header *)&opts->uvc_color_matching;