lkml.org 
[lkml]   [2018]   [Apr]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.9 20/95] USB: gadget: f_midi: fixing a possible double-free in f_midi
    Date
    4.9-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Yavuz, Tuba <tuba@ece.ufl.edu>

    commit 7fafcfdf6377b18b2a726ea554d6e593ba44349f upstream.

    It looks like there is a possibility of a double-free vulnerability on an
    error path of the f_midi_set_alt function in the f_midi driver. If the
    path is feasible then free_ep_req gets called twice:

    req->complete = f_midi_complete;
    err = usb_ep_queue(midi->out_ep, req, GFP_ATOMIC);
    => ...
    usb_gadget_giveback_request
    =>
    f_midi_complete (CALLBACK)
    (inside f_midi_complete, for various cases of status)
    free_ep_req(ep, req); // first kfree
    if (err) {
    ERROR(midi, "%s: couldn't enqueue request: %d\n",
    midi->out_ep->name, err);
    free_ep_req(midi->out_ep, req); // second kfree
    return err;
    }

    The double-free possibility was introduced with commit ad0d1a058eac
    ("usb: gadget: f_midi: fix leak on failed to enqueue out requests").

    Found by MOXCAFE tool.

    Signed-off-by: Tuba Yavuz <tuba@ece.ufl.edu>
    Fixes: ad0d1a058eac ("usb: gadget: f_midi: fix leak on failed to enqueue out requests")
    Acked-by: Felipe Balbi <felipe.balbi@linux.intel.com>
    Cc: stable <stable@vger.kernel.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/usb/gadget/function/f_midi.c | 3 ++-
    drivers/usb/gadget/u_f.h | 2 ++
    2 files changed, 4 insertions(+), 1 deletion(-)

    --- a/drivers/usb/gadget/function/f_midi.c
    +++ b/drivers/usb/gadget/function/f_midi.c
    @@ -389,7 +389,8 @@ static int f_midi_set_alt(struct usb_fun
    if (err) {
    ERROR(midi, "%s: couldn't enqueue request: %d\n",
    midi->out_ep->name, err);
    - free_ep_req(midi->out_ep, req);
    + if (req->buf != NULL)
    + free_ep_req(midi->out_ep, req);
    return err;
    }
    }
    --- a/drivers/usb/gadget/u_f.h
    +++ b/drivers/usb/gadget/u_f.h
    @@ -64,7 +64,9 @@ struct usb_request *alloc_ep_req(struct
    /* Frees a usb_request previously allocated by alloc_ep_req() */
    static inline void free_ep_req(struct usb_ep *ep, struct usb_request *req)
    {
    + WARN_ON(req->buf == NULL);
    kfree(req->buf);
    + req->buf = NULL;
    usb_ep_free_request(ep, req);
    }


    \
     
     \ /
      Last update: 2018-04-22 17:06    [W:3.505 / U:0.340 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site