From patchwork Mon Aug 10 14:22:54 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sagi Grimberg X-Patchwork-Id: 6984821 Return-Path: X-Original-To: patchwork-linux-rdma@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id F2C659F373 for ; Mon, 10 Aug 2015 14:23:25 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id DF68B2051C for ; Mon, 10 Aug 2015 14:23:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C5164202DD for ; Mon, 10 Aug 2015 14:23:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752767AbbHJOXV (ORCPT ); Mon, 10 Aug 2015 10:23:21 -0400 Received: from [193.47.165.129] ([193.47.165.129]:43506 "EHLO mellanox.co.il" rhost-flags-FAIL-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1751592AbbHJOXU (ORCPT ); Mon, 10 Aug 2015 10:23:20 -0400 Received: from Internal Mail-Server by MTLPINE1 (envelope-from sagig@mellanox.com) with ESMTPS (AES256-SHA encrypted); 10 Aug 2015 17:22:55 +0300 Received: from r-vnc05.mtr.labs.mlnx (r-vnc05.mtr.labs.mlnx [10.208.0.115]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id t7AEMtBf003785; Mon, 10 Aug 2015 17:22:55 +0300 Received: from r-vnc05.mtr.labs.mlnx (localhost [127.0.0.1]) by r-vnc05.mtr.labs.mlnx (8.14.4/8.14.4) with ESMTP id t7AEMtYa025984; Mon, 10 Aug 2015 17:22:55 +0300 Received: (from sagig@localhost) by r-vnc05.mtr.labs.mlnx (8.14.4/8.14.4/Submit) id t7AEMsm1025980; Mon, 10 Aug 2015 17:22:54 +0300 From: Sagi Grimberg To: Bart Van Assche , linux-rdma@vger.kernel.org Subject: [PATCH] IB/srp: Fix possible use-after-free Date: Mon, 10 Aug 2015 17:22:54 +0300 Message-Id: <1439216574-25936-1-git-send-email-sagig@mellanox.com> X-Mailer: git-send-email 1.8.4.3 Sender: linux-rdma-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rdma@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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:[] [] _raw_spin_lock_irqsave+0x1b/0x50 Call Trace: [] ib_fmr_pool_unmap+0x1a/0xb0 [ib_core] [] srp_unmap_data+0x17d/0x250 [ib_srp] [] srp_free_req+0x2b/0x60 [ib_srp] [] srp_recv_completion+0x174/0x580 [ib_srp] [] mlx4_eq_int+0x4de/0xe50 [mlx4_core] [] mlx4_msi_x_interrupt+0x10/0x20 [mlx4_core] [] handle_irq_event_percpu+0x35/0x1b0 [] handle_irq_event+0x32/0x50 [] handle_edge_irq+0x6f/0x120 [] handle_irq+0x1a/0x30 [] do_IRQ+0x45/0xb0 [] common_interrupt+0x6d/0x6d [] cpuidle_enter_state+0x4f/0xc0 [] cpuidle_idle_call+0xcc/0x210 [] arch_cpu_idle+0xa/0x30 [] cpu_startup_entry+0xe1/0x270 [] start_secondary+0x21a/0x2c0 Reported-by: Eliott Kespi Signed-off-by: Sagi Grimberg --- drivers/infiniband/ulp/srp/ib_srp.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 3a1514c..93eadfb 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -620,6 +620,10 @@ static void srp_free_ch_ib(struct srp_target_port *target, if (!ch->qp) return; + srp_destroy_qp(ch); + ib_destroy_cq(ch->send_cq); + ib_destroy_cq(ch->recv_cq); + if (dev->use_fast_reg) { if (ch->fr_pool) srp_destroy_fr_pool(ch->fr_pool); @@ -627,9 +631,6 @@ static void srp_free_ch_ib(struct srp_target_port *target, if (ch->fmr_pool) ib_destroy_fmr_pool(ch->fmr_pool); } - srp_destroy_qp(ch); - ib_destroy_cq(ch->send_cq); - ib_destroy_cq(ch->recv_cq); /* * Avoid that the SCSI error handler tries to use this channel after