Skip to content

Commit b18c7da

Browse files
Bob Pearsonjgunthorpe
Bob Pearson
authored andcommitted
RDMA/rxe: Fix memory leak in error path code
In rxe_mr_init_user() at the third error the driver fails to free the memory at mr->map. This patch adds code to do that. This error only occurs if page_address() fails to return a non zero address which should never happen for 64 bit architectures. Fixes: 8700e3e ("Soft RoCE driver") Link: https://lore.kernel.org/r/[email protected] Reported by: Haakon Bugge <[email protected]> Signed-off-by: Bob Pearson <[email protected]> Reviewed-by: Zhu Yanjun <[email protected]> Reviewed-by: Håkon Bugge <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent c953883 commit b18c7da

File tree

1 file changed

+17
-10
lines changed

1 file changed

+17
-10
lines changed

drivers/infiniband/sw/rxe/rxe_mr.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -113,13 +113,14 @@ int rxe_mr_init_user(struct rxe_pd *pd, u64 start, u64 length, u64 iova,
113113
int num_buf;
114114
void *vaddr;
115115
int err;
116+
int i;
116117

117118
umem = ib_umem_get(pd->ibpd.device, start, length, access);
118119
if (IS_ERR(umem)) {
119-
pr_warn("err %d from rxe_umem_get\n",
120-
(int)PTR_ERR(umem));
120+
pr_warn("%s: Unable to pin memory region err = %d\n",
121+
__func__, (int)PTR_ERR(umem));
121122
err = PTR_ERR(umem);
122-
goto err1;
123+
goto err_out;
123124
}
124125

125126
mr->umem = umem;
@@ -129,9 +130,9 @@ int rxe_mr_init_user(struct rxe_pd *pd, u64 start, u64 length, u64 iova,
129130

130131
err = rxe_mr_alloc(mr, num_buf);
131132
if (err) {
132-
pr_warn("err %d from rxe_mr_alloc\n", err);
133-
ib_umem_release(umem);
134-
goto err1;
133+
pr_warn("%s: Unable to allocate memory for map\n",
134+
__func__);
135+
goto err_release_umem;
135136
}
136137

137138
mr->page_shift = PAGE_SHIFT;
@@ -151,10 +152,10 @@ int rxe_mr_init_user(struct rxe_pd *pd, u64 start, u64 length, u64 iova,
151152

152153
vaddr = page_address(sg_page_iter_page(&sg_iter));
153154
if (!vaddr) {
154-
pr_warn("null vaddr\n");
155-
ib_umem_release(umem);
155+
pr_warn("%s: Unable to get virtual address\n",
156+
__func__);
156157
err = -ENOMEM;
157-
goto err1;
158+
goto err_cleanup_map;
158159
}
159160

160161
buf->addr = (uintptr_t)vaddr;
@@ -177,7 +178,13 @@ int rxe_mr_init_user(struct rxe_pd *pd, u64 start, u64 length, u64 iova,
177178

178179
return 0;
179180

180-
err1:
181+
err_cleanup_map:
182+
for (i = 0; i < mr->num_map; i++)
183+
kfree(mr->map[i]);
184+
kfree(mr->map);
185+
err_release_umem:
186+
ib_umem_release(umem);
187+
err_out:
181188
return err;
182189
}
183190

0 commit comments

Comments
 (0)