Message ID | 20220902151423.3351414-2-abel.vesa@linaro.org (mailing list archive) |
---|---|
State | Not Applicable |
Headers | show |
Series | [1/3] misc: fastrpc: Fix use-after-free and race in fastrpc_map_find | expand |
On 02/09/2022 16:14, Abel Vesa wrote: > Do not remove the map from the list on error path in > fastrpc_init_create_process, instead call fastrpc_map_put, to avoid > use-after-free. Do not remove it on fastrpc_device_release either, > call fastrpc_map_put instead. > > The fastrpc_free_map is the only proper place to remove the map. > This is called only after the reference count is 0. > > Fixes: b49f6d83e290f ("misc: fastrpc: Fix a possible double free") > Co-developed-by: Ola Jeppsson <ola@snap.com> > Signed-off-by: Ola Jeppsson <ola@snap.com> > Signed-off-by: Abel Vesa <abel.vesa@linaro.org> > --- Reviewed-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> > drivers/misc/fastrpc.c | 18 +++++++++--------- > 1 file changed, 9 insertions(+), 9 deletions(-) > > diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c > index 0c816a11eeec..50c17f5da3a8 100644 > --- a/drivers/misc/fastrpc.c > +++ b/drivers/misc/fastrpc.c > @@ -316,6 +316,13 @@ static void fastrpc_free_map(struct kref *ref) > dma_buf_put(map->buf); > } > > + if (map->fl) { > + spin_lock(&map->fl->lock); > + list_del(&map->node); > + spin_unlock(&map->fl->lock); > + map->fl = NULL; > + } > + > kfree(map); > } > > @@ -1266,12 +1273,7 @@ static int fastrpc_init_create_process(struct fastrpc_user *fl, > fl->init_mem = NULL; > fastrpc_buf_free(imem); > err_alloc: > - if (map) { > - spin_lock(&fl->lock); > - list_del(&map->node); > - spin_unlock(&fl->lock); > - fastrpc_map_put(map); > - } > + fastrpc_map_put(map); > err: > kfree(args); > > @@ -1347,10 +1349,8 @@ static int fastrpc_device_release(struct inode *inode, struct file *file) > fastrpc_context_put(ctx); > } > > - list_for_each_entry_safe(map, m, &fl->maps, node) { > - list_del(&map->node); > + list_for_each_entry_safe(map, m, &fl->maps, node) > fastrpc_map_put(map); > - } > > list_for_each_entry_safe(buf, b, &fl->mmaps, node) { > list_del(&buf->node);
diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 0c816a11eeec..50c17f5da3a8 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -316,6 +316,13 @@ static void fastrpc_free_map(struct kref *ref) dma_buf_put(map->buf); } + if (map->fl) { + spin_lock(&map->fl->lock); + list_del(&map->node); + spin_unlock(&map->fl->lock); + map->fl = NULL; + } + kfree(map); } @@ -1266,12 +1273,7 @@ static int fastrpc_init_create_process(struct fastrpc_user *fl, fl->init_mem = NULL; fastrpc_buf_free(imem); err_alloc: - if (map) { - spin_lock(&fl->lock); - list_del(&map->node); - spin_unlock(&fl->lock); - fastrpc_map_put(map); - } + fastrpc_map_put(map); err: kfree(args); @@ -1347,10 +1349,8 @@ static int fastrpc_device_release(struct inode *inode, struct file *file) fastrpc_context_put(ctx); } - list_for_each_entry_safe(map, m, &fl->maps, node) { - list_del(&map->node); + list_for_each_entry_safe(map, m, &fl->maps, node) fastrpc_map_put(map); - } list_for_each_entry_safe(buf, b, &fl->mmaps, node) { list_del(&buf->node);