[PATCH v2 0/3] Fix RPMB cross-subsystem UAF and UFS OP-TEE RPMB lifecycle

Stanley Jhu posted 3 patches 3 weeks ago
drivers/misc/rpmb-core.c       | 24 ++++++++++----
drivers/ufs/core/ufs-rpmb.c    | 96 +++++++++++++++++++++-------------
drivers/ufs/core/ufshcd-priv.h | 13 ++++-
drivers/ufs/core/ufshcd.c      | 16 +++++-
include/linux/rpmb.h           |  5 ++
5 files changed, 111 insertions(+), 43 deletions(-)
[PATCH v2 0/3] Fix RPMB cross-subsystem UAF and UFS OP-TEE RPMB lifecycle
Posted by Stanley Jhu 3 weeks ago
This series addresses a critical cross-subsystem Use-After-Free (UAF)
vulnerability in the RPMB subsystem core, along with lifecycle and bus
registration fixes in the UFS OP-TEE RPMB driver.

Problem Overview:
During concurrent accesses to an RPMB partition while the UFS host
controller unbinds or shuts down, a critical Use-After-Free (UAF) occurs:
1. When the driver calls rpmb_dev_unregister(), device_del() drops the
   driver core's reference to the parent device taken during device_add().
2. Because rpmb_dev_register() never explicitly pinned the parent device
   via get_device(), the parent device's refcount drops prematurely while
   the child struct rpmb_dev remains alive via external references.
3. The parent driver teardown frees the parent device structure.
4. Subsequent calls to rpmb_route_frames() dereference rdev->dev.parent,
   resulting in a crash or arbitrary memory corruption on freed memory.
5. In addition, in the UFS RPMB driver, struct ufs_rpmb_dev was allocated
   using devm_kzalloc(), which gets freed prematurely by devres on host
   unbind, and its bus_type was never registered with the driver core.

Patch Breakdown:

Patch 1: rpmb: core: Pin parent device and guard requests with rwsem
- Pins the parent device for the lifetime of the RPMB device, and
  guards in-flight requests against teardown with an rw_semaphore
  barrier.

Patch 2: scsi: ufs: rpmb: Decouple device lifecycle from devres
- Decouples ufs_rpmb from devres, managing its lifetime strictly through
  the embedded struct device reference count, and pins the underlying
  SCSI device.

Patch 3: scsi: ufs: rpmb: Register and unregister ufs_rpmb_bus_type
- Registers ufs_rpmb_bus_type in ufshcd_core_init() and unregisters it
  in ufshcd_core_exit(), preventing device_register() rejection with
  -EINVAL.

Changes in v2:
- Added Patch 1 to pin parent device in RPMB core and guard in-flight
  requests with an rw_semaphore teardown barrier (sashiko-bot).

Verification:
- Tested on QEMU ARM64 with concurrent RPMB accesses under driver unbind.

Stanley Jhu (3):
  rpmb: core: Pin parent device and guard requests with rwsem
  scsi: ufs: rpmb: Decouple device lifecycle from devres to avoid UAF
  scsi: ufs: rpmb: Register and unregister ufs_rpmb_bus_type

 drivers/misc/rpmb-core.c       | 24 ++++++++++----
 drivers/ufs/core/ufs-rpmb.c    | 96 +++++++++++++++++++++-------------
 drivers/ufs/core/ufshcd-priv.h | 13 ++++-
 drivers/ufs/core/ufshcd.c      | 16 +++++-
 include/linux/rpmb.h           |  5 ++
 5 files changed, 111 insertions(+), 43 deletions(-)

-- 
2.48.1