From nobody Mon Jun 8 09:49:04 2026 Received: from mail-pl1-f179.google.com (mail-pl1-f179.google.com [209.85.214.179]) (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 2B8DB36A36B for ; Thu, 4 Jun 2026 09:48:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780566503; cv=none; b=A3BbDc1JN2r984cSuKGGObYL1XCDiq+JBZ7dDqWI/teWD68dMLSE9i5M3dmiJmv+fMlV6/DKhANm68KR5fvUNPT6AL1V8edXKCycmCsZUm7Xdr5pYWSimiDGA3Pj3gmnkc20Y3aGqIum4m2LRoigQDmiZC6kIUBaQfiqQhUnZME= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780566503; c=relaxed/simple; bh=9XUhj/aQhEbqF1QEgvqMf1sfpXb4ZTg9F7SIZs8KIjQ=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=Psfqqrt/xKLBHsqFUV7I5hlWhrsgVEGii3G7iJm2jCegVz41vxV/B2xRvxNkOF9pmo94zQQEJKOODbwj3IugjJShMbuMpc8YmB2opTgIrW4myDcuMat+1DYbRBB+prVBqFKVNVumRP126xXtwxvpJPcKVniUbcTp3d44maS3jM8= 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=pbNofXeM; arc=none smtp.client-ip=209.85.214.179 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="pbNofXeM" Received: by mail-pl1-f179.google.com with SMTP id d9443c01a7336-2c0c2a68d01so3463195ad.1 for ; Thu, 04 Jun 2026 02:48:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780566501; x=1781171301; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:from:to:cc:subject:date:message-id:reply-to; bh=36+Jo+RZnwMrw4XLYpXyQIN+lhgu1dY7S7BmHTngUjs=; b=pbNofXeM6unGgEM3NgrfKAH0ILq/fKnVty6fQ7BDmkvk1pE8udDUuR3AwMkXnHGOo/ y4kbUa+zuCl5YmKgQ8xtydx4I9Deq+o4ciXlYC6bXBIuZ6tqG9tW4/eLxzGrs+obDadM 0k+I6YU8wsTTeRtmBi2eIEIq9ofvjRxBZLvFShRcCHA8Pr9M2uSJiYSVFsJEYAQTO3r7 c3HEna70meNspskuAx2Fnd9d1XzgbHi984wwN0Df5R7nqv010vlVHJkfHHkgIPNsV3X1 +NmZCJAKmfuB0iQ5bPFr/5Vk+vbS9iMElQf6hVy06voch5LGNoojBL1mplvDjjLzI9h6 e4fg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780566501; x=1781171301; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=36+Jo+RZnwMrw4XLYpXyQIN+lhgu1dY7S7BmHTngUjs=; b=P2ms6qld7ticKg9Mofim1cFVKul2KMAoTieGmsoMjvnnVlaHv3VstDMdERjGNySA9Z bH0+4s/KJg/EOyatfUMlcXixoSSd3c4DXd+UfJrBGg2v9WSz+Bdg9B8vDHUmqKf+28q5 OQiwYK4ZoIZBh5pyT86xYlHWRXV2zuZrCyS5U3v3dXBWOOzn/7DFll4avHxPepf8elwx 3/ezhl4hFSIrO4F5rc/Fcp2PHhM9liO1Pl0+kqob/Xe3vBHbf2e+ppmRhG3olrtPtO7U meI+A7qG+HwCYY4clViB+cgEImgILuzV6tajOVN1FUKdSGux/Um2JQbwsUQjYIBwW78r /bqw== X-Forwarded-Encrypted: i=1; AFNElJ8Q3CJa3MFhKeHknK9dqyhK2NPyiWkiZspn1ahgWs4Oxt/UeHe2pVvaDNGvSmOVaETPwMaLMW9HYa+GNS4=@vger.kernel.org X-Gm-Message-State: AOJu0YyJ+oA+BmLOeoe8HQ6m/w/Lug8QjJGmZ19gglAk+qI5bmnR33av LOYdZnDep8uTRI7ulSoUmpO7X1OqhfGR1YnXBeXwRb/aUYefh/PhGerQ X-Gm-Gg: Acq92OHr+9Hm+moieVLSnROz/wlppBvGCVkEYqT1Fo+owmw1/RdeDeYSTVX4Z+t45jp mEO9zvaeFbu/GTNoA6sVIspRajfKtwEAjy0KzLMU3fLq5WdWzOAgXIUDX7+5WDM2R1sXQ5vKaG7 6MZOOXgWdi+L/eC3108QrLkJDCOSWPf1J3HR5eMaeKazCSd/ilkhyZ90tVp3PGrfGhiaGpqeWim hMi9umstvzRUYrOkY0WD6rBgQuo8DWs/kmHITWfp3CmUX2Yc6MrtNYiUGQXenXkOZQrVML4b0dD 7H/ARQpElQcXHW9w1Yfmsrmbinkia1FhDNf2JOyydrlt73KuIRYSv7HwpW7IffKqoJ4xGLM44bA 8rrpJ8uXC7Sfar3wC0bGA9n9pf6x9qcZF99glsGjhvIHSjcZ/MGM/35WjIlSaoEOrdPHHoizCij tMiWWjMEuMleGDCigQymk7w5XlHSNQulB51Q== X-Received: by 2002:a17:902:d4c7:b0:2bd:606d:b339 with SMTP id d9443c01a7336-2c1644a9b5fmr73325875ad.21.1780566501251; Thu, 04 Jun 2026 02:48:21 -0700 (PDT) Received: from lgs.. ([101.36.111.22]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2c164fa00b3sm50627395ad.32.2026.06.04.02.48.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Jun 2026 02:48:20 -0700 (PDT) From: Guangshuo Li To: Ulf Hansson , Johan Hovold , Thomas Gleixner , Ingo Molnar , Guangshuo Li , Binbin Zhou , Yang Yingliang , linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2] mmc: vub300: fix use-after-free on probe failure Date: Thu, 4 Jun 2026 17:48:01 +0800 Message-ID: <20260604094801.1418367-1-lgs201920130244@gmail.com> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The vub300 driver lifetime-manages its controller state using vub300->kref, with vub300_delete() freeing the mmc host when the last reference is dropped. The probe error path after the inactivity timer has been armed still bypasses that lifetime rule, however, and falls through to mmc_free_host() directly if mmc_add_host() fails. The race window is between arming the inactivity timer and reaching the probe error unwind after mmc_add_host() fails: probe thread timer/workqueue ------------ --------------- kref_init(&vub300->kref) ref =3D 1 kref_get(&vub300->kref) ref =3D 2, timer ref add_timer(inactivity_timer) | | race window |<----------------------------------------------------> | mmc_add_host(mmc) inactivity timer fires vub300_queue_dead_work() kref_get() ref =3D 3 queue_work(deadwork) mmc_add_host() fails timer_delete_sync() mmc_free_host(mmc) frees vub300 deadwork runs use-after-free timer_delete_sync() only waits for the timer callback itself. It does not flush deadwork that the callback may already have queued. As a result, queued deadwork can still hold a kref while the probe error path directly frees the backing mmc host, including the vub300 storage. Fix this by making the post-timer probe error path obey the kref lifetime rules. After deleting the inactivity timer, drop both the timer reference and the initial probe reference, and return without falling through to err_free_host. If deadwork was queued, its reference keeps the object alive until the work item drops it; otherwise the final kref_put() runs vub300_delete() and releases the mmc host and USB resources. Fixes: 0613ad2401f8 ("mmc: vub300: fix return value check of mmc_add_host()= ") Signed-off-by: Guangshuo Li --- v2: - Rebase on current mainline. - Correct the Fixes tag. - Add blank lines around the early return. - Reword the code comment. drivers/mmc/host/vub300.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c index 6c3cb2f1c9d3..1b46bb87f39a 100644 --- a/drivers/mmc/host/vub300.c +++ b/drivers/mmc/host/vub300.c @@ -2342,6 +2342,16 @@ static int vub300_probe(struct usb_interface *interf= ace, =20 err_delete_timer: timer_delete_sync(&vub300->inactivity_timer); + /* + * vub300 may have async references via queued deadwork. Drop the + * timer and initial references and let the last kref put release the + * host through the proper destructor. + */ + kref_put(&vub300->kref, vub300_delete); /* timer's kref */ + kref_put(&vub300->kref, vub300_delete); /* init's kref */ + + return retval; + err_free_host: mmc_free_host(mmc); /* --=20 2.43.0