Skip to content

Commit e6daa8f

Browse files
Jack Wangjgunthorpe
authored andcommitted
RDMA/rtrs-srv: Fix stack-out-of-bounds
BUG: KASAN: stack-out-of-bounds in _mlx4_ib_post_send+0x1bd2/0x2770 [mlx4_ib] Read of size 4 at addr ffff8880d5a7f980 by task kworker/0:1H/565 CPU: 0 PID: 565 Comm: kworker/0:1H Tainted: G O 5.4.84-storage #5.4.84-1+feature+linux+5.4.y+dbg+20201216.1319+b6b887b~deb10 Hardware name: Supermicro H8QG6/H8QG6, BIOS 3.00 09/04/2012 Workqueue: ib-comp-wq ib_cq_poll_work [ib_core] Call Trace: dump_stack+0x96/0xe0 print_address_description.constprop.4+0x1f/0x300 ? irq_work_claim+0x2e/0x50 __kasan_report.cold.8+0x78/0x92 ? _mlx4_ib_post_send+0x1bd2/0x2770 [mlx4_ib] kasan_report+0x10/0x20 _mlx4_ib_post_send+0x1bd2/0x2770 [mlx4_ib] ? check_chain_key+0x1d7/0x2e0 ? _mlx4_ib_post_recv+0x630/0x630 [mlx4_ib] ? lockdep_hardirqs_on+0x1a8/0x290 ? stack_depot_save+0x218/0x56e ? do_profile_hits.isra.6.cold.13+0x1d/0x1d ? check_chain_key+0x1d7/0x2e0 ? save_stack+0x4d/0x80 ? save_stack+0x19/0x80 ? __kasan_slab_free+0x125/0x170 ? kfree+0xe7/0x3b0 rdma_write_sg+0x5b0/0x950 [rtrs_server] The problem is when we send imm_wr, the type should be ib_rdma_wr, so hw driver like mlx4 can do rdma_wr(wr), so fix it by use the ib_rdma_wr as type for imm_wr. Fixes: 9cb8374 ("RDMA/rtrs: server: main functionality") Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jack Wang <[email protected]> Reviewed-by: Gioh Kim <[email protected]> Reviewed-by: Leon Romanovsky <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent bf139b5 commit e6daa8f

File tree

1 file changed

+33
-31
lines changed

1 file changed

+33
-31
lines changed

drivers/infiniband/ulp/rtrs/rtrs-srv.c

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,8 @@ static int rdma_write_sg(struct rtrs_srv_op *id)
222222
dma_addr_t dma_addr = sess->dma_addr[id->msg_id];
223223
struct rtrs_srv_mr *srv_mr;
224224
struct rtrs_srv *srv = sess->srv;
225-
struct ib_send_wr inv_wr, imm_wr;
225+
struct ib_send_wr inv_wr;
226+
struct ib_rdma_wr imm_wr;
226227
struct ib_rdma_wr *wr = NULL;
227228
enum ib_send_flags flags;
228229
size_t sg_cnt;
@@ -274,15 +275,15 @@ static int rdma_write_sg(struct rtrs_srv_op *id)
274275
if (need_inval && always_invalidate) {
275276
wr->wr.next = &rwr.wr;
276277
rwr.wr.next = &inv_wr;
277-
inv_wr.next = &imm_wr;
278+
inv_wr.next = &imm_wr.wr;
278279
} else if (always_invalidate) {
279280
wr->wr.next = &rwr.wr;
280-
rwr.wr.next = &imm_wr;
281+
rwr.wr.next = &imm_wr.wr;
281282
} else if (need_inval) {
282283
wr->wr.next = &inv_wr;
283-
inv_wr.next = &imm_wr;
284+
inv_wr.next = &imm_wr.wr;
284285
} else {
285-
wr->wr.next = &imm_wr;
286+
wr->wr.next = &imm_wr.wr;
286287
}
287288
/*
288289
* From time to time we have to post signaled sends,
@@ -300,7 +301,7 @@ static int rdma_write_sg(struct rtrs_srv_op *id)
300301
inv_wr.ex.invalidate_rkey = rkey;
301302
}
302303

303-
imm_wr.next = NULL;
304+
imm_wr.wr.next = NULL;
304305
if (always_invalidate) {
305306
struct rtrs_msg_rkey_rsp *msg;
306307

@@ -321,22 +322,22 @@ static int rdma_write_sg(struct rtrs_srv_op *id)
321322
list.addr = srv_mr->iu->dma_addr;
322323
list.length = sizeof(*msg);
323324
list.lkey = sess->s.dev->ib_pd->local_dma_lkey;
324-
imm_wr.sg_list = &list;
325-
imm_wr.num_sge = 1;
326-
imm_wr.opcode = IB_WR_SEND_WITH_IMM;
325+
imm_wr.wr.sg_list = &list;
326+
imm_wr.wr.num_sge = 1;
327+
imm_wr.wr.opcode = IB_WR_SEND_WITH_IMM;
327328
ib_dma_sync_single_for_device(sess->s.dev->ib_dev,
328329
srv_mr->iu->dma_addr,
329330
srv_mr->iu->size, DMA_TO_DEVICE);
330331
} else {
331-
imm_wr.sg_list = NULL;
332-
imm_wr.num_sge = 0;
333-
imm_wr.opcode = IB_WR_RDMA_WRITE_WITH_IMM;
332+
imm_wr.wr.sg_list = NULL;
333+
imm_wr.wr.num_sge = 0;
334+
imm_wr.wr.opcode = IB_WR_RDMA_WRITE_WITH_IMM;
334335
}
335-
imm_wr.send_flags = flags;
336-
imm_wr.ex.imm_data = cpu_to_be32(rtrs_to_io_rsp_imm(id->msg_id,
336+
imm_wr.wr.send_flags = flags;
337+
imm_wr.wr.ex.imm_data = cpu_to_be32(rtrs_to_io_rsp_imm(id->msg_id,
337338
0, need_inval));
338339

339-
imm_wr.wr_cqe = &io_comp_cqe;
340+
imm_wr.wr.wr_cqe = &io_comp_cqe;
340341
ib_dma_sync_single_for_device(sess->s.dev->ib_dev, dma_addr,
341342
offset, DMA_BIDIRECTIONAL);
342343

@@ -363,7 +364,8 @@ static int send_io_resp_imm(struct rtrs_srv_con *con, struct rtrs_srv_op *id,
363364
{
364365
struct rtrs_sess *s = con->c.sess;
365366
struct rtrs_srv_sess *sess = to_srv_sess(s);
366-
struct ib_send_wr inv_wr, imm_wr, *wr = NULL;
367+
struct ib_send_wr inv_wr, *wr = NULL;
368+
struct ib_rdma_wr imm_wr;
367369
struct ib_reg_wr rwr;
368370
struct rtrs_srv *srv = sess->srv;
369371
struct rtrs_srv_mr *srv_mr;
@@ -400,15 +402,15 @@ static int send_io_resp_imm(struct rtrs_srv_con *con, struct rtrs_srv_op *id,
400402
if (need_inval && always_invalidate) {
401403
wr = &inv_wr;
402404
inv_wr.next = &rwr.wr;
403-
rwr.wr.next = &imm_wr;
405+
rwr.wr.next = &imm_wr.wr;
404406
} else if (always_invalidate) {
405407
wr = &rwr.wr;
406-
rwr.wr.next = &imm_wr;
408+
rwr.wr.next = &imm_wr.wr;
407409
} else if (need_inval) {
408410
wr = &inv_wr;
409-
inv_wr.next = &imm_wr;
411+
inv_wr.next = &imm_wr.wr;
410412
} else {
411-
wr = &imm_wr;
413+
wr = &imm_wr.wr;
412414
}
413415
/*
414416
* From time to time we have to post signalled sends,
@@ -417,13 +419,13 @@ static int send_io_resp_imm(struct rtrs_srv_con *con, struct rtrs_srv_op *id,
417419
flags = (atomic_inc_return(&con->wr_cnt) % srv->queue_depth) ?
418420
0 : IB_SEND_SIGNALED;
419421
imm = rtrs_to_io_rsp_imm(id->msg_id, errno, need_inval);
420-
imm_wr.next = NULL;
422+
imm_wr.wr.next = NULL;
421423
if (always_invalidate) {
422424
struct ib_sge list;
423425
struct rtrs_msg_rkey_rsp *msg;
424426

425427
srv_mr = &sess->mrs[id->msg_id];
426-
rwr.wr.next = &imm_wr;
428+
rwr.wr.next = &imm_wr.wr;
427429
rwr.wr.opcode = IB_WR_REG_MR;
428430
rwr.wr.wr_cqe = &local_reg_cqe;
429431
rwr.wr.num_sge = 0;
@@ -440,21 +442,21 @@ static int send_io_resp_imm(struct rtrs_srv_con *con, struct rtrs_srv_op *id,
440442
list.addr = srv_mr->iu->dma_addr;
441443
list.length = sizeof(*msg);
442444
list.lkey = sess->s.dev->ib_pd->local_dma_lkey;
443-
imm_wr.sg_list = &list;
444-
imm_wr.num_sge = 1;
445-
imm_wr.opcode = IB_WR_SEND_WITH_IMM;
445+
imm_wr.wr.sg_list = &list;
446+
imm_wr.wr.num_sge = 1;
447+
imm_wr.wr.opcode = IB_WR_SEND_WITH_IMM;
446448
ib_dma_sync_single_for_device(sess->s.dev->ib_dev,
447449
srv_mr->iu->dma_addr,
448450
srv_mr->iu->size, DMA_TO_DEVICE);
449451
} else {
450-
imm_wr.sg_list = NULL;
451-
imm_wr.num_sge = 0;
452-
imm_wr.opcode = IB_WR_RDMA_WRITE_WITH_IMM;
452+
imm_wr.wr.sg_list = NULL;
453+
imm_wr.wr.num_sge = 0;
454+
imm_wr.wr.opcode = IB_WR_RDMA_WRITE_WITH_IMM;
453455
}
454-
imm_wr.send_flags = flags;
455-
imm_wr.wr_cqe = &io_comp_cqe;
456+
imm_wr.wr.send_flags = flags;
457+
imm_wr.wr.wr_cqe = &io_comp_cqe;
456458

457-
imm_wr.ex.imm_data = cpu_to_be32(imm);
459+
imm_wr.wr.ex.imm_data = cpu_to_be32(imm);
458460

459461
err = ib_post_send(id->con->c.qp, wr, NULL);
460462
if (unlikely(err))

0 commit comments

Comments
 (0)