From nobody Mon Feb 9 23:22:39 2026 Received: from mail-qt1-f172.google.com (mail-qt1-f172.google.com [209.85.160.172]) (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 05A7A2D876B for ; Wed, 14 Jan 2026 20:32:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=209.85.160.172 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768422754; cv=pass; b=RpLXp1LTbD1wkewWduKYG3jyGffz0xvc6hzNtqU2Vo2X3wGjJfdVgeemM0/LKv8mE//XLzmUi9lcudYBBqoxSjRYURxWTdCQa4ho0xdoB/CVCBV6ueOJNrZX5BSSaxt3nJHUPWZMQ6zwMqH4bd4oeU+JkBgZO2dn2bi3/f7erS0= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768422754; c=relaxed/simple; bh=tVj17GUpQMLRYSUDWQiykbEOTBs0tGD6gwkI7XVaJ+A=; h=MIME-Version:From:Date:Message-ID:Subject:To:Cc:Content-Type; b=T3onM/f3/Djiwg7L5HTgsGTiB/LUeMMToRKA24eH/s4dWs6oNs+sTpnl58sPCyNO6l67M7reNUE0T4htdc/47MVv6kJpZWen5SpAG+Ub6RbEIvn/u+M9nbZt5Rby0gkpEIHcfwPHSNltTrlLSEoJyIXfU2NPBBlhR8yqNfTky9c= ARC-Authentication-Results: i=2; 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=e5FrgORa; arc=pass smtp.client-ip=209.85.160.172 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="e5FrgORa" Received: by mail-qt1-f172.google.com with SMTP id d75a77b69052e-5013c1850bdso1795041cf.0 for ; Wed, 14 Jan 2026 12:32:32 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1768422752; cv=none; d=google.com; s=arc-20240605; b=j7aaRsf8yQS0uE6SUTitUJA/Yq1r0GZo2t7sB7otuDK1RHwwE/VrZZHCb/ftdinY34 PWYcD30Y6mftBW4ssr7dUuIWiF7Q3tw6xfqZj5GzvJte5QY5MhNYfTJgFh6RATPCZpKd PLxsdo8fMAlbHOxT6pZhbhT9MQ4XnZSU5FwAzPJjcy48iKYoVUZ+SC3Q0z28MLEFhpmh vs9GItiblWKw2T36T/aH+dhKh+NlP01ltswQYcoA0z4gSjiXNNLlt5NonrO9vJ7Q03sk HKAOC/8u8sy3PfCxfuLjyJ0X7nhM96rtYCibUl7HcBsaxusJ19wPXofEXWWsxLEvPiOm mF+Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=cc:to:subject:message-id:date:from:mime-version:dkim-signature; bh=PtB1+GiCWWXBQg9l5i9zTk1CK4VEZJWi0P2LjbHs6IQ=; fh=mHQTqrkbEiaboiSxmNejkUoicIOOgGe9lp+3iMQ/4Gc=; b=kJex0HA9UM610V0izTY5tJj/yL3jIEc+gTaoxWKAxJln8FgE+4rZ5nWYNcMudxHC4f A4jC5gUIazJqC7e7N3+coe/F1vqziF9yHg3EOiqoMJ1+IJFkyon/Kk+T9S5qOqH9GmsT g9mxDLn5YNSV1hG8we/eXViw585ZK492/qAQ3ecyz5afP0CNCWCOVMA5fnJGhsE2zHjj NV6EAjE8osiAvZX0DwvQ0hoYBXYJIIpABs2AQJ+D6wlgNMwNpP0XzT1Xgi66VM5pLWk8 w6GLWWVLny8bSOdVsvZG5bKFZd9zmSqd7jauDYzHiJ0X6Xat2iBye/oh9mFuZ6NUttMN kcjA==; darn=vger.kernel.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1768422752; x=1769027552; darn=vger.kernel.org; h=cc:to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=PtB1+GiCWWXBQg9l5i9zTk1CK4VEZJWi0P2LjbHs6IQ=; b=e5FrgORapJB1MpyuNMqGAKnPd+mwSA00qEDvpiviBKAXQebYc/PlLdef4IsWQpmm5Y SXxK3wYnLoTjXjnPdUEV/TgmJFmzjnT13afFKb7/ri5inSyrGH1e+Fjovlm/byIB7tpP 7EeE6nRPoTdqElOwRqhRcJ6We1Tj8YQJiq0wRbSyAy6sy+z+Fu/oxcg/u2ve0qaGZ4Ns hwy49zeKD9PEnndalrnYxvnH1ON2T1xvLnQO8uIA7WADgg0om0p6oFOPwkT8pzobdXDu t3gyf0ymLSJmpBzr65z9KW2s0b60vMKVPBX2UqmJf/UJsLGXz1PqmKRq2XXaz+uxVhGd AwXQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768422752; x=1769027552; h=cc:to:subject:message-id:date:from:mime-version:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=PtB1+GiCWWXBQg9l5i9zTk1CK4VEZJWi0P2LjbHs6IQ=; b=rATqtEXusAq1IRTz/pXUzbvSrhMA4/Taoy7U6+tK0Sp7FKkXSJD5kGIRtyWBGQj9hQ yYePHnU2YNLZcoZJLVzLNkQjHUJLCap/zA3biVBCOhTSqU+SvIeaJhw4NnpxXuUREV/x DO2UFtR66uFs1r9KklFYvSIMI1LpUqa6y4VolZqLfcwd7OOFlDac4nCHKiXP/eXXWOch b+NGEI5abRtP+aLAcU0/4tyJCuiNhUtO7d+SC4vTNEJ5lkamD1yPgRsbWnyyUy6CfrkS ILm1VCaHyN8o25gswvn9A0bVKlqq9N+0Gwp631lFtXpbSRL7ARM4ilJOxV1NqzyIjFk6 namw== X-Forwarded-Encrypted: i=1; AJvYcCUz3estecxWAt2f0piv/Lv4MnMK5pTf+pcyenkyA1R/c1y7SO7kVn1rmsk972BfTG9wFzgy6VXSBVs976I=@vger.kernel.org X-Gm-Message-State: AOJu0YzamHNdpPVvr6944yIi6fMF7NbMN07tQKxczyXEnIzu+gCIohwH UmdfiZ/cCMFbFWBvme4DNaJR3d+Zq+421CBp1AbI/sHDKBojEPxdCZJdI3WJSo46NJ9YNwYZTRh 0yGXTiNycwfDUBNcZjhYZP8OtNylQNA== X-Gm-Gg: AY/fxX7VM74TAAKV/6nO1DWukhuTorTKw1LpLmCIP7u618Q/x3DlEYMv+/6WaCGaIj6 Ifi3WEtcii5APcxLKC6wBWlvY9x5hElATlDWkyBtmyZcW6ud6mBKzdHklmD+rlPQSlp2joILtJ5 v42fzsYHnGzgQruGIJQRbBBfYGlL5DYkbVjoqiJ9tCrfPGVus8duii+q/+ODtnrcrL/DQgHIKUl 6KVvJkzpB6rUWz7KoiwTnx1um/gw5eO3ho5Zc72QLBtqqayr7SBgFUTJh5+zJUhXTmI+g== X-Received: by 2002:ac8:7e8b:0:b0:501:5233:2a6f with SMTP id d75a77b69052e-50234f774f1mr3383941cf.14.1768422751762; Wed, 14 Jan 2026 12:32:31 -0800 (PST) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: =?UTF-8?B?6b2Q5p+v5a6H?= Date: Thu, 15 Jan 2026 04:32:21 +0800 X-Gm-Features: AZwV_QhvetgktZFjMdOgMWnRgnHfU_QNiUm28bh3uJfXYmrsYJEDfO45ZOPgFhg Message-ID: Subject: [PATCH] usb: cdns2: fix use-after-free in cdns2_gadget_giveback To: pawell@cadence.com, gregkh@linuxfoundation.org Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This fix addresses a use-after-free vulnerability discovered through static code analysis of the cdns2_gadget_giveback() function. The vulnerability exists because after usb_gadget_giveback_request() is called, the code continues to access request->buf. However, usb_gadget_giveback_request() invokes the request's complete callback, and certain gadget function drivers (such as FunctionFS with DMABUF) may directly free the request within this callback. Call flow leading to use-after-free: cdns2_gadget_giveback() -> usb_gadget_giveback_request() -> request->complete() [e.g., ffs_epfile_dmabuf_io_complete] -> usb_ep_free_request() // request is freed here -> if (request->buf =3D=3D pdev->zlp_buf) // UAF: accessing freed memo= ry -> cdns2_gadget_ep_free_request() // potential double-free Data flow analysis shows that this vulnerability can be triggered when: 1. A user application uses FunctionFS with DMABUF transfer capability 2. The user attaches a DMABUF via FUNCTIONFS_DMABUF_ATTACH ioctl 3. The user initiates a transfer via FUNCTIONFS_DMABUF_TRANSFER ioctl 4. Upon transfer completion, ffs_epfile_dmabuf_io_complete() is called as the complete callback, which frees the request 5. cdns2_gadget_giveback() then accesses the freed request->buf field Evidence that complete callback can free the request (f_fs.c): static void ffs_epfile_dmabuf_io_complete(struct usb_ep *ep, struct usb_request *req) { ffs_dmabuf_signal_done(req->context, req->status); usb_ep_free_request(ep, req); // frees the request directly } The fix saves the ZLP check result before calling the complete callback and uses mutually exclusive logic: requests with complete callbacks are owned by the gadget function driver, while only ZLP requests without complete callbacks are freed by the UDC driver. Fixes: 3eb1f1efe204 ("usb: cdns2: Add main part of Cadence USBHS driver") Signed-off-by: Kery Qi --- drivers/usb/gadget/udc/cdns2/cdns2-gadget.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/udc/cdns2/cdns2-gadget.c b/drivers/usb/gadget/udc/cdns2/cdns2-gadget.c index 9b53daf76583..8997623cca5a 100644 --- a/drivers/usb/gadget/udc/cdns2/cdns2-gadget.c +++ b/drivers/usb/gadget/udc/cdns2/cdns2-gadget.c @@ -240,6 +240,7 @@ void cdns2_gadget_giveback(struct cdns2_endpoint *pep, { struct usb_request *request =3D &preq->request; struct cdns2_device *pdev =3D pep->pdev; + bool is_zlp =3D (request->buf =3D=3D pdev->zlp_buf); list_del_init(&preq->list); @@ -257,10 +258,14 @@ void cdns2_gadget_giveback(struct cdns2_endpoint *pep, spin_unlock(&pdev->lock); usb_gadget_giveback_request(&pep->endpoint, request); spin_lock(&pdev->lock); - } - - if (request->buf =3D=3D pdev->zlp_buf) + } else if (is_zlp) { + /* + * Only ZLP requests without a complete callback are freed + * by the driver. Requests with complete callbacks are + * owned by the gadget function driver. + */ cdns2_gadget_ep_free_request(&pep->endpoint, request); + } } static void cdns2_wa1_restore_cycle_bit(struct cdns2_endpoint *pep) --=20 2.34.1