* [PATCH v3 0/2] scsi: ufs: rpmb: Fix bus registration and device lifecycle
@ 2026-09-10 1:55 Stanley Jhu
2026-09-10 1:55 ` [PATCH v3 1/2] scsi: ufs: rpmb: Register and unregister ufs_rpmb_bus_type Stanley Jhu
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Stanley Jhu @ 2026-09-10 1:55 UTC (permalink / raw)
To: Martin K . Petersen, James E . J . Bottomley, linux-scsi
Cc: Brian Kao, Bean Huo, Bart Van Assche, Alim Akhtar, Avri Altman,
Peter Wang, Can Guo, Li Qiang, Ao Sun, linux-kernel, Stanley Jhu
This series fixes bus registration and device lifecycle defects in the
UFS OP-TEE RPMB driver.
Why:
1. ufs_rpmb_bus_type was never registered with bus_register(), causing
device_register() in ufs_rpmb_probe() to unconditionally fail with
-EINVAL.
2. struct ufs_rpmb_dev embeds struct device but was allocated via
devm_kzalloc() tied to hba->dev. On host unbind, devres frees the
structure prematurely while external references remain active,
causing a Use-After-Free (UAF) Oops.
What:
- Patch 1: Register ufs_rpmb_bus_type during ufshcd_core_init() and
unregister it in ufshcd_core_exit(), with stubs for !CONFIG_RPMB.
- Patch 2: Allocate ufs_rpmb with kzalloc_obj() and free it via kfree()
in ufs_rpmb_device_release(). Pin the underlying SCSI WLUN via
scsi_device_get/put() and unregister in ufs_rpmb_remove().
Differences from v2:
- Drop generic RPMB core changes (sent as a separate patch).
- Reorder patches so bus registration comes first for bisectability.
- Call rpmb_dev_unregister() in ufs_rpmb_remove() to break cyclic refcount.
- Pin underlying SCSI WLUN via scsi_device_get/put().
Tested:
- Verified clean probe, RPMB I/O, and unbind on QEMU ARM64 without UAF.
Stanley Jhu (2):
scsi: ufs: rpmb: Register and unregister ufs_rpmb_bus_type
scsi: ufs: rpmb: Decouple device lifecycle from devres to avoid UAF
drivers/ufs/core/ufs-rpmb.c | 107 ++++++++++++++++++++-------------
drivers/ufs/core/ufshcd-priv.h | 13 +++-
drivers/ufs/core/ufshcd.c | 16 ++++-
3 files changed, 91 insertions(+), 45 deletions(-)
--
2.55.0.1007.g17ff1f9808-goog
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH v3 1/2] scsi: ufs: rpmb: Register and unregister ufs_rpmb_bus_type 2026-09-10 1:55 [PATCH v3 0/2] scsi: ufs: rpmb: Fix bus registration and device lifecycle Stanley Jhu @ 2026-09-10 1:55 ` Stanley Jhu 2026-09-10 1:55 ` [PATCH v3 2/2] scsi: ufs: rpmb: Decouple device lifecycle from devres to avoid UAF Stanley Jhu 2026-09-10 2:06 ` [PATCH v3 0/2] scsi: ufs: rpmb: Fix bus registration and device lifecycle Stanley Jhu 2 siblings, 0 replies; 6+ messages in thread From: Stanley Jhu @ 2026-09-10 1:55 UTC (permalink / raw) To: Martin K . Petersen, James E . J . Bottomley, linux-scsi Cc: Brian Kao, Bean Huo, Bart Van Assche, Alim Akhtar, Avri Altman, Peter Wang, Can Guo, Li Qiang, Ao Sun, linux-kernel, Stanley Jhu The UFS RPMB driver defines ufs_rpmb_bus_type and assigns it to the bus member of struct device for each RPMB device. However, ufs_rpmb_bus_type is never registered with the driver core via bus_register(). When driver core rejects devices assigned to unregistered buses with -EINVAL in bus_add_device(), device_register(&ufs_rpmb->dev) in ufs_rpmb_probe() fails with: "bus_add_device: cannot add device 'ufs_rpmb0' to unregistered bus 'ufs_rpmb'" "ufshcd: Failed to register UFS RPMB device 0" Fix this by registering ufs_rpmb_bus_type during UFS core initialization in ufshcd_core_init() and unregistering it in ufshcd_core_exit(). Add helper functions ufs_rpmb_bus_register() and ufs_rpmb_bus_unregister(), guarding their declarations with IS_REACHABLE(CONFIG_RPMB) and inline fallback stubs for configurations where CONFIG_RPMB is disabled. Mark ufs_rpmb_bus_register() as __init so its memory can be reclaimed after module initialization. Fixes: b06b8c421485 ("scsi: ufs: core: Add OP-TEE based RPMB driver for UFS devices") Signed-off-by: Stanley Jhu <stanleyjhu@google.com> --- drivers/ufs/core/ufs-rpmb.c | 10 ++++++++++ drivers/ufs/core/ufshcd-priv.h | 13 ++++++++++++- drivers/ufs/core/ufshcd.c | 16 ++++++++++++++-- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/drivers/ufs/core/ufs-rpmb.c b/drivers/ufs/core/ufs-rpmb.c index aa925cbb07e8..c7aade96c823 100644 --- a/drivers/ufs/core/ufs-rpmb.c +++ b/drivers/ufs/core/ufs-rpmb.c @@ -28,6 +28,16 @@ static const struct bus_type ufs_rpmb_bus_type = { .name = "ufs_rpmb", }; +int __init ufs_rpmb_bus_register(void) +{ + return bus_register(&ufs_rpmb_bus_type); +} + +void ufs_rpmb_bus_unregister(void) +{ + bus_unregister(&ufs_rpmb_bus_type); +} + /* UFS RPMB device structure */ struct ufs_rpmb_dev { u8 region_id; diff --git a/drivers/ufs/core/ufshcd-priv.h b/drivers/ufs/core/ufshcd-priv.h index e55c2a02c1f5..d5e0cc3edb5b 100644 --- a/drivers/ufs/core/ufshcd-priv.h +++ b/drivers/ufs/core/ufshcd-priv.h @@ -493,10 +493,21 @@ static inline u32 ufshcd_mcq_get_sq_head_slot(struct ufs_hw_queue *q) return val / sizeof(struct utp_transfer_req_desc); } -#if IS_ENABLED(CONFIG_RPMB) +#if IS_REACHABLE(CONFIG_RPMB) +int __init ufs_rpmb_bus_register(void); +void ufs_rpmb_bus_unregister(void); int ufs_rpmb_probe(struct ufs_hba *hba); void ufs_rpmb_remove(struct ufs_hba *hba); #else +static inline int ufs_rpmb_bus_register(void) +{ + return 0; +} + +static inline void ufs_rpmb_bus_unregister(void) +{ +} + static inline int ufs_rpmb_probe(struct ufs_hba *hba) { return 0; diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index a25b6a0cb5c6..4470e3d65c5c 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -11584,16 +11584,28 @@ static int __init ufshcd_core_init(void) ufs_debugfs_init(); + ret = ufs_rpmb_bus_register(); + if (ret) + goto err_debugfs; + ret = scsi_register_driver(&ufs_dev_wlun_template); if (ret) - ufs_debugfs_exit(); + goto err_rpmb_bus; + + return 0; + +err_rpmb_bus: + ufs_rpmb_bus_unregister(); +err_debugfs: + ufs_debugfs_exit(); return ret; } static void __exit ufshcd_core_exit(void) { - ufs_debugfs_exit(); scsi_unregister_driver(&ufs_dev_wlun_template); + ufs_rpmb_bus_unregister(); + ufs_debugfs_exit(); } module_init(ufshcd_core_init); -- 2.55.0.1007.g17ff1f9808-goog ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v3 2/2] scsi: ufs: rpmb: Decouple device lifecycle from devres to avoid UAF 2026-09-10 1:55 [PATCH v3 0/2] scsi: ufs: rpmb: Fix bus registration and device lifecycle Stanley Jhu 2026-09-10 1:55 ` [PATCH v3 1/2] scsi: ufs: rpmb: Register and unregister ufs_rpmb_bus_type Stanley Jhu @ 2026-09-10 1:55 ` Stanley Jhu 2026-09-10 2:09 ` sashiko-bot 2026-09-10 2:06 ` [PATCH v3 0/2] scsi: ufs: rpmb: Fix bus registration and device lifecycle Stanley Jhu 2 siblings, 1 reply; 6+ messages in thread From: Stanley Jhu @ 2026-09-10 1:55 UTC (permalink / raw) To: Martin K . Petersen, James E . J . Bottomley, linux-scsi Cc: Brian Kao, Bean Huo, Bart Van Assche, Alim Akhtar, Avri Altman, Peter Wang, Can Guo, Li Qiang, Ao Sun, linux-kernel, Stanley Jhu, stable struct ufs_rpmb_dev embeds struct device, but is allocated using devm_kzalloc() tied to the host controller (hba->dev). When the host controller unbinds, devres automatically frees ufs_rpmb regardless of active references to ufs_rpmb->dev (such as sysfs users or child devices). Subsequent access to ufs_rpmb->dev triggers a Use-After-Free (UAF) kernel Oops. Fix this lifetime defect: - Allocate ufs_rpmb with kzalloc_obj() and free it in ufs_rpmb_device_release() via kfree(), strictly tying memory lifetime to the device reference count. - Pin the underlying SCSI WLUN via scsi_device_get() in probe and release it with scsi_device_put() in device_release. - Call rpmb_dev_unregister() in ufs_rpmb_remove() and probe error unwind before device_unregister(). - Check scsi_device_online() before submitting security commands. Fixes: b06b8c421485 ("scsi: ufs: core: Add OP-TEE based RPMB driver for UFS devices") Signed-off-by: Stanley Jhu <stanleyjhu@google.com> Cc: stable@vger.kernel.org --- drivers/ufs/core/ufs-rpmb.c | 97 +++++++++++++++++++++---------------- 1 file changed, 55 insertions(+), 42 deletions(-) diff --git a/drivers/ufs/core/ufs-rpmb.c b/drivers/ufs/core/ufs-rpmb.c index c7aade96c823..33b9a4a1b120 100644 --- a/drivers/ufs/core/ufs-rpmb.c +++ b/drivers/ufs/core/ufs-rpmb.c @@ -13,6 +13,7 @@ #include <linux/module.h> #include <linux/device.h> #include <linux/kernel.h> +#include <linux/slab.h> #include <linux/types.h> #include <linux/rpmb.h> #include <linux/string.h> @@ -43,15 +44,19 @@ struct ufs_rpmb_dev { u8 region_id; struct device dev; struct rpmb_dev *rdev; - struct ufs_hba *hba; + struct scsi_device *sdev; struct list_head node; }; -static int ufs_sec_submit(struct ufs_hba *hba, u16 spsp, void *buffer, size_t len, bool send) +static int ufs_sec_submit(struct ufs_rpmb_dev *ufs_rpmb, u16 spsp, + void *buffer, size_t len, bool send) { - struct scsi_device *sdev = hba->ufs_rpmb_wlun; + struct scsi_device *sdev = ufs_rpmb->sdev; u8 cdb[12] = { }; + if (!sdev || !scsi_device_online(sdev)) + return -ENODEV; + cdb[0] = send ? SECURITY_PROTOCOL_OUT : SECURITY_PROTOCOL_IN; cdb[1] = UFS_RPMB_SEC_PROTOCOL; put_unaligned_be16(spsp, &cdb[2]); @@ -63,13 +68,12 @@ static int ufs_sec_submit(struct ufs_hba *hba, u16 spsp, void *buffer, size_t le /* UFS RPMB route frames implementation */ static int ufs_rpmb_route_frames(struct device *dev, u8 *req, unsigned int req_len, u8 *resp, - unsigned int resp_len) + unsigned int resp_len) { struct ufs_rpmb_dev *ufs_rpmb = dev_get_drvdata(dev); struct rpmb_frame *frm_out = (struct rpmb_frame *)req; bool need_result_read = true; u16 req_type, protocol_id; - struct ufs_hba *hba; int ret; if (!ufs_rpmb) { @@ -77,8 +81,6 @@ static int ufs_rpmb_route_frames(struct device *dev, u8 *req, unsigned int req_l return -ENODEV; } - hba = ufs_rpmb->hba; - /* req_resp is at the end of an RPMB frame. */ if (req_len < sizeof(*frm_out)) return -EINVAL; @@ -111,7 +113,7 @@ static int ufs_rpmb_route_frames(struct device *dev, u8 *req, unsigned int req_l protocol_id = ufs_rpmb->region_id << 8 | UFS_RPMB_SEC_PROTOCOL_ID; - ret = ufs_sec_submit(hba, protocol_id, req, req_len, true); + ret = ufs_sec_submit(ufs_rpmb, protocol_id, req, req_len, true); if (ret) { dev_err(dev, "Command failed with ret=%d\n", ret); return ret; @@ -122,7 +124,7 @@ static int ufs_rpmb_route_frames(struct device *dev, u8 *req, unsigned int req_l memset(frm_resp, 0, sizeof(*frm_resp)); put_unaligned_be16(RPMB_RESULT_READ, &frm_resp->req_resp); - ret = ufs_sec_submit(hba, protocol_id, resp, resp_len, true); + ret = ufs_sec_submit(ufs_rpmb, protocol_id, resp, resp_len, true); if (ret) { dev_err(dev, "Result read request failed with ret=%d\n", ret); return ret; @@ -130,7 +132,7 @@ static int ufs_rpmb_route_frames(struct device *dev, u8 *req, unsigned int req_l } if (!ret) { - ret = ufs_sec_submit(hba, protocol_id, resp, resp_len, false); + ret = ufs_sec_submit(ufs_rpmb, protocol_id, resp, resp_len, false); if (ret) dev_err(dev, "Response read failed with ret=%d\n", ret); } @@ -140,22 +142,29 @@ static int ufs_rpmb_route_frames(struct device *dev, u8 *req, unsigned int req_l static void ufs_rpmb_device_release(struct device *dev) { - struct ufs_rpmb_dev *ufs_rpmb = dev_get_drvdata(dev); + struct ufs_rpmb_dev *ufs_rpmb = container_of(dev, struct ufs_rpmb_dev, dev); - rpmb_dev_unregister(ufs_rpmb->rdev); + scsi_device_put(ufs_rpmb->sdev); + kfree(ufs_rpmb); } /* UFS RPMB device registration */ int ufs_rpmb_probe(struct ufs_hba *hba) { + struct rpmb_descr descr = { + .type = RPMB_TYPE_UFS, + .route_frames = ufs_rpmb_route_frames, + .reliable_wr_count = hba->dev_info.rpmb_io_size, + }; + struct scsi_device *sdev = hba->ufs_rpmb_wlun; struct ufs_rpmb_dev *ufs_rpmb, *it, *tmp; struct rpmb_dev *rdev; - char *cid = NULL; + char *cid; int region; u32 cap; int ret; - if (!hba->ufs_rpmb_wlun || hba->dev_info.b_advanced_rpmb_en) { + if (!sdev || hba->dev_info.b_advanced_rpmb_en) { dev_info(hba->dev, "Skip OP-TEE RPMB registration\n"); return -ENODEV; } @@ -166,25 +175,28 @@ int ufs_rpmb_probe(struct ufs_hba *hba) return -EINVAL; } - struct rpmb_descr descr = { - .type = RPMB_TYPE_UFS, - .route_frames = ufs_rpmb_route_frames, - .reliable_wr_count = hba->dev_info.rpmb_io_size, - }; - for (region = 0; region < ARRAY_SIZE(hba->dev_info.rpmb_region_size); region++) { cap = hba->dev_info.rpmb_region_size[region]; if (!cap) continue; - ufs_rpmb = devm_kzalloc(hba->dev, sizeof(*ufs_rpmb), GFP_KERNEL); + ufs_rpmb = kzalloc_obj(*ufs_rpmb); if (!ufs_rpmb) { ret = -ENOMEM; goto err_out; } - ufs_rpmb->hba = hba; - ufs_rpmb->dev.parent = &hba->ufs_rpmb_wlun->sdev_gendev; + INIT_LIST_HEAD(&ufs_rpmb->node); + + ret = scsi_device_get(sdev); + if (ret) { + kfree(ufs_rpmb); + goto err_out; + } + + ufs_rpmb->sdev = sdev; + ufs_rpmb->region_id = region; + ufs_rpmb->dev.parent = &sdev->sdev_gendev; ufs_rpmb->dev.bus = &ufs_rpmb_bus_type; ufs_rpmb->dev.release = ufs_rpmb_device_release; dev_set_name(&ufs_rpmb->dev, "ufs_rpmb%d", region); @@ -195,16 +207,14 @@ int ufs_rpmb_probe(struct ufs_hba *hba) ret = device_register(&ufs_rpmb->dev); if (ret) { dev_err(hba->dev, "Failed to register UFS RPMB device %d\n", region); - put_device(&ufs_rpmb->dev); - goto err_out; + goto err_put; } /* Create unique ID by appending region number to device_id */ cid = kasprintf(GFP_KERNEL, "%s-R%d", hba->dev_info.device_id, region); if (!cid) { - device_unregister(&ufs_rpmb->dev); ret = -ENOMEM; - goto err_out; + goto err_unreg; } descr.dev_id = cid; @@ -213,29 +223,33 @@ int ufs_rpmb_probe(struct ufs_hba *hba) /* Register RPMB device */ rdev = rpmb_dev_register(&ufs_rpmb->dev, &descr); + kfree(cid); if (IS_ERR(rdev)) { dev_err(hba->dev, "Failed to register UFS RPMB device.\n"); - device_unregister(&ufs_rpmb->dev); ret = PTR_ERR(rdev); - goto err_out; + goto err_unreg; } - kfree(cid); - cid = NULL; - ufs_rpmb->rdev = rdev; - ufs_rpmb->region_id = region; - list_add_tail(&ufs_rpmb->node, &hba->rpmbs); dev_info(hba->dev, "UFS RPMB region %d registered (capacity=%u)\n", region, cap); } return 0; + +err_unreg: + device_unregister(&ufs_rpmb->dev); + goto err_out; +err_put: + put_device(&ufs_rpmb->dev); err_out: - kfree(cid); list_for_each_entry_safe(it, tmp, &hba->rpmbs, node) { - list_del(&it->node); + list_del_init(&it->node); + if (it->rdev) { + rpmb_dev_unregister(it->rdev); + it->rdev = NULL; + } device_unregister(&it->dev); } @@ -252,14 +266,13 @@ void ufs_rpmb_remove(struct ufs_hba *hba) /* Remove all registered RPMB devices */ list_for_each_entry_safe(ufs_rpmb, tmp, &hba->rpmbs, node) { - dev_info(hba->dev, "Removing UFS RPMB region %d\n", ufs_rpmb->region_id); - /* Remove from list first */ - list_del(&ufs_rpmb->node); - /* Unregister device */ + list_del_init(&ufs_rpmb->node); + if (ufs_rpmb->rdev) { + rpmb_dev_unregister(ufs_rpmb->rdev); + ufs_rpmb->rdev = NULL; + } device_unregister(&ufs_rpmb->dev); } - - dev_info(hba->dev, "All UFS RPMB devices unregistered\n"); } MODULE_LICENSE("GPL v2"); -- 2.55.0.1007.g17ff1f9808-goog ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v3 2/2] scsi: ufs: rpmb: Decouple device lifecycle from devres to avoid UAF 2026-09-10 1:55 ` [PATCH v3 2/2] scsi: ufs: rpmb: Decouple device lifecycle from devres to avoid UAF Stanley Jhu @ 2026-09-10 2:09 ` sashiko-bot 2026-09-10 2:13 ` Stanley Jhu 0 siblings, 1 reply; 6+ messages in thread From: sashiko-bot @ 2026-09-10 2:09 UTC (permalink / raw) To: Stanley Jhu; +Cc: linux-scsi Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: Pre-existing issues: - [Critical] This problem wasn't introduced by this patch, but the patch fails to resolve the pre-existing Use-After-Free during device removal. The device model's `device_del()` drops the parent reference, meaning `rdev->dev.parent` becomes a dangling pointer if a consumer holds a reference to `rdev`. -- commit 19c2abff2bd57dbeee481738657ea4d9e1123a19 Author: Stanley Jhu <stanleyjhu@google.com> scsi: ufs: rpmb: Decouple device lifecycle from devres to avoid UAF This commit changes the allocation of the UFS RPMB device from devres to a reference-counted lifecycle. It also explicitly unregisters the RPMB child device during host removal before unregistering the parent device to prevent memory safety issues. Cc: stable@vger.kernel.org > diff --git a/drivers/ufs/core/ufs-rpmb.c b/drivers/ufs/core/ufs-rpmb.c > index c7aade96c823e..33b9a4a1b120e 100644 > --- a/drivers/ufs/core/ufs-rpmb.c > +++ b/drivers/ufs/core/ufs-rpmb.c [ ... ] > @@ -252,14 +266,13 @@ void ufs_rpmb_remove(struct ufs_hba *hba) > > /* Remove all registered RPMB devices */ > list_for_each_entry_safe(ufs_rpmb, tmp, &hba->rpmbs, node) { > - dev_info(hba->dev, "Removing UFS RPMB region %d\n", ufs_rpmb->region_id); > - /* Remove from list first */ > - list_del(&ufs_rpmb->node); > - /* Unregister device */ > + list_del_init(&ufs_rpmb->node); > + if (ufs_rpmb->rdev) { > + rpmb_dev_unregister(ufs_rpmb->rdev); > + ufs_rpmb->rdev = NULL; > + } > device_unregister(&ufs_rpmb->dev); [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? > } > - > - dev_info(hba->dev, "All UFS RPMB devices unregistered\n"); > } > > MODULE_LICENSE("GPL v2"); -- Sashiko AI review · https://sashiko.dev/#/patchset/20260910015503.1991119-1-stanleyjhu@google.com?part=2 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3 2/2] scsi: ufs: rpmb: Decouple device lifecycle from devres to avoid UAF 2026-09-10 2:09 ` sashiko-bot @ 2026-09-10 2:13 ` Stanley Jhu 0 siblings, 0 replies; 6+ messages in thread From: Stanley Jhu @ 2026-09-10 2:13 UTC (permalink / raw) To: sashiko-bot; +Cc: linux-scsi, sashiko-reviews, Martin K . Petersen, Brian Kao 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 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 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3 0/2] scsi: ufs: rpmb: Fix bus registration and device lifecycle 2026-09-10 1:55 [PATCH v3 0/2] scsi: ufs: rpmb: Fix bus registration and device lifecycle Stanley Jhu 2026-09-10 1:55 ` [PATCH v3 1/2] scsi: ufs: rpmb: Register and unregister ufs_rpmb_bus_type Stanley Jhu 2026-09-10 1:55 ` [PATCH v3 2/2] scsi: ufs: rpmb: Decouple device lifecycle from devres to avoid UAF Stanley Jhu @ 2026-09-10 2:06 ` Stanley Jhu 2 siblings, 0 replies; 6+ messages in thread From: Stanley Jhu @ 2026-09-10 2:06 UTC (permalink / raw) To: Martin K . Petersen, James E . J . Bottomley, linux-scsi Cc: Brian Kao, Bean Huo, Bart Van Assche, Alim Akhtar, Avri Altman, Peter Wang, Can Guo, Li Qiang, Ao Sun, linux-kernel For reference, the companion patch guarding the generic RPMB core with mutex has been submitted to Jens Wiklander and LKML here: https://lore.kernel.org/r/20260910015515.1991789-1-stanleyjhu@google.com Thanks, Stanley ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-09-10 2:13 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-09-10 1:55 [PATCH v3 0/2] scsi: ufs: rpmb: Fix bus registration and device lifecycle Stanley Jhu 2026-09-10 1:55 ` [PATCH v3 1/2] scsi: ufs: rpmb: Register and unregister ufs_rpmb_bus_type Stanley Jhu 2026-09-10 1:55 ` [PATCH v3 2/2] scsi: ufs: rpmb: Decouple device lifecycle from devres to avoid UAF Stanley Jhu 2026-09-10 2:09 ` sashiko-bot 2026-09-10 2:13 ` Stanley Jhu 2026-09-10 2:06 ` [PATCH v3 0/2] scsi: ufs: rpmb: Fix bus registration and device lifecycle Stanley Jhu
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.