Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

IB/srp: Fix srp_create_target() error handling

Avoid that the following kernel oops occurs if memory pool
allocation fails:

BUG: unable to handle kernel NULL pointer dereference at (null)
IP: [<ffffffffa048d0a0>] ib_drain_rq+0x0/0x20 [ib_core]
Call Trace:
[<ffffffffa04af386>] srp_create_target+0xca6/0x13a9 [ib_srp]
[<ffffffff813cc863>] dev_attr_store+0x13/0x20
[<ffffffff81214b50>] sysfs_kf_write+0x40/0x50
[<ffffffff81213f1c>] kernfs_fop_write+0x13c/0x180
[<ffffffff81197683>] __vfs_write+0x23/0xf0
[<ffffffff81198744>] vfs_write+0xa4/0x1a0
[<ffffffff81199a44>] SyS_write+0x44/0xa0
[<ffffffff8159e3e9>] entry_SYSCALL_64_fastpath+0x1c/0xac

Fixes: 1dc7b1f10dcb ("IB/srp: use the new CQ API")
Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Reviewed-by: Leon Romanovsky <leonro@mellanox.com>
Tested-by: Laurence Oberman <loberman@redhat.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Sagi Grimberg <sagi@grimberg.me>
Cc: <stable@vger.kernel.org> # v4.5+
Signed-off-by: Doug Ledford <dledford@redhat.com>

authored by

Bart Van Assche and committed by
Doug Ledford
f83b2561 9d8e7d0d

+7 -7
+7 -7
drivers/infiniband/ulp/srp/ib_srp.c
··· 447 447 448 448 /** 449 449 * srp_destroy_qp() - destroy an RDMA queue pair 450 - * @ch: SRP RDMA channel. 450 + * @qp: RDMA queue pair. 451 451 * 452 452 * Drain the qp before destroying it. This avoids that the receive 453 453 * completion handler can access the queue pair while it is 454 454 * being destroyed. 455 455 */ 456 - static void srp_destroy_qp(struct srp_rdma_ch *ch) 456 + static void srp_destroy_qp(struct ib_qp *qp) 457 457 { 458 - ib_drain_rq(ch->qp); 459 - ib_destroy_qp(ch->qp); 458 + ib_drain_rq(qp); 459 + ib_destroy_qp(qp); 460 460 } 461 461 462 462 static int srp_create_ch_ib(struct srp_rdma_ch *ch) ··· 529 529 } 530 530 531 531 if (ch->qp) 532 - srp_destroy_qp(ch); 532 + srp_destroy_qp(ch->qp); 533 533 if (ch->recv_cq) 534 534 ib_free_cq(ch->recv_cq); 535 535 if (ch->send_cq) ··· 553 553 return 0; 554 554 555 555 err_qp: 556 - srp_destroy_qp(ch); 556 + srp_destroy_qp(qp); 557 557 558 558 err_send_cq: 559 559 ib_free_cq(send_cq); ··· 596 596 ib_destroy_fmr_pool(ch->fmr_pool); 597 597 } 598 598 599 - srp_destroy_qp(ch); 599 + srp_destroy_qp(ch->qp); 600 600 ib_free_cq(ch->send_cq); 601 601 ib_free_cq(ch->recv_cq); 602 602