Re: [PATCH] misc: fastrpc: remove map before remote unmap
From: Ekansh Gupta
Date: Fri Jul 31 2026 - 02:46:43 EST
On 24-06-2026 23:19, Yousef Alhouseen wrote:
> FASTRPC_IOCTL_MEM_UNMAP found a map under fl->lock, then dropped the lock.
>
> It used that map until the DSP completed the unmap.
>
> A second unmap can find the same map and race to fastrpc_map_put().
>
> That can cause a use-after-free or double list deletion.
>
> Remove the map from the lookup list before the remote unmap.
>
> Reinsert it if the remote side reports an error.
>
> Signed-off-by: Yousef Alhouseen <alhouseenyousef@xxxxxxxxx>
> ---
> drivers/misc/fastrpc.c | 7 ++++++-
> 1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
> index 6a5239b1c..6ced210ca 100644
> --- a/drivers/misc/fastrpc.c
> +++ b/drivers/misc/fastrpc.c
> @@ -365,7 +365,8 @@ static void fastrpc_free_map(struct kref *ref)
>
> if (map->fl) {
> spin_lock(&map->fl->lock);
> - list_del(&map->node);
> + if (!list_empty(&map->node))
> + list_del_init(&map->node);
> spin_unlock(&map->fl->lock);
> map->fl = NULL;
> }
> @@ -2064,6 +2065,7 @@ static int fastrpc_req_mem_unmap_impl(struct fastrpc_user *fl, struct fastrpc_me
> list_for_each_entry_safe(iter, m, &fl->maps, node) {
> if ((req->fd < 0 || iter->fd == req->fd) && (iter->raddr == req->vaddr)) {
> map = iter;
> + list_del_init(&map->node);
The map is not available after this point in the fl->maps list and there
can be another thread making a MEM_MAP request for the same fd/dmabuf at
the same time. Now as the entry is removed from the list,
fastrpc_map_lookup() won't find the entry in the list, the MEM_MAP call
will go ahead and create DSP mapping for the same fd again. This can
leave the same buffer mapped twice on the DSP with two different raddrs,
which might cause problems.
> break;
> }
> }
> @@ -2088,6 +2090,9 @@ static int fastrpc_req_mem_unmap_impl(struct fastrpc_user *fl, struct fastrpc_me
> &args[0]);
> if (err) {
> dev_err(dev, "unmmap\tpt fd = %d, 0x%09llx error\n", map->fd, map->raddr);
> + spin_lock(&fl->lock);
> + list_add_tail(&map->node, &fl->maps);
> + spin_unlock(&fl->lock);
> return err;
> }
> fastrpc_map_put(map);