From patchwork Tue Oct 6 04:32:57 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Junichi Nomura X-Patchwork-Id: 7333191 Return-Path: X-Original-To: patchwork-linux-scsi@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 980F59F1D5 for ; Tue, 6 Oct 2015 04:34:30 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id BAA0F20615 for ; Tue, 6 Oct 2015 04:34:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id BCAB020611 for ; Tue, 6 Oct 2015 04:34:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751330AbbJFEe2 (ORCPT ); Tue, 6 Oct 2015 00:34:28 -0400 Received: from TYO202.gate.nec.co.jp ([210.143.35.52]:54324 "EHLO tyo202.gate.nec.co.jp" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750902AbbJFEe1 convert rfc822-to-8bit (ORCPT ); Tue, 6 Oct 2015 00:34:27 -0400 Received: from mailgate3.nec.co.jp ([10.7.69.192]) by tyo202.gate.nec.co.jp (8.13.8/8.13.4) with ESMTP id t964YGPg022677; Tue, 6 Oct 2015 13:34:16 +0900 (JST) Received: from mailsv.nec.co.jp (imss61.nec.co.jp [10.7.69.156]) by mailgate3.nec.co.jp (8.11.7/3.7W-MAILGATE-NEC) with ESMTP id t964YG221139; Tue, 6 Oct 2015 13:34:16 +0900 (JST) Received: from mail01b.kamome.nec.co.jp (mail01b.kamome.nec.co.jp [10.25.43.2]) by mailsv.nec.co.jp (8.13.8/8.13.4) with ESMTP id t964YF9L021491; Tue, 6 Oct 2015 13:34:15 +0900 (JST) Received: from bpxc99gp.gisp.nec.co.jp ([10.38.151.139] [10.38.151.139]) by mail02.kamome.nec.co.jp with ESMTP id BT-MMP-2439620; Tue, 6 Oct 2015 13:32:58 +0900 Received: from BPXM12GP.gisp.nec.co.jp ([169.254.2.181]) by BPXC11GP.gisp.nec.co.jp ([10.38.151.139]) with mapi id 14.03.0224.002; Tue, 6 Oct 2015 13:32:57 +0900 From: Junichi Nomura To: linux-scsi CC: Christoph Hellwig , Hannes Reinecke Subject: [PATCH for v4.3-rc] scsi_dh: fix use-after-free when removing scsi device Thread-Topic: [PATCH for v4.3-rc] scsi_dh: fix use-after-free when removing scsi device Thread-Index: AQHQ//ATcClCDbnE2EuD8hpfIYYIRA== Date: Tue, 6 Oct 2015 04:32:57 +0000 Message-ID: <20151006043256.GA8193@xzibit.linux.bs1.fc.nec.co.jp> Accept-Language: ja-JP, en-US Content-Language: ja-JP X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.34.125.85] Content-ID: MIME-Version: 1.0 Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable 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 The commit 1bab0de0274f ("dm-mpath, scsi_dh: don't let dm detach device handlers") removed reference counting of attached scsi device handler. As a result, handler data is freed immediately via scsi_dh->detach() in the context of scsi_remove_device() where activation request can be still in flight. This patch moves scsi_dh_handler_detach() to sdev releasing function, scsi_device_dev_release_usercontext(), at that point the device is already in quiesced state. Fixes: 1bab0de0274f ("dm-mpath, scsi_dh: don't let dm detach device handlers") Signed-off-by: Jun'ichi Nomura Acked-by: Christoph Hellwig --- drivers/scsi/scsi_dh.c | 6 +++++- drivers/scsi/scsi_priv.h | 2 ++ drivers/scsi/scsi_sysfs.c | 2 ++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_dh.c b/drivers/scsi/scsi_dh.c index edb044a..19bf9db 100644 --- a/drivers/scsi/scsi_dh.c +++ b/drivers/scsi/scsi_dh.c @@ -232,10 +232,14 @@ int scsi_dh_add_device(struct scsi_device *sdev) return err; } -void scsi_dh_remove_device(struct scsi_device *sdev) +void scsi_dh_release_device(struct scsi_device *sdev) { if (sdev->handler) scsi_dh_handler_detach(sdev); +} + +void scsi_dh_remove_device(struct scsi_device *sdev) +{ device_remove_file(&sdev->sdev_gendev, &scsi_dh_state_attr); } diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index 644bb73..4d01cdb 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h @@ -173,9 +173,11 @@ extern struct async_domain scsi_sd_probe_domain; /* scsi_dh.c */ #ifdef CONFIG_SCSI_DH int scsi_dh_add_device(struct scsi_device *sdev); +void scsi_dh_release_device(struct scsi_device *sdev); void scsi_dh_remove_device(struct scsi_device *sdev); #else static inline int scsi_dh_add_device(struct scsi_device *sdev) { return 0; } +static inline void scsi_dh_release_device(struct scsi_device *sdev) { } static inline void scsi_dh_remove_device(struct scsi_device *sdev) { } #endif diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index b333389..dff8faf 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -399,6 +399,8 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work) sdev = container_of(work, struct scsi_device, ew.work); + scsi_dh_release_device(sdev); + parent = sdev->sdev_gendev.parent; spin_lock_irqsave(sdev->host->host_lock, flags);