diff options
author | Dan Carpenter <error27@gmail.com> | 2010-05-06 09:22:21 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2010-05-12 12:30:45 -0400 |
commit | 9fda1ac5fa09c49e9148f85be14f55e2bb856c0f (patch) | |
tree | def6cf681e460d54b6fc7fe148e5756fb9d5c4c0 /drivers/infiniband/ulp | |
parent | 39ff05dbbbdb082bbabf06206c56b3cd4ef73904 (diff) |
IB/iser: Fix error flow in iser_create_ib_conn_res()
We shouldn't free things here because we free them later.
The call tree looks like this:
iser_connect() ==> initiating the connection establishment
and later
iser_cma_handler() => iser_route_handler() => iser_create_ib_conn_res()
if we fail here, eventually iser_conn_release() is called, resulting
in a double free.
Signed-off-by: Dan Carpenter <error27@gmail.com>
Signed-off-by: Or Gerlitz <ogerlitz@voltaire.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/ulp')
-rw-r--r-- | drivers/infiniband/ulp/iser/iser_verbs.c | 25 |
1 files changed, 9 insertions, 16 deletions
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c index 78fdecacea35..9876865732f7 100644 --- a/drivers/infiniband/ulp/iser/iser_verbs.c +++ b/drivers/infiniband/ulp/iser/iser_verbs.c | |||
@@ -163,10 +163,8 @@ static int iser_create_ib_conn_res(struct iser_conn *ib_conn) | |||
163 | device = ib_conn->device; | 163 | device = ib_conn->device; |
164 | 164 | ||
165 | ib_conn->login_buf = kmalloc(ISER_RX_LOGIN_SIZE, GFP_KERNEL); | 165 | ib_conn->login_buf = kmalloc(ISER_RX_LOGIN_SIZE, GFP_KERNEL); |
166 | if (!ib_conn->login_buf) { | 166 | if (!ib_conn->login_buf) |
167 | goto alloc_err; | 167 | goto out_err; |
168 | ret = -ENOMEM; | ||
169 | } | ||
170 | 168 | ||
171 | ib_conn->login_dma = ib_dma_map_single(ib_conn->device->ib_device, | 169 | ib_conn->login_dma = ib_dma_map_single(ib_conn->device->ib_device, |
172 | (void *)ib_conn->login_buf, ISER_RX_LOGIN_SIZE, | 170 | (void *)ib_conn->login_buf, ISER_RX_LOGIN_SIZE, |
@@ -175,10 +173,9 @@ static int iser_create_ib_conn_res(struct iser_conn *ib_conn) | |||
175 | ib_conn->page_vec = kmalloc(sizeof(struct iser_page_vec) + | 173 | ib_conn->page_vec = kmalloc(sizeof(struct iser_page_vec) + |
176 | (sizeof(u64) * (ISCSI_ISER_SG_TABLESIZE +1)), | 174 | (sizeof(u64) * (ISCSI_ISER_SG_TABLESIZE +1)), |
177 | GFP_KERNEL); | 175 | GFP_KERNEL); |
178 | if (!ib_conn->page_vec) { | 176 | if (!ib_conn->page_vec) |
179 | ret = -ENOMEM; | 177 | goto out_err; |
180 | goto alloc_err; | 178 | |
181 | } | ||
182 | ib_conn->page_vec->pages = (u64 *) (ib_conn->page_vec + 1); | 179 | ib_conn->page_vec->pages = (u64 *) (ib_conn->page_vec + 1); |
183 | 180 | ||
184 | params.page_shift = SHIFT_4K; | 181 | params.page_shift = SHIFT_4K; |
@@ -198,7 +195,8 @@ static int iser_create_ib_conn_res(struct iser_conn *ib_conn) | |||
198 | ib_conn->fmr_pool = ib_create_fmr_pool(device->pd, ¶ms); | 195 | ib_conn->fmr_pool = ib_create_fmr_pool(device->pd, ¶ms); |
199 | if (IS_ERR(ib_conn->fmr_pool)) { | 196 | if (IS_ERR(ib_conn->fmr_pool)) { |
200 | ret = PTR_ERR(ib_conn->fmr_pool); | 197 | ret = PTR_ERR(ib_conn->fmr_pool); |
201 | goto fmr_pool_err; | 198 | ib_conn->fmr_pool = NULL; |
199 | goto out_err; | ||
202 | } | 200 | } |
203 | 201 | ||
204 | memset(&init_attr, 0, sizeof init_attr); | 202 | memset(&init_attr, 0, sizeof init_attr); |
@@ -216,7 +214,7 @@ static int iser_create_ib_conn_res(struct iser_conn *ib_conn) | |||
216 | 214 | ||
217 | ret = rdma_create_qp(ib_conn->cma_id, device->pd, &init_attr); | 215 | ret = rdma_create_qp(ib_conn->cma_id, device->pd, &init_attr); |
218 | if (ret) | 216 | if (ret) |
219 | goto qp_err; | 217 | goto out_err; |
220 | 218 | ||
221 | ib_conn->qp = ib_conn->cma_id->qp; | 219 | ib_conn->qp = ib_conn->cma_id->qp; |
222 | iser_err("setting conn %p cma_id %p: fmr_pool %p qp %p\n", | 220 | iser_err("setting conn %p cma_id %p: fmr_pool %p qp %p\n", |
@@ -224,12 +222,7 @@ static int iser_create_ib_conn_res(struct iser_conn *ib_conn) | |||
224 | ib_conn->fmr_pool, ib_conn->cma_id->qp); | 222 | ib_conn->fmr_pool, ib_conn->cma_id->qp); |
225 | return ret; | 223 | return ret; |
226 | 224 | ||
227 | qp_err: | 225 | out_err: |
228 | (void)ib_destroy_fmr_pool(ib_conn->fmr_pool); | ||
229 | fmr_pool_err: | ||
230 | kfree(ib_conn->page_vec); | ||
231 | kfree(ib_conn->login_buf); | ||
232 | alloc_err: | ||
233 | iser_err("unable to alloc mem or create resource, err %d\n", ret); | 226 | iser_err("unable to alloc mem or create resource, err %d\n", ret); |
234 | return ret; | 227 | return ret; |
235 | } | 228 | } |