When ncm_ubind() executes first then ncm->notify_req is freed before usb_ep_free_request(). This produces use-after-free bug in ncm_close() while we write to ncm->notify_req->buf despite the "if (!req)". To make this sanity check working, we set ncm->notify_req to NULL after each free. Signed-off-by: Milosz Kieronski <milosz.kieronski@xxxxxxxxx> Co-developed-by: Slawek Ignacyk <slawek.ignacyk@xxxxxxxxx> Signed-off-by: Slawek Ignacyk <slawek.ignacyk@xxxxxxxxx> --- drivers/usb/gadget/function/f_ncm.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c index 2d6e76e4cffa..a1a521a69187 100644 --- a/drivers/usb/gadget/function/f_ncm.c +++ b/drivers/usb/gadget/function/f_ncm.c @@ -1526,10 +1526,13 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f) kfree(f->os_desc_table); f->os_desc_n = 0; + spin_lock(&ncm->lock); if (ncm->notify_req) { kfree(ncm->notify_req->buf); usb_ep_free_request(ncm->notify, ncm->notify_req); + ncm->notify_req = NULL; } + spin_unlock(&ncm->lock); ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); @@ -1649,8 +1652,11 @@ static void ncm_unbind(struct usb_configuration *c, struct usb_function *f) ncm_string_defs[0].id = 0; usb_free_all_descriptors(f); + spin_lock(&ncm->lock); kfree(ncm->notify_req->buf); usb_ep_free_request(ncm->notify, ncm->notify_req); + ncm->notify_req = NULL; + spin_unlock(&ncm->lock); } static struct usb_function *ncm_alloc(struct usb_function_instance *fi) -- 2.17.1