[PATCH v5 0/3] rpmb: Fix request serialisation and teardown races
From: Stanley Jhu
Date: Mon Sep 14 2026 - 11:53:47 EST
This merges two series that were both last posted as v3:
[PATCH v3] rpmb: core: Guard frame requests and teardown with mutex
https://lore.kernel.org/all/20260910015515.1991789-1-stanleyjhu@xxxxxxxxxx/
[PATCH v3 0/2] scsi: ufs: rpmb: Fix bus registration and device lifecycle
https://lore.kernel.org/all/20260910015503.1991119-1-stanleyjhu@xxxxxxxxxx/
They turned out to be one problem. The UFS patches make RPMB registration
work again. Registering RPMB devices without the core fix triggers a
use-after-free on any unbind that races an in-flight request. Landing them
as two independent series would leave that window open in between.
The order is chosen so that no commit enables RPMB registration before the
lifetime handling and the serialisation are in place:
1/3 fixes the generic core. It fixes the teardown race on eMMC today
and carries a stable tag. It has no effect on UFS on current
kernels, where nothing registers.
2/3 fixes the UFS device lifetime. Still nothing registers.
3/3 removes the never registered bus, which is what makes UFS RPMB
devices appear again.
drivers/misc/rpmb-core.c and drivers/ufs/ are not in the same tree. 1/3
has no build or runtime dependency on the other two and can be taken on
its own; 2/3 and 3/3 must not land before it.
Verified on QEMU arm64 with KASAN, PROVE_LOCKING and SLUB_DEBUG_ON, against
a UFS device advertising four 4 MiB RPMB regions. Two kthreads on different
CPUs issue RPMB_GET_WRITE_COUNTER against the same region 20000 times each
and compare the nonce echoed back. A third thread holds an rpmb_dev
reference and keeps issuing requests across a host unbind. OP-TEE is the
only in-kernel consumer of rpmb_route_frames(), so an out-of-tree module
stands in for it.
tree rpmb_dev stolen responses unbind
-------------------- -------- ---------------- --------------------
3/3 alone 4 16512 of 40000 KASAN use-after-free
3/3 and 2/3, no 1/3 4 17030 of 40000 KASAN use-after-free
all three 4 0 of 40000 clean
The intermediate points were booted and unbound as well. After 1/3 and
after 2/3 no rpmb_dev is registered, so neither test applies to them, and
neither point reports KASAN.
UFS RPMB is not a feature that never worked. bus_add_device() only began
rejecting devices on an unregistered bus in commit 36f35b8df697 ("driver
core: reject devices with unregistered buses") in v7.2-rc1. Reverting that
commit on the same base, with none of these patches applied, brings all
four rpmb_devs back. All four are still in /sys/class/rpmb after a host
unbind that leaves /sys/class/scsi_device empty. So 2/3 fixes a leak that
is live on v6.19 through v7.1. 3/3 restores what v7.2 disabled. Both
carry Cc: stable again. For a backport the three must be taken together
and in order: 3/3 without 1/3 re-enables registration with the core race
still open.
Upstream QEMU answers SECURITY PROTOCOL IN/OUT on the RPMB well known LU
with INVALID OPCODE. The three rows above therefore also needed a local
QEMU change that implements the authenticated frame state machine. I can
post that to qemu-devel separately, and send the test module to anyone
who wants to reproduce the numbers.
Changes since v4, mostly from Bean Huo's review:
https://lore.kernel.org/all/20260913033633.3159296-1-stanleyjhu@xxxxxxxxxx/
- v4 dropped Cc: stable from the UFS patches on the grounds that the
feature has never worked on any released kernel. That is wrong, as
explained above, and both tags are back
- shortened the patch 1 and 2 commit messages
- documented that the rpmb_dev mutex also serialises requests, not only
guards against teardown
- patch 2 keeps list_del() and the two dev_info() calls, and drops a dead
rdev check, so its diff is smaller
- corrected the JESD220F section references in patch 1
- picked up Bean Huo's Reviewed-by on all three patches
Changes since v3:
- merged the two series and reordered so registration is enabled last
- dropped the incorrect Tested: line from the core patch
- dropped Cc: stable from the UFS patches; the feature has never worked on
any released kernel, so there is nothing to backport (wrong, retracted
in v5 above)
- rewrote the commit messages around the measured results
Stanley Jhu (3):
rpmb: core: Guard frame requests and teardown with mutex
scsi: ufs: rpmb: Decouple device lifecycle from devres to avoid UAF
scsi: ufs: rpmb: Drop the unregistered ufs_rpmb bus
drivers/misc/rpmb-core.c | 34 ++++++++++++---
drivers/ufs/core/ufs-rpmb.c | 85 ++++++++++++++++++++-----------------
include/linux/rpmb.h | 5 +++
3 files changed, 79 insertions(+), 45 deletions(-)
--
2.55.0.1007.g17ff1f9808-goog