Skip to content

Commit

Permalink
usb: gadget: composite: Fix possible double free memory bug
Browse files Browse the repository at this point in the history
composite_dev_cleanup call from the failure of configfs_composite_bind
frees up the cdev->os_desc_req and cdev->req. If the previous calls of
bind and unbind is successful these will carry stale values.

Consider the below sequence of function calls:
configfs_composite_bind()
        composite_dev_prepare()
                - Allocate cdev->req, cdev->req->buf
        composite_os_desc_req_prepare()
                - Allocate cdev->os_desc_req, cdev->os_desc_req->buf
configfs_composite_unbind()
        composite_dev_cleanup()
                - free the cdev->os_desc_req->buf and cdev->req->buf
Next composition switch
configfs_composite_bind()
        - If it fails goto err_comp_cleanup will call the
	  composite_dev_cleanup() function
        composite_dev_cleanup()
	        - calls kfree up with the stale values of cdev->req->buf and
		  cdev->os_desc_req from the previous configfs_composite_bind
		  call. The free call on these stale values leads to double free.

Hence, Fix this issue by setting request and buffer pointer to NULL after
kfree.

Signed-off-by: Chandana Kishori Chiluveru <[email protected]>
Signed-off-by: Felipe Balbi <[email protected]>
  • Loading branch information
Chandana Kishori Chiluveru authored and felipebalbi committed Oct 27, 2019
1 parent ba3a1a9 commit 1c20c89
Showing 1 changed file with 4 additions and 0 deletions.
4 changes: 4 additions & 0 deletions drivers/usb/gadget/composite.c
Original file line number Diff line number Diff line change
Expand Up @@ -2170,14 +2170,18 @@ void composite_dev_cleanup(struct usb_composite_dev *cdev)
usb_ep_dequeue(cdev->gadget->ep0, cdev->os_desc_req);

kfree(cdev->os_desc_req->buf);
cdev->os_desc_req->buf = NULL;
usb_ep_free_request(cdev->gadget->ep0, cdev->os_desc_req);
cdev->os_desc_req = NULL;
}
if (cdev->req) {
if (cdev->setup_pending)
usb_ep_dequeue(cdev->gadget->ep0, cdev->req);

kfree(cdev->req->buf);
cdev->req->buf = NULL;
usb_ep_free_request(cdev->gadget->ep0, cdev->req);
cdev->req = NULL;
}
cdev->next_string_id = 0;
device_remove_file(&cdev->gadget->dev, &dev_attr_suspended);
Expand Down

0 comments on commit 1c20c89

Please sign in to comment.