Commit 8ff5f5d9 authored by Li Zhijian's avatar Li Zhijian Committed by Jason Gunthorpe
Browse files

RDMA/rxe: Prevent double freeing rxe_map_set()

The same rxe_map_set could be freed twice:

rxe_reg_user_mr()
  -> rxe_mr_init_user()
    -> rxe_mr_free_map_set() # 1st

  -> rxe_drop_ref()
   ...
    -> rxe_mr_cleanup()
      -> rxe_mr_free_map_set() # 2nd

Follow normal convection and put resource cleanup either in the error
unwind of the allocator, or the overall free function. Leave the object
unchanged with a NULL cur_map_set on failure and remove the unncessary
free in rxe_mr_init_user().

Link: https://lore.kernel.org/r/20211228014406.1033444-1-lizhijian@cn.fujitsu.com


Signed-off-by: default avatarLi Zhijian <lizhijian@cn.fujitsu.com>
Acked-by: default avatarZhu Yanjun <zyjzyj2000@gmail.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
parent c9e6606c
Loading
Loading
Loading
Loading
+7 −9
Original line number Diff line number Diff line
@@ -135,19 +135,19 @@ static int rxe_mr_alloc(struct rxe_mr *mr, int num_buf, int both)

	ret = rxe_mr_alloc_map_set(num_map, &mr->cur_map_set);
	if (ret)
		goto err_out;
		return -ENOMEM;

	if (both) {
		ret = rxe_mr_alloc_map_set(num_map, &mr->next_map_set);
		if (ret) {
			rxe_mr_free_map_set(mr->num_map, mr->cur_map_set);
			goto err_out;
		}
		if (ret)
			goto err_free;
	}

	return 0;

err_out:
err_free:
	rxe_mr_free_map_set(mr->num_map, mr->cur_map_set);
	mr->cur_map_set = NULL;
	return -ENOMEM;
}

@@ -214,7 +214,7 @@ int rxe_mr_init_user(struct rxe_pd *pd, u64 start, u64 length, u64 iova,
				pr_warn("%s: Unable to get virtual address\n",
						__func__);
				err = -ENOMEM;
				goto err_cleanup_map;
				goto err_release_umem;
			}

			buf->addr = (uintptr_t)vaddr;
@@ -237,8 +237,6 @@ int rxe_mr_init_user(struct rxe_pd *pd, u64 start, u64 length, u64 iova,

	return 0;

err_cleanup_map:
	rxe_mr_free_map_set(mr->num_map, mr->cur_map_set);
err_release_umem:
	ib_umem_release(umem);
err_out: