From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f182.google.com (mail-pl1-f182.google.com [209.85.214.182]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DB6CF340412 for ; Mon, 8 Jun 2026 08:20:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.182 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780906812; cv=none; b=tB9320XK2t8mGlgkdQYnJh4GwZ65u4w7rX25uf4vvoame95IRpqv+7fLPN1lrNvLGbFCCj3oRy1ftppZe6wY9FBGzsOsdINMYHIECv/xIAePV1TtdzRX1X61+z86bP6sPWLBCKx3AZFt+1riiQq/DG+im9n5RC7QGOrDSk3SWN4= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780906812; c=relaxed/simple; bh=PuUpW8VAfH86IoYd5Si32XGflm9Drp+C687w7ly7Sug=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=i3Ek2J2DcIA/ncRsBHGCgRy7Ewa1dKCRlqIMIaxnyMjIMpfYHVUwO1FPFeCX6Mo0D6ongvpCtClvN7chs/RBdfs3s1A+4aHa2aJ05QycKQ+4UxcsC0B8RM9QtV3O/5JPATnw8OIcrPDTPqrL0pZsWmQa58nw+2Jb46IuJyBXxKo= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=ZS7SByb8; arc=none smtp.client-ip=209.85.214.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ZS7SByb8" Received: by mail-pl1-f182.google.com with SMTP id d9443c01a7336-2bf237e1433so46189065ad.1 for ; Mon, 08 Jun 2026 01:20:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780906805; x=1781511605; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=QaxSxNePW62N/aLYNU2ICZZcrY71w9JpJK96h4Ml418=; b=ZS7SByb8AOgCEG2IXbVOLn4vWo3Kzml6Z6j6mwUHzCHqu2hdbtoMlVz/pgrGTOMrLt hBOtf5WoE2BBNL9S4FBRhko8w+9aLtDSILVJkQOHcnRJ6S9APynwV3fzEY9O+uAWJhkh og7cOTbM706GKAmPniHibRwtqJhLk6EdVJvDJBJ9PGxGvyKBBdrR4Vtna5aNZA8qNFUt Z9aG53QmRVHi2pbuV6qQqmyVRzKVuDxfwQOKNz/GJV5If8dJ3j9caZctd9z0r9wqU6ZB lGfL/QGti3uo0h54q0FQModefVRC7PJUoKqMmWk5Z2SqTkEFgaV7F6A+xv4JXARWfPfg 0YUg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780906805; x=1781511605; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=QaxSxNePW62N/aLYNU2ICZZcrY71w9JpJK96h4Ml418=; b=sOBvwPokaRcI/X98BLcST8+B9FrTmRpF88quLCmVpEo/c34pNbjRLMrli813LF1Xop CbXYJ9jHRvYSCfoVlo3GFriwqAMmuFfQOfRJzRCWvprMlcQ9LHowQlQg8Ur76C4PYlx2 G2rNbLRVt6WM866ydwEO9E3bbDpFV4lTI9Xl40nSNYPgoPl7gWhicB+MBfGhPjJnhGqL rKTP66986MHTjnbVIS+JQbdKK9TEEecCzQYLkAtgG3IDBeJUvItw8j3Zt5JfuMWn83e5 gIBOvlGc7Gvxk9GtgZo5l3UZU26Kt0JfZaUIppk/8fJQ8fgdZ/gZhLzDowy3uQFhL566 RV1w== X-Forwarded-Encrypted: i=1; AFNElJ9j9FGq4LPDSZdOMf3oyBCBQtwvCzTUSCVgNXbjdVwSgdyHKkgOhdYyLGi+qoat560YMZ3LSQ0AtrkjEjY=@vger.kernel.org X-Gm-Message-State: AOJu0YwS5zT/kEqH+yyM2IwJnM95KBvtGIl1r5yXwJShKCktK2X0v51C +S0SaNIcT3dmVgIyMD32xxKHj8leUF+5EcqIUUIwNYIewuBp0T9vt1VTe6sZ5aewNmA= X-Gm-Gg: Acq92OG1jbXkTNmljrnBEtD2H2fqLwbreqZLrgEB1icS3HTxfTOL8y1vobA3zzsql7w h4MVJYcBawnpT5Wv2/Ai0IPv16CMp+fPLTJQHxJafothPJBv16JfHx9/wf4qLKaLekGm6Akvl6N 3OtWNhHLrQwvnC08LTb6NQLXJL/Hr2zAhag8NrlySZ6biifrbhDxyMrn+IXnf/8tHp4UpJ78tPm CrLLrLvIoMLLhBF/yCzYUjpmd6+MACtqHeY/rtUauflkM5N5HIxNaS7Q78REfh8D2budETJfupU 8oC0rdBATWY20EN1MlS+o3SIlkXyARPKyNeip36iLXFn42xg5dcW7s4R7UbZuKLGWPkFcPZxuZQ epeKU7/hUa0404xd657H2gewQa1+7nUMUBUcMDfktSF4jx3IsDHUOfYd8RGwrsthh6KxgK1sxei NXTJ3b+pRAF8LY9w8HHBl92vN2GG9oiFq4zLmzlA3Lw3al9DmHAtXN X-Received: by 2002:a17:903:3c48:b0:2c0:eee2:fc40 with SMTP id d9443c01a7336-2c1e80cede0mr162261145ad.3.1780906804922; Mon, 08 Jun 2026 01:20:04 -0700 (PDT) Received: from haichao.tail057a43.ts.net ([2001:da8:e000:1206:9a2:954d:67fe:d9c2]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2c164fa3a5fsm183050945ad.36.2026.06.08.01.20.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 08 Jun 2026 01:20:04 -0700 (PDT) From: Ruoyu Wang To: Neal Liu , Greg Kroah-Hartman Cc: Joel Stanley , Andrew Jeffery , linux-aspeed@lists.ozlabs.org, linux-usb@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Ruoyu Wang Subject: [PATCH] usb: gadget: aspeed_udc: check endpoint DMA allocation Date: Mon, 8 Jun 2026 16:19:48 +0800 Message-ID: <20260608081948.3-1-ruoyuw560@gmail.com> X-Mailer: git-send-email 2.51.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit ast_udc_probe() allocates a coherent DMA buffer used as the backing store for endpoint buffers. ast_udc_init_ep() derives per-endpoint buffer pointers from udc->ep0_buf, so a failed allocation is dereferenced during probe. Check the allocation before endpoint setup. The existing probe error path called ast_udc_remove(), which unregisters the gadget unconditionally and is not safe before usb_add_gadget_udc() succeeds. Add a local cleanup helper for probe failures so pre-registration failures only unwind the resources that were actually initialized. This was found by a local static analysis checker for unchecked allocator returns while scanning Linux 6.16. The change was checked by applying it to current mainline and by running checkpatch. I do not have access to Aspeed UDC hardware, so no runtime testing was performed. Fixes: 055276c13205 ("usb: gadget: add Aspeed ast2600 udc driver") Signed-off-by: Ruoyu Wang --- Note: a 2022 patch attempted to add only a NULL check for this allocation: https://lore.kernel.org/all/20221213025120.23149-1-jiasheng@iscas.ac.cn/ This version also fixes the probe unwind path so the clock is disabled on allocation failure and usb_del_gadget_udc() is not called before the gadget has been registered. diff --git a/drivers/usb/gadget/udc/aspeed_udc.c b/drivers/usb/gadget/udc/aspeed_udc.c index 7fc6696b7..809a7d5b7 100644 --- a/drivers/usb/gadget/udc/aspeed_udc.c +++ b/drivers/usb/gadget/udc/aspeed_udc.c @@ -1434,11 +1434,34 @@ static void ast_udc_init_hw(struct ast_udc_dev *udc) ast_udc_write(udc, 0, AST_UDC_EP0_CTRL); } +static void ast_udc_cleanup(struct platform_device *pdev) +{ + struct ast_udc_dev *udc = platform_get_drvdata(pdev); + unsigned long flags; + u32 ctrl; + + spin_lock_irqsave(&udc->lock, flags); + + /* Disable upstream port connection */ + ctrl = ast_udc_read(udc, AST_UDC_FUNC_CTRL) & ~USB_UPSTREAM_EN; + ast_udc_write(udc, ctrl, AST_UDC_FUNC_CTRL); + + clk_disable_unprepare(udc->clk); + + spin_unlock_irqrestore(&udc->lock, flags); + + if (udc->ep0_buf) + dma_free_coherent(&pdev->dev, + AST_UDC_EP_DMA_SIZE * AST_UDC_NUM_ENDPOINTS, + udc->ep0_buf, + udc->ep0_buf_dma); + + udc->ep0_buf = NULL; +} + static void ast_udc_remove(struct platform_device *pdev) { struct ast_udc_dev *udc = platform_get_drvdata(pdev); - unsigned long flags; - u32 ctrl; usb_del_gadget_udc(&udc->gadget); if (udc->driver) { @@ -1453,23 +1476,7 @@ static void ast_udc_remove(struct platform_device *pdev) return; } - spin_lock_irqsave(&udc->lock, flags); - - /* Disable upstream port connection */ - ctrl = ast_udc_read(udc, AST_UDC_FUNC_CTRL) & ~USB_UPSTREAM_EN; - ast_udc_write(udc, ctrl, AST_UDC_FUNC_CTRL); - - clk_disable_unprepare(udc->clk); - - spin_unlock_irqrestore(&udc->lock, flags); - - if (udc->ep0_buf) - dma_free_coherent(&pdev->dev, - AST_UDC_EP_DMA_SIZE * AST_UDC_NUM_ENDPOINTS, - udc->ep0_buf, - udc->ep0_buf_dma); - - udc->ep0_buf = NULL; + ast_udc_cleanup(pdev); } static int ast_udc_probe(struct platform_device *pdev) @@ -1523,6 +1530,10 @@ static int ast_udc_probe(struct platform_device *pdev) AST_UDC_EP_DMA_SIZE * AST_UDC_NUM_ENDPOINTS, &udc->ep0_buf_dma, GFP_KERNEL); + if (!udc->ep0_buf) { + rc = -ENOMEM; + goto err_disable_clk; + } udc->gadget.speed = USB_SPEED_UNKNOWN; udc->gadget.max_speed = USB_SPEED_HIGH; @@ -1553,20 +1564,20 @@ static int ast_udc_probe(struct platform_device *pdev) udc->irq = platform_get_irq(pdev, 0); if (udc->irq < 0) { rc = udc->irq; - goto err; + goto err_cleanup; } rc = devm_request_irq(&pdev->dev, udc->irq, ast_udc_isr, 0, KBUILD_MODNAME, udc); if (rc) { dev_err(&pdev->dev, "Failed to request interrupt\n"); - goto err; + goto err_cleanup; } rc = usb_add_gadget_udc(&pdev->dev, &udc->gadget); if (rc) { dev_err(&pdev->dev, "Failed to add gadget udc\n"); - goto err; + goto err_cleanup; } dev_info(&pdev->dev, "Initialized udc in USB%s mode\n", @@ -1574,9 +1585,14 @@ static int ast_udc_probe(struct platform_device *pdev) return 0; +err_disable_clk: + clk_disable_unprepare(udc->clk); + goto err; +err_cleanup: + ast_udc_cleanup(pdev); + goto err; err: dev_err(&pdev->dev, "Failed to udc probe, rc:0x%x\n", rc); - ast_udc_remove(pdev); return rc; } -- 2.51.0