aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSagi Grimberg <sagig@mellanox.com>2015-08-24 12:04:51 -0400
committerDoug Ledford <dledford@redhat.com>2015-09-03 15:59:48 -0400
commit7fbc67df2cd6d0b72fd5d6d3acaa79ab6f5b0224 (patch)
tree83730c17d8dd8aedc08e8740966fdebd5b962881
parent0629cb06cdf8f1a403ce71bce5b83380ae898e1a (diff)
IB/srp: Fix possible protection fault
srp_destroy_qp is designed to indicate we are safe to continue with freeing the channel resources by modifying the qp error state, posting a dummy wr on the queue-pair and waiting for it to flush. This also holds for the channel registration pool as we are unmapping the memory region when handling a scsi response. Destroying the channel registration pool before we make sure we processed all the inflight IO might introduce a use-after-free of the registration pool. This use-after-free is demonstrated in the stack trace below where srp is trying to unmap a used FMR after the fmr_pool was already destroyed. general protection fault: 0000 [#1] SMP RIP: 0010:[<ffffffff8151121b>] [<ffffffff8151121b>] _raw_spin_lock_irqsave+0x1b/0x50 Call Trace: [<ffffffffa055d88a>] ib_fmr_pool_unmap+0x1a/0xb0 [ib_core] [<ffffffffa06c00ed>] srp_unmap_data.isra.28+0x17d/0x250 [ib_srp] [<ffffffffa06c01eb>] srp_free_req+0x2b/0x60 [ib_srp] [<ffffffffa06c0c94>] srp_recv_completion+0x174/0x580 [ib_srp] [<ffffffffa04580fe>] mlx4_eq_int+0x4de/0xe50 [mlx4_core] [<ffffffffa0458b00>] mlx4_msi_x_interrupt+0x10/0x20 [mlx4_core] [<ffffffff810abc45>] handle_irq_event_percpu+0x35/0x1b0 [<ffffffff810abdf2>] handle_irq_event+0x32/0x50 [<ffffffff810ae5cf>] handle_edge_irq+0x6f/0x120 [<ffffffff8100455a>] handle_irq+0x1a/0x30 [<ffffffff8151b475>] do_IRQ+0x45/0xb0 [<ffffffff8151162d>] common_interrupt+0x6d/0x6d [<ffffffff813e4d2f>] cpuidle_enter_state+0x4f/0xc0 [<ffffffff813e4e6c>] cpuidle_idle_call+0xcc/0x210 [<ffffffff8100b9ea>] arch_cpu_idle+0xa/0x30 [<ffffffff810ab1e1>] cpu_startup_entry+0xe1/0x270 [<ffffffff81030b3a>] start_secondary+0x21a/0x2c0 Reported-by: Eliott Kespi <eliottk@mellanox.com> Signed-off-by: Sagi Grimberg <sagig@mellanox.com> Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index ca98d3b47281..b481490ad257 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -554,9 +554,6 @@ static int srp_create_ch_ib(struct srp_rdma_ch *ch)
554 "FR pool allocation failed (%d)\n", ret); 554 "FR pool allocation failed (%d)\n", ret);
555 goto err_qp; 555 goto err_qp;
556 } 556 }
557 if (ch->fr_pool)
558 srp_destroy_fr_pool(ch->fr_pool);
559 ch->fr_pool = fr_pool;
560 } else if (dev->use_fmr) { 557 } else if (dev->use_fmr) {
561 fmr_pool = srp_alloc_fmr_pool(target); 558 fmr_pool = srp_alloc_fmr_pool(target);
562 if (IS_ERR(fmr_pool)) { 559 if (IS_ERR(fmr_pool)) {
@@ -565,9 +562,6 @@ static int srp_create_ch_ib(struct srp_rdma_ch *ch)
565 "FMR pool allocation failed (%d)\n", ret); 562 "FMR pool allocation failed (%d)\n", ret);
566 goto err_qp; 563 goto err_qp;
567 } 564 }
568 if (ch->fmr_pool)
569 ib_destroy_fmr_pool(ch->fmr_pool);
570 ch->fmr_pool = fmr_pool;
571 } 565 }
572 566
573 if (ch->qp) 567 if (ch->qp)
@@ -581,6 +575,16 @@ static int srp_create_ch_ib(struct srp_rdma_ch *ch)
581 ch->recv_cq = recv_cq; 575 ch->recv_cq = recv_cq;
582 ch->send_cq = send_cq; 576 ch->send_cq = send_cq;
583 577
578 if (dev->use_fast_reg) {
579 if (ch->fr_pool)
580 srp_destroy_fr_pool(ch->fr_pool);
581 ch->fr_pool = fr_pool;
582 } else if (dev->use_fmr) {
583 if (ch->fmr_pool)
584 ib_destroy_fmr_pool(ch->fmr_pool);
585 ch->fmr_pool = fmr_pool;
586 }
587
584 kfree(init_attr); 588 kfree(init_attr);
585 return 0; 589 return 0;
586 590