3.16.63-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Nicholas Mc Guire hofrat@osadl.org
commit 4ab2b48c98f2ec9712452d520a381917f91ac3d2 upstream.
The allocation with fsl_alloc_request() and kmalloc() were unchecked fixed this up with a NULL check and appropriate cleanup.
Additionally udc->ep_qh_size was reset to 0 on failure of allocation. Similar udc->phy_mode is initially 0 (as udc_controller was allocated with kzalloc in fsl_udc_probe()) so reset it to 0 as well so that this function is side-effect free on failure. Not clear if this is necessary or sensible as fsl_udc_release() probably can not be called if fsl_udc_probe() failed - but it should not hurt.
Signed-off-by: Nicholas Mc Guire hofrat@osadl.org Fixes: b504882da5 ("USB: add Freescale high-speed USB SOC device controller driver") Signed-off-by: Felipe Balbi felipe.balbi@linux.intel.com [bwh: Backported to 3.16: adjust filename, context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/usb/gadget/fsl_udc_core.c | 30 +++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-)
--- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -2256,8 +2256,10 @@ static int __init struct_udc_setup(struc udc->phy_mode = pdata->phy_mode;
udc->eps = kzalloc(sizeof(struct fsl_ep) * udc->max_ep, GFP_KERNEL); - if (!udc->eps) - return -1; + if (!udc->eps) { + ERR("kmalloc udc endpoint status failed\n"); + goto eps_alloc_failed; + }
/* initialized QHs, take care of alignment */ size = udc->max_ep * sizeof(struct ep_queue_head); @@ -2271,8 +2273,7 @@ static int __init struct_udc_setup(struc &udc->ep_qh_dma, GFP_KERNEL); if (!udc->ep_qh) { ERR("malloc QHs for udc failed\n"); - kfree(udc->eps); - return -1; + goto ep_queue_alloc_failed; }
udc->ep_qh_size = size; @@ -2281,8 +2282,17 @@ static int __init struct_udc_setup(struc /* FIXME: fsl_alloc_request() ignores ep argument */ udc->status_req = container_of(fsl_alloc_request(NULL, GFP_KERNEL), struct fsl_req, req); + if (!udc->status_req) { + ERR("kzalloc for udc status request failed\n"); + goto udc_status_alloc_failed; + } + /* allocate a small amount of memory to get valid address */ udc->status_req->req.buf = kmalloc(8, GFP_KERNEL); + if (!udc->status_req->req.buf) { + ERR("kzalloc for udc request buffer failed\n"); + goto udc_req_buf_alloc_failed; + }
udc->resume_state = USB_STATE_NOTATTACHED; udc->usb_state = USB_STATE_POWERED; @@ -2290,6 +2300,18 @@ static int __init struct_udc_setup(struc udc->remote_wakeup = 0; /* default to 0 on reset */
return 0; + +udc_req_buf_alloc_failed: + kfree(udc->status_req); +udc_status_alloc_failed: + kfree(udc->ep_qh); + udc->ep_qh_size = 0; +ep_queue_alloc_failed: + kfree(udc->eps); +eps_alloc_failed: + udc->phy_mode = 0; + return -1; + }
/*----------------------------------------------------------------