Re: [PATCH v3 2/2] scsi: ufs: rpmb: Decouple device lifecycle from devres to avoid UAF
flat view
From: Stanley Jhu <hidden>
Date: 2026-09-10 02:13:20
Also in:
sashiko-reviews
On Thu, 10 Sep 2026, sashiko-bot@kernel.org wrote:
[Severity: Critical]
This isn't a bug introduced by this patch, but does this sequence still
leave a use-after-free window during device removal?
When rpmb_dev_unregister() is called, it internally calls device_del() on
the child device, which immediately drops the reference to its parent device
(ufs_rpmb->dev).
If a consumer is actively holding a reference to the child device via
rpmb_dev_get(), the child device itself remains allocated. However, the
subsequent call to device_unregister() here drops the final reference to
the parent ufs_rpmb structure, causing it to be freed.
If the consumer then concurrently executes a request, the framework will
pass the now-dangling parent pointer to the route_frames callback:
drivers/ufs/core/ufs-rpmb.c:ufs_rpmb_route_frames() {
struct ufs_rpmb_dev *ufs_rpmb = dev_get_drvdata(dev);
...
}
Could this dev_get_drvdata(dev) dereference the freed parent memory,
resulting in a use-after-free despite the new lifecycle management?This specific teardown race is guarded by the companion patch in the generic RPMB core: "[PATCH v3] rpmb: core: Guard frame requests and teardown with mutex" https://lore.kernel.org/r/20260910015515.1991789-1-stanleyjhu@google.com (local) In rpmb_dev_unregister(), rdev->lock is acquired to drain in-flight requests and mark rdev->dead = true before device_del() is invoked. Any concurrent or subsequent call to rpmb_route_frames() is rejected with -ENODEV under rdev->lock before dereferencing rdev->dev.parent. Therefore, the dangling parent pointer is never dereferenced once rpmb_dev_unregister() returns. Thanks, Stanley