Re: [PATCH v3] rapidio: mport_cdev: fix use-after-free in dma_req_free()

From: James Kim

Date: Mon Jul 27 2026 - 03:58:07 EST


Hi Andrew,

Thanks for picking up this patch.

I noticed that the version currently queued in mm-everything appears to
correspond to v2 (commit c044e529fa01).

The v3 update includes one additional change based on your review by
clearing req->map while holding md->buf_mutex:

mutex_lock(&md->buf_mutex);
req->map = NULL;
kref_put(&map->ref, mport_release_mapping);
mutex_unlock(&md->buf_mutex);

The v3 posting is available here:

https://lore.kernel.org/lkml/20260723235220.588424-1-james010kim@xxxxxxxxx/

If it's still convenient, could you please replace the queued version
with v3?

Thanks!

James

On Fri, Jul 24, 2026 at 8:53 AM James Kim <james010kim@xxxxxxxxx> wrote:
>
> dma_req_free() acquires buf_mutex through req->map, drops the mapping
> reference with kref_put(), and then dereferences req->map again to
> unlock the mutex.
>
> If kref_put() drops the last reference, mport_release_mapping() frees
> the mapping, and the subsequent mutex_unlock() dereferences a freed
> object. This is a use-after-free.
>
> Fix this by caching map and md before kref_put(), clearing req->map
> while holding buf_mutex, and using the cached md for mutex unlocking.
>
> The bug is reachable from userspace via the RapidIO mport character
> device interface.
>
> Fixes: e8de370188d0 ("rapidio: add mport char device driver")
> Cc: stable@xxxxxxxxxxxxxxx
> Reviewed-by: Dan Carpenter <error27@xxxxxxxxx>
> Signed-off-by: James Kim <james010kim@xxxxxxxxx>
>
> ---
> Changes since v2:
> - Correct the Fixes tag.
> - Clear req->map while holding buf_mutex.
> - Clarify that the bug is reachable from userspace.
> - Update Dan Carpenter's email address and add his Reviewed-by tag.
>
> Changes since v1:
> - Rebase on v7.1.
> - Add Dan Carpenter to Cc for lifetime and use-after-free review.
> - No functional changes.
> ---
> drivers/rapidio/devices/rio_mport_cdev.c | 10 +++++++---
> 1 file changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/rapidio/devices/rio_mport_cdev.c b/drivers/rapidio/devices/rio_mport_cdev.c
> index 009b3b595bbf..ad82c2108a56 100644
> --- a/drivers/rapidio/devices/rio_mport_cdev.c
> +++ b/drivers/rapidio/devices/rio_mport_cdev.c
> @@ -564,9 +564,13 @@ static void dma_req_free(struct kref *ref)
> }
>
> if (req->map) {
> - mutex_lock(&req->map->md->buf_mutex);
> - kref_put(&req->map->ref, mport_release_mapping);
> - mutex_unlock(&req->map->md->buf_mutex);
> + struct rio_mport_mapping *map = req->map;
> + struct mport_dev *md = map->md;
> +
> + mutex_lock(&md->buf_mutex);
> + req->map = NULL;
> + kref_put(&map->ref, mport_release_mapping);
> + mutex_unlock(&md->buf_mutex);
> }
>
> kref_put(&priv->dma_ref, mport_release_dma);
> --
> 2.25.1
>