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 <[email protected]> > --- > 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);
