From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=209.85.215.200 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1794444085; b=bsIKa5OT4RHzMoz7ValLfB3Qhx9imR84v3d8XujpzgHVpx0qcOYRar+SV0rqa9JWUsZ6 Mhr3aUfaUAeQU4EhQkqiJQBQ1+nTLMamPhXW/eAz7wvRAeT33tCNny8GbeJLAc7SKEVb4 hoYUkDHDM9oeVoecDwNruqZucnFLHST7zu0UYOwzb9UJ/E4TMWEBlbuZKByBODMAd/6LW JQ7yFFQ9e7V2q/KFG2qUFoLbNiW1Ly+FVsbeaeNPXEbQvF31DfV5CzbTPMVxUCDVuijRe CVq2+Nxk3E9p4wVfkENhifG03qgWzFMPIDMWiu4T3Qsvcvf91PHPf600Xl7nFH9rYTw== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1794444085; h=DMARC-Filter:Received:DKIM-Signature:X-Google-DKIM-Signature: X-Forwarded-Encrypted:X-Gm-Message-State:X-Received:Date:In-Reply-To: Mime-Version:References:X-Mailer:Message-ID:Subject:From:To:Cc: Content-Type; bh=sFiTj1V9ORohuicZdlyi6G8w7v9+PWw4rbDBBSUy/HI=; b=PCwPZu8lpPwxQUZB8fpmmDwCIcOXHlFYuz1dxbeqTKaKwlTleYnN4KmQK7yOj86+dnAq WvX0f26UA6GkL97ydhct05z5ndxD0Nj39aNieEakuB5a+mx2ez0QzZsMx8FmEYTGazO2U SLJsgmDHPHurqUpGgl1SDBp37sC6QrhZP3Amscsa6naszae5+zb1HODF59xbESq7Ker5X Cz9GIcsJdvDZszp9kISensRqEy1pshp48OExO1peatkYd64v1DuS85G0OmmnwOSGwbnr8 UxqNQbH5UkLhg8ApBTRHpBeQF6CXXPdDr5B4mtMR/1PIoibCKOasLqHYmNUXPGDpFzA== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass header.from=google.com; spf=pass smtp.mailfrom=flex--stanleyjhu.bounces.google.com; dkim=pass header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20260707 header.b=hX0aa1cA; arc=none smtp.remote-ip=209.85.215.200 Received: from mail-pg1-f200.google.com (mail-pg1-f200.google.com [209.85.215.200]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2BA79606A8AD for ; Thu, 12 Nov 2026 00:41:20 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org 2BA79606A8AD Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--stanleyjhu.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20260707 header.b=hX0aa1cA Received: by mail-pg1-f200.google.com with SMTP id 41be03b00d2f7-cd652c0385bso2479601a12.2 for ; Wed, 11 Nov 2026 16:41:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20260707; t=1794444079; x=1795048879; darn=vger.kernel.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:from:to:cc:subject:date:message-id:reply-to :content-type; bh=sFiTj1V9ORohuicZdlyi6G8w7v9+PWw4rbDBBSUy/HI=; b=hX0aa1cAZuU/cWlJiAGzqRhuzmmFjiavmDF1monemszKlOm4RissaytZrtK59qSRwh qvoWzqyuwjvKs2bZV8voXGBbRVhl6FMNE/DVXlPZ0e3P8NvHWQOAe6nnaQNl9LvFfrHP FVqpLqYoUiiLf4xD2PuR+zs6OkVHvhoK3IXUndKvq2TdpcqqAI8vksbQCScUvu+DhbzE qWMB/t9iwVHrp6Ch9izFQjXGvE5Bx/XwCQhIF+DELq/h2003auRjoO/BWO/7r26vsKVw 7L9K8Y/GuXhvulSpB+NtYaRyFvs65BG3WPxS17u7npqu68+mc8ZP8UWfTZydfUvskLtc gF2w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1794444079; x=1795048879; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=sFiTj1V9ORohuicZdlyi6G8w7v9+PWw4rbDBBSUy/HI=; b=f/uATSevXQmc8bev1aq13/z3tApU/0NLTjwwD4JJvKmQ44sXUBYzxWyQjcAgF0AICz 5wBj2CvsDGCUVysjWtsgjHmpsQtGl0h2FC3czXP/CKoM7Wc/vZC983vUyrJ8chdtxe+O 3AAZNFtoQDB4LHlx0O8akOYDtYQiU/MryX32fmd6VwcCW/mnjySdUL3e+RYPSM0F9I0C ZwR6uc6Pk1FGJOTQskS3gjb/br8NlShup6iya28bitq2yyZ4s1af/3ASRDUcbke2REJX zgRAyyCV5VI/drRdi7NI3XSRbVTQCSMbctuMhmhHXWv8gJ5PLBXI4GEdIbfHrZ6XEu7h e3Hw== X-Forwarded-Encrypted: i=1; AL+hErGAz4AZDR3TZJL9tMvq5ywmH3fGaa/4eQ/CUYUNio7F93u6nQExjb52vH9eqxhwsDqw5P7VnKIekVC5xXg=@vger.kernel.org X-Gm-Message-State: APuU4Z8Zprm89+gqD81C1aWBbNp0+ZYRjHH9gN/OhuFguPJwoHNHYBvk 1fC0KbPxzKI3yy5+/OiW4Eh4KQ5P8FGJy1iFFu+vBMomvN13nEC5A+efybFArrheT1QvxqGG3Gf eppsUVWGYfrhC6JrcxRcZGQ== X-Received: from plih6.prod.google.com ([2002:a17:903:37c6:b0:2e8:ac89:717d]) (user=stanleyjhu job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:2710:b0:3a6:f1d2:57f3 with SMTP id 98e67ed59e1d1-3b182fd55a2mr3751521a91.58.1794444079037; Wed, 11 Nov 2026 16:41:19 -0800 (PST) Date: Thu, 12 Nov 2026 08:41:10 +0800 In-Reply-To: <20261112004112.3059801-1-stanleyjhu@google.com> X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list Mime-Version: 1.0 References: <20261112004112.3059801-1-stanleyjhu@google.com> X-Mailer: git-send-email 2.56.0.567.gdb80ae8cd5-goog Message-ID: <20261112004112.3059801-2-stanleyjhu@google.com> Subject: [PATCH v6 1/3] rpmb: core: Guard frame requests and teardown with mutex From: Stanley Jhu To: "Martin K . Petersen" , Jens Wiklander , linux-scsi@vger.kernel.org Cc: Greg Kroah-Hartman , Arnd Bergmann , Bart Van Assche , Avri Altman , Alim Akhtar , Bean Huo , Bean Huo , Alexey Charkov , Can Guo , Ulf Hansson , Linus Walleij , Shyam Saini , "=?UTF-8?q?Alex=20Benn=C3=A9e?=" , "James E . J . Bottomley" , linux-kernel@vger.kernel.org Content-Type: text/plain; charset="UTF-8" rpmb_route_frames() invokes the provider callback without serialization, which causes two races: 1. Concurrent callers on the same rpmb_dev interleave multi-frame authenticated sequences on the region's single result register and receive each other's responses without error. 2. rpmb_dev_unregister() calls device_del() and allows the parent provider device to be freed while an in-flight rpmb_route_frames() call still dereferences rdev->dev.parent, causing a use-after-free. Serialize rpmb_route_frames() and rpmb_dev_unregister() with a mutex in struct rpmb_dev and clear descr.route_frames on unregistration so new requests fail with -ENODEV. Also update the stale kerneldoc note advising providers to unregister from their parent release callback, which cannot run while the child rpmb_dev still holds a parent reference. Fixes: 1e9046e3a154 ("rpmb: add Replay Protected Memory Block (RPMB) subsystem") Cc: stable@vger.kernel.org Signed-off-by: Stanley Jhu --- Jens, if this looks good to you, an Acked-by would let Martin take the whole series through the SCSI tree. Patches 2/3 and 3/3 depend on this one. drivers/misc/rpmb-core.c | 20 ++++++++++++++++++-- include/linux/rpmb.h | 3 +++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/misc/rpmb-core.c b/drivers/misc/rpmb-core.c index ecf14acf230a..0fda893dd74d 100644 --- a/drivers/misc/rpmb-core.c +++ b/drivers/misc/rpmb-core.c @@ -45,6 +45,8 @@ EXPORT_SYMBOL_GPL(rpmb_dev_put); * @rsp: rpmb response frames * @rsp_len: length of rpmb response frames in bytes * + * Context: Might sleep. + * * Returns: < 0 on failure */ int rpmb_route_frames(struct rpmb_dev *rdev, u8 *req, @@ -53,6 +55,10 @@ int rpmb_route_frames(struct rpmb_dev *rdev, u8 *req, if (!req || !req_len || !rsp || !rsp_len) return -EINVAL; + guard(mutex)(&rdev->lock); + if (!rdev->descr.route_frames) + return -ENODEV; + return rdev->descr.route_frames(rdev->dev.parent, req, req_len, rsp, rsp_len); } @@ -62,6 +68,7 @@ static void rpmb_dev_release(struct device *dev) { struct rpmb_dev *rdev = to_rpmb_dev(dev); + mutex_destroy(&rdev->lock); ida_free(&rpmb_ida, rdev->id); kfree(rdev->descr.dev_id); kfree(rdev); @@ -123,8 +130,9 @@ EXPORT_SYMBOL_GPL(rpmb_interface_unregister); * rpmb_dev_unregister() - unregister RPMB partition from the RPMB subsystem * @rdev: the rpmb device to unregister * - * This function should be called from the release function of the - * underlying device used when the RPMB device was registered. + * This function should be called from the remove or unbind callback of the + * underlying device used when the RPMB device was registered, never from + * a device release callback. * * Returns: < 0 on failure */ @@ -133,6 +141,12 @@ int rpmb_dev_unregister(struct rpmb_dev *rdev) if (!rdev) return -EINVAL; + scoped_guard(mutex, &rdev->lock) { + if (!rdev->descr.route_frames) + return 0; + rdev->descr.route_frames = NULL; + } + device_del(&rdev->dev); rpmb_dev_put(rdev); @@ -164,6 +178,7 @@ struct rpmb_dev *rpmb_dev_register(struct device *dev, rdev = kzalloc_obj(*rdev); if (!rdev) return ERR_PTR(-ENOMEM); + mutex_init(&rdev->lock); rdev->descr = *descr; rdev->descr.dev_id = kmemdup(descr->dev_id, descr->dev_id_len, GFP_KERNEL); @@ -194,6 +209,7 @@ struct rpmb_dev *rpmb_dev_register(struct device *dev, err_free_dev_id: kfree(rdev->descr.dev_id); err_free_rdev: + mutex_destroy(&rdev->lock); kfree(rdev); return ERR_PTR(ret); } diff --git a/include/linux/rpmb.h b/include/linux/rpmb.h index ed3f8e431eff..11a5d2646e38 100644 --- a/include/linux/rpmb.h +++ b/include/linux/rpmb.h @@ -7,6 +7,7 @@ #define __RPMB_H__ #include +#include #include /** @@ -48,12 +49,14 @@ struct rpmb_descr { * struct rpmb_dev - device which can support RPMB partition * * @dev : device + * @lock : serialises requests and protects them against teardown * @id : device_id * @list_node : linked list node * @descr : RPMB description */ struct rpmb_dev { struct device dev; + struct mutex lock; int id; struct list_head list_node; struct rpmb_descr descr; -- 2.56.0.567.gdb80ae8cd5-goog