From patchwork Tue Jul 12 22:19:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bart Van Assche X-Patchwork-Id: 589996 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B39C5C43334 for ; Tue, 12 Jul 2022 22:19:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232386AbiGLWTt (ORCPT ); Tue, 12 Jul 2022 18:19:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37588 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230010AbiGLWTr (ORCPT ); Tue, 12 Jul 2022 18:19:47 -0400 Received: from mail-pj1-f43.google.com (mail-pj1-f43.google.com [209.85.216.43]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B1C3332EF8 for ; Tue, 12 Jul 2022 15:19:46 -0700 (PDT) Received: by mail-pj1-f43.google.com with SMTP id i8-20020a17090a4b8800b001ef8a65bfbdso578023pjh.1 for ; Tue, 12 Jul 2022 15:19:46 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=l7t/LiMMlcRYUk+orrbi6bYOidjg0HO2tcia+QqtEDE=; b=zZkNoewAaUbItlp5fu6LQu3919ZUHMqPB0R4QHFwvkhTRer4TlQN2rBfH2sOlSSDkr ldluJQbHawgr6qkXkdty7yQADjqijmWr0kR2ZTemau1yEIUHO0JLo7/fxnGmHTYcrXKV 7DQyVANX+048mv5rJgg7FtGXrDavUTBajdxqTNOG8WYdwaD34wc6qNRa7PpXJqyXwvGR BBh5KpQlk0PKbWWUNgbvJ17IiL3c1Dw01GpAFUE5V7jWzYPX7VgK+bUMGqEatgRV5tWY Gep7TbjKlqvvF5INuPbNoa9kTS6gW979IGR6xajmQ3NCgkWOTreRXY+32x7NXSu6SsNG 5OPw== X-Gm-Message-State: AJIora/NNljhsS3oqv1k3fL1fJ9Wj5EMjyAw6Cq8LsMvoVmMS+i4368Z ARRi1/fq7wzaoFhRqc2xvVE= X-Google-Smtp-Source: AGRyM1uxQQGrXIr+7eVnADsghlYDzhSdo/AhLZuiPli9g2atpM4Hc9MzvhapFPTN96NNTASC3NKgOw== X-Received: by 2002:a17:902:d395:b0:16b:e5e9:ac59 with SMTP id e21-20020a170902d39500b0016be5e9ac59mr189255pld.74.1657664386064; Tue, 12 Jul 2022 15:19:46 -0700 (PDT) Received: from bvanassche-linux.mtv.corp.google.com ([2620:15c:211:201:de3c:137c:f4d2:d291]) by smtp.gmail.com with ESMTPSA id w12-20020a63f50c000000b0040d0a57be02sm6640192pgh.31.2022.07.12.15.19.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Jul 2022 15:19:45 -0700 (PDT) From: Bart Van Assche To: "Martin K . Petersen" Cc: Jaegeuk Kim , linux-scsi@vger.kernel.org, Bart Van Assche , Mike Christie , Christoph Hellwig , Ming Lei , Hannes Reinecke , John Garry , Li Zhijian Subject: [PATCH v4 1/4] scsi: core: Make sure that targets outlive devices Date: Tue, 12 Jul 2022 15:19:33 -0700 Message-Id: <20220712221936.1199196-2-bvanassche@acm.org> X-Mailer: git-send-email 2.37.0.144.g8ac04bfd2-goog In-Reply-To: <20220712221936.1199196-1-bvanassche@acm.org> References: <20220712221936.1199196-1-bvanassche@acm.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org This patch prevents that the following sequence triggers a kernel crash: * Deletion of a SCSI device is requested via sysfs. Device removal takes some time because blk_cleanup_queue() is waiting for the SCSI error handler. * The SCSI target associated with that SCSI device is removed. * scsi_remove_target() returns and its caller frees the resources associated with the SCSI target. * The error handler makes progress and invokes an LLD callback that dereferences the SCSI target pointer. Reported-by: Mike Christie Cc: Christoph Hellwig Cc: Ming Lei Cc: Mike Christie Cc: Hannes Reinecke Cc: John Garry Cc: Li Zhijian Signed-off-by: Bart Van Assche Reviewed-by: Ming Lei --- drivers/scsi/scsi_scan.c | 2 ++ drivers/scsi/scsi_sysfs.c | 20 +++++++++++++++++--- include/scsi/scsi_device.h | 2 ++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 91ac901a6682..4c1efd6a3b0c 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -521,6 +521,8 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, starget->state = STARGET_CREATED; starget->scsi_level = SCSI_2; starget->max_target_blocked = SCSI_DEFAULT_TARGET_BLOCKED; + init_waitqueue_head(&starget->sdev_wq); + retry: spin_lock_irqsave(shost->host_lock, flags); diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 43949798a2e4..1bc9c26fe1d4 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -443,7 +443,9 @@ static void scsi_device_cls_release(struct device *class_dev) static void scsi_device_dev_release_usercontext(struct work_struct *work) { - struct scsi_device *sdev; + struct scsi_device *sdev = container_of(work, struct scsi_device, + ew.work); + struct scsi_target *starget = sdev->sdev_target; struct device *parent; struct list_head *this, *tmp; struct scsi_vpd *vpd_pg80 = NULL, *vpd_pg83 = NULL; @@ -452,8 +454,6 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work) unsigned long flags; struct module *mod; - sdev = container_of(work, struct scsi_device, ew.work); - mod = sdev->host->hostt->module; scsi_dh_release_device(sdev); @@ -516,6 +516,9 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work) kfree(sdev->inquiry); kfree(sdev); + if (starget && atomic_dec_return(&starget->sdev_count) == 0) + wake_up(&starget->sdev_wq); + if (parent) put_device(parent); module_put(mod); @@ -1535,6 +1538,14 @@ static void __scsi_remove_target(struct scsi_target *starget) goto restart; } spin_unlock_irqrestore(shost->host_lock, flags); + + /* + * After scsi_remove_target() returns its caller can remove resources + * associated with @starget, e.g. an rport or session. Wait until all + * devices associated with @starget have been removed to prevent that + * a SCSI error handling callback function triggers a use-after-free. + */ + wait_event(starget->sdev_wq, atomic_read(&starget->sdev_count) == 0); } /** @@ -1645,6 +1656,9 @@ void scsi_sysfs_device_initialize(struct scsi_device *sdev) list_add_tail(&sdev->same_target_siblings, &starget->devices); list_add_tail(&sdev->siblings, &shost->__devices); spin_unlock_irqrestore(shost->host_lock, flags); + + atomic_inc(&starget->sdev_count); + /* * device can now only be removed via __scsi_remove_device() so hold * the target. Target will be held in CREATED state until something diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 7cf5f3b7589f..190d2081f4c6 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -309,6 +309,8 @@ struct scsi_target { struct list_head devices; struct device dev; struct kref reap_ref; /* last put renders target invisible */ + atomic_t sdev_count; + wait_queue_head_t sdev_wq; unsigned int channel; unsigned int id; /* target id ... replace * scsi_device.id eventually */ From patchwork Tue Jul 12 22:19:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bart Van Assche X-Patchwork-Id: 590754 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E8982C433EF for ; Tue, 12 Jul 2022 22:19:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232907AbiGLWTy (ORCPT ); Tue, 12 Jul 2022 18:19:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37630 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230010AbiGLWTu (ORCPT ); Tue, 12 Jul 2022 18:19:50 -0400 Received: from mail-pg1-f182.google.com (mail-pg1-f182.google.com [209.85.215.182]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C574532EF8 for ; Tue, 12 Jul 2022 15:19:48 -0700 (PDT) Received: by mail-pg1-f182.google.com with SMTP id e132so8834661pgc.5 for ; Tue, 12 Jul 2022 15:19:48 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=B2VpnzpxPX3Pmo2QoyyBQCVYsbY7t6a8XWBDIqfLwcI=; b=OdR21mxyXx1dY9gBH9c3106D971gPUteOitAZkm2Yvyw8N6tNwpJn2kf8JDkVstEVn mY+V21GHLPTF8jfELo31M1vvACIg3Yo6CzG/C1vIP7+7hp5bnWva/Ylfzs63A5z5RVzT 20AT4zqtyds/hS4AedxtTVkuz+abBJqtTDpd+Olv9UKO8Y61Xm3Q02Z5pEZG2p+KrPfb v7sAt9mryWEWJPrlYYJ5TtgDkTdQA+swC2d6vvMbcbAusodjccwBwnUZIqoUxBKYcHmK ylCcYQu/Hc1oJ0t8V6dlYD4XipCAeat2mJFahA20/vDxmI8+89CsXPAEB/9FZpp37Hd/ sBjg== X-Gm-Message-State: AJIora8K+OiWHCmqElY23WNP3uE0rNQJXZo1s4pCcIMOGDaoVtgRpoIH S4NnlpUBAuHTFHeGyRjnfnArsHkCHFI= X-Google-Smtp-Source: AGRyM1uvt6cAmBctGapSp5CPN/mP/gkVJ3qbkxAySvLyBLCO8E2DrgnDvf9b3REX9CwJDaY42QAuUg== X-Received: by 2002:a63:2bc4:0:b0:419:7b8c:210a with SMTP id r187-20020a632bc4000000b004197b8c210amr330099pgr.439.1657664388018; Tue, 12 Jul 2022 15:19:48 -0700 (PDT) Received: from bvanassche-linux.mtv.corp.google.com ([2620:15c:211:201:de3c:137c:f4d2:d291]) by smtp.gmail.com with ESMTPSA id w12-20020a63f50c000000b0040d0a57be02sm6640192pgh.31.2022.07.12.15.19.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Jul 2022 15:19:47 -0700 (PDT) From: Bart Van Assche To: "Martin K . Petersen" Cc: Jaegeuk Kim , linux-scsi@vger.kernel.org, Bart Van Assche , Ming Lei , Christoph Hellwig , Mike Christie , Hannes Reinecke , John Garry Subject: [PATCH v4 2/4] scsi: core: Make sure that hosts outlive targets Date: Tue, 12 Jul 2022 15:19:34 -0700 Message-Id: <20220712221936.1199196-3-bvanassche@acm.org> X-Mailer: git-send-email 2.37.0.144.g8ac04bfd2-goog In-Reply-To: <20220712221936.1199196-1-bvanassche@acm.org> References: <20220712221936.1199196-1-bvanassche@acm.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Ming Lei Fix the race conditions between SCSI LLD kernel module unloading and SCSI device and target removal by making sure that SCSI hosts are destroyed after all associated target and device objects have been freed. Cc: Christoph Hellwig Cc: Ming Lei Cc: Mike Christie Cc: Hannes Reinecke Cc: John Garry Signed-off-by: Ming Lei Signed-off-by: Bart Van Assche [ bvanassche: Reworked Ming's patch and split it ] --- drivers/scsi/hosts.c | 8 ++++++++ drivers/scsi/scsi_scan.c | 7 +++++++ include/scsi/scsi_host.h | 3 +++ 3 files changed, 18 insertions(+) diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index ef6c0e37acce..8fa98c8d0ee0 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -190,6 +190,13 @@ void scsi_remove_host(struct Scsi_Host *shost) transport_unregister_device(&shost->shost_gendev); device_unregister(&shost->shost_dev); device_del(&shost->shost_gendev); + + /* + * After scsi_remove_host() has returned the scsi LLD module can be + * unloaded and/or the host resources can be released. Hence wait until + * the dependent SCSI targets and devices are gone before returning. + */ + wait_event(shost->targets_wq, atomic_read(&shost->target_count) == 0); } EXPORT_SYMBOL(scsi_remove_host); @@ -394,6 +401,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) INIT_LIST_HEAD(&shost->starved_list); init_waitqueue_head(&shost->host_wait); mutex_init(&shost->scan_mutex); + init_waitqueue_head(&shost->targets_wq); index = ida_alloc(&host_index_ida, GFP_KERNEL); if (index < 0) { diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 4c1efd6a3b0c..ac6059702d13 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -406,9 +406,14 @@ static void scsi_target_destroy(struct scsi_target *starget) static void scsi_target_dev_release(struct device *dev) { struct device *parent = dev->parent; + struct Scsi_Host *shost = dev_to_shost(parent); struct scsi_target *starget = to_scsi_target(dev); kfree(starget); + + if (atomic_dec_return(&shost->target_count) == 0) + wake_up(&shost->targets_wq); + put_device(parent); } @@ -523,6 +528,8 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, starget->max_target_blocked = SCSI_DEFAULT_TARGET_BLOCKED; init_waitqueue_head(&starget->sdev_wq); + atomic_inc(&shost->target_count); + retry: spin_lock_irqsave(shost->host_lock, flags); diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 667d889b92b5..339f975d356e 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -689,6 +689,9 @@ struct Scsi_Host { /* ldm bits */ struct device shost_gendev, shost_dev; + atomic_t target_count; + wait_queue_head_t targets_wq; + /* * Points to the transport data (if any) which is allocated * separately From patchwork Tue Jul 12 22:19:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bart Van Assche X-Patchwork-Id: 589995 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 320ABCCA47F for ; Tue, 12 Jul 2022 22:19:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232913AbiGLWTz (ORCPT ); Tue, 12 Jul 2022 18:19:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37632 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232476AbiGLWTu (ORCPT ); Tue, 12 Jul 2022 18:19:50 -0400 Received: from mail-pf1-f175.google.com (mail-pf1-f175.google.com [209.85.210.175]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 26DC73335D for ; Tue, 12 Jul 2022 15:19:50 -0700 (PDT) Received: by mail-pf1-f175.google.com with SMTP id a15so8612479pfv.13 for ; Tue, 12 Jul 2022 15:19:50 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=PK7GhXluDeO7vB7OgT+f4kVleUWpGV4FgrTIBb4orbk=; b=lLINBmHuVGUfEK0t9Ny3VskTDnhOMoHp9vJLutae4RAw9pvwI9qTR4RUcXQSuKZFkK xLVtsX+mh2EoyFBElgWDfGshuJf0FPj0jYG2KgZP2CmeLBtw6e9K39RuiQaHwlsN0nij 4Kkb6QpHeK2OolRfyjgw++7TBCvDlmC1Ra8rdXu4/gppa+RGPfCU1NdNhpmgfVjPooHH yNiiAfDkKAV8REwuec5LJmSe0Eu/zRi7pj/h03W8JS+JrS6du0RdEBjuNKi0eJqvqsp1 EFAGGj2dmyvEV27HwMP6sXl/qoWEUaJTLuV3D+nhiscqYT54yF4oC2owuBB9aRpzR/c4 LDbg== X-Gm-Message-State: AJIora9nkqWrDIGDE04LAwTRfnHhRuHg4a1ttIf4tM/vWa7njA7V6p+q +kAv46NpOr0GFPHSHikJ8t8= X-Google-Smtp-Source: AGRyM1vOM7aQaeP2D80qPoRrpURdwVIKoBJ/DBC5MrNO17Ywdp3YpoZTOe2kg2Hz08bhbj7kntYydA== X-Received: by 2002:a63:460f:0:b0:412:7a8b:128c with SMTP id t15-20020a63460f000000b004127a8b128cmr371256pga.270.1657664389569; Tue, 12 Jul 2022 15:19:49 -0700 (PDT) Received: from bvanassche-linux.mtv.corp.google.com ([2620:15c:211:201:de3c:137c:f4d2:d291]) by smtp.gmail.com with ESMTPSA id w12-20020a63f50c000000b0040d0a57be02sm6640192pgh.31.2022.07.12.15.19.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Jul 2022 15:19:48 -0700 (PDT) From: Bart Van Assche To: "Martin K . Petersen" Cc: Jaegeuk Kim , linux-scsi@vger.kernel.org, Bart Van Assche , Ming Lei , Christoph Hellwig , Mike Christie , Hannes Reinecke , John Garry Subject: [PATCH v4 3/4] scsi: core: Simplify LLD module reference counting Date: Tue, 12 Jul 2022 15:19:35 -0700 Message-Id: <20220712221936.1199196-4-bvanassche@acm.org> X-Mailer: git-send-email 2.37.0.144.g8ac04bfd2-goog In-Reply-To: <20220712221936.1199196-1-bvanassche@acm.org> References: <20220712221936.1199196-1-bvanassche@acm.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Ming Lei Swap two statements in scsi_device_put() now that it is guaranteed that SCSI hosts outlive SCSI devices. Remove the reference counting code from scsi_sysfs.c that became superfluous because SCSI hosts now outlive SCSI devices. Cc: Christoph Hellwig Cc: Ming Lei Cc: Mike Christie Cc: Hannes Reinecke Cc: John Garry Signed-off-by: Ming Lei Signed-off-by: Bart Van Assche [ bvanassche: Extracted this patch from a larger patch ] --- drivers/scsi/scsi.c | 9 ++++++--- drivers/scsi/scsi_sysfs.c | 9 --------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index c59eac7a32f2..086ec5b5862d 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -586,10 +586,13 @@ EXPORT_SYMBOL(scsi_device_get); */ void scsi_device_put(struct scsi_device *sdev) { - struct module *mod = sdev->host->hostt->module; - + /* + * Decreasing the module reference count before the device reference + * count is safe since scsi_remove_host() only returns after all + * devices have been removed. + */ + module_put(sdev->host->hostt->module); put_device(&sdev->sdev_gendev); - module_put(mod); } EXPORT_SYMBOL(scsi_device_put); diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 1bc9c26fe1d4..213ebc88f76a 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -452,9 +452,6 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work) struct scsi_vpd *vpd_pg0 = NULL, *vpd_pg89 = NULL; struct scsi_vpd *vpd_pgb0 = NULL, *vpd_pgb1 = NULL, *vpd_pgb2 = NULL; unsigned long flags; - struct module *mod; - - mod = sdev->host->hostt->module; scsi_dh_release_device(sdev); @@ -521,17 +518,11 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work) if (parent) put_device(parent); - module_put(mod); } static void scsi_device_dev_release(struct device *dev) { struct scsi_device *sdp = to_scsi_device(dev); - - /* Set module pointer as NULL in case of module unloading */ - if (!try_module_get(sdp->host->hostt->module)) - sdp->host->hostt->module = NULL; - execute_in_process_context(scsi_device_dev_release_usercontext, &sdp->ew); } From patchwork Tue Jul 12 22:19:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bart Van Assche X-Patchwork-Id: 590753 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0F88DC43334 for ; Tue, 12 Jul 2022 22:19:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233026AbiGLWT4 (ORCPT ); Tue, 12 Jul 2022 18:19:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37664 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232683AbiGLWTw (ORCPT ); Tue, 12 Jul 2022 18:19:52 -0400 Received: from mail-pj1-f41.google.com (mail-pj1-f41.google.com [209.85.216.41]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ADBB833343 for ; Tue, 12 Jul 2022 15:19:51 -0700 (PDT) Received: by mail-pj1-f41.google.com with SMTP id t5-20020a17090a6a0500b001ef965b262eso553195pjj.5 for ; Tue, 12 Jul 2022 15:19:51 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=gp31xlzEC2i02lVg8krLl11Lk6DbeUjrmj3d4p0+mVE=; b=wMusbTcoWpqWoKElAUZyZjLAETRQjzXlFhWCn6bpLSyWV/GAn0ilLXSG/pC/xDb40J Zb7RHwwtDW8FUykgH+0syvT9PwAMJ2h3nVkgmbczvSmREg9QfYcvnDangKT2MPkttmaM 2eN2BN9+TRYBlXSyeawZ/sdYqz9XtdyFtQrNdSSCnqxvV4GakO55hs3oWDxOSqRGVkXM jcW8HQ/kIjDDi4JQKpTXtPynuMvxoECGn3yIJa9FiKveEE+GOYfMlq4MQmW3PFy8vyXI 56+FAsB3oSiX7sw/Aa428+IPvhS4UCH5UYScxNIuoN84oq5pJ3YSzjZo+kl+8V4RrO2s fI6w== X-Gm-Message-State: AJIora8t6Y/32qdc/QK4fRuFi799M5/rNMVDQh9wlMxj1QaklfTltW2T aI9ufxb4qV4hiK1unGjywN0= X-Google-Smtp-Source: AGRyM1t3rfLgdVRcPwwFoR8Yy3cITjfVMuyxAjOUjMyqNf9Q9evLpz1y8i2td5d4WNG6ciaZqkWAxQ== X-Received: by 2002:a17:902:efd1:b0:16b:dc3b:7fbc with SMTP id ja17-20020a170902efd100b0016bdc3b7fbcmr388867plb.45.1657664391127; Tue, 12 Jul 2022 15:19:51 -0700 (PDT) Received: from bvanassche-linux.mtv.corp.google.com ([2620:15c:211:201:de3c:137c:f4d2:d291]) by smtp.gmail.com with ESMTPSA id w12-20020a63f50c000000b0040d0a57be02sm6640192pgh.31.2022.07.12.15.19.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Jul 2022 15:19:50 -0700 (PDT) From: Bart Van Assche To: "Martin K . Petersen" Cc: Jaegeuk Kim , linux-scsi@vger.kernel.org, Bart Van Assche , Christoph Hellwig , Ming Lei , Mike Christie , Hannes Reinecke , John Garry , Li Zhijian Subject: [PATCH v4 4/4] scsi: core: Call blk_mq_free_tag_set() earlier Date: Tue, 12 Jul 2022 15:19:36 -0700 Message-Id: <20220712221936.1199196-5-bvanassche@acm.org> X-Mailer: git-send-email 2.37.0.144.g8ac04bfd2-goog In-Reply-To: <20220712221936.1199196-1-bvanassche@acm.org> References: <20220712221936.1199196-1-bvanassche@acm.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org There are two .exit_cmd_priv implementations. Both implementations use resources associated with the SCSI host. Make sure that these resources are still available when .exit_cmd_priv is called by moving the .exit_cmd_priv calls from scsi_host_dev_release() to scsi_forget_host(). Moving blk_mq_free_tag_set() from scsi_host_dev_release() to scsi_forget_host() is safe because scsi_forget_host() waits until all SCSI devices associated with the host have been removed. This patch fixes the following use-after-free: ================================================================== BUG: KASAN: use-after-free in srp_exit_cmd_priv+0x27/0xd0 [ib_srp] Read of size 8 at addr ffff888100337000 by task multipathd/16727 Call Trace: dump_stack_lvl+0x34/0x44 print_report.cold+0x5e/0x5db kasan_report+0xab/0x120 srp_exit_cmd_priv+0x27/0xd0 [ib_srp] scsi_mq_exit_request+0x4d/0x70 blk_mq_free_rqs+0x143/0x410 __blk_mq_free_map_and_rqs+0x6e/0x100 blk_mq_free_tag_set+0x2b/0x160 scsi_host_dev_release+0xf3/0x1a0 device_release+0x54/0xe0 kobject_put+0xa5/0x120 device_release+0x54/0xe0 kobject_put+0xa5/0x120 scsi_device_dev_release_usercontext+0x4c1/0x4e0 execute_in_process_context+0x23/0x90 device_release+0x54/0xe0 kobject_put+0xa5/0x120 scsi_disk_release+0x3f/0x50 device_release+0x54/0xe0 kobject_put+0xa5/0x120 disk_release+0x17f/0x1b0 device_release+0x54/0xe0 kobject_put+0xa5/0x120 dm_put_table_device+0xa3/0x160 [dm_mod] dm_put_device+0xd0/0x140 [dm_mod] free_priority_group+0xd8/0x110 [dm_multipath] free_multipath+0x94/0xe0 [dm_multipath] dm_table_destroy+0xa2/0x1e0 [dm_mod] __dm_destroy+0x196/0x350 [dm_mod] dev_remove+0x10c/0x160 [dm_mod] ctl_ioctl+0x2c2/0x590 [dm_mod] dm_ctl_ioctl+0x5/0x10 [dm_mod] __x64_sys_ioctl+0xb4/0xf0 dm_ctl_ioctl+0x5/0x10 [dm_mod] __x64_sys_ioctl+0xb4/0xf0 do_syscall_64+0x3b/0x90 entry_SYSCALL_64_after_hwframe+0x46/0xb0 Cc: Christoph Hellwig Cc: Ming Lei Cc: Mike Christie Cc: Hannes Reinecke Cc: John Garry Cc: Li Zhijian Reported-by: Li Zhijian Tested-by: Li Zhijian Fixes: 65ca846a5314 ("scsi: core: Introduce {init,exit}_cmd_priv()") Signed-off-by: Bart Van Assche --- drivers/scsi/hosts.c | 10 +++++----- drivers/scsi/scsi_lib.c | 3 +++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 8fa98c8d0ee0..6c63672971f1 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -197,6 +197,8 @@ void scsi_remove_host(struct Scsi_Host *shost) * the dependent SCSI targets and devices are gone before returning. */ wait_event(shost->targets_wq, atomic_read(&shost->target_count) == 0); + + scsi_mq_destroy_tags(shost); } EXPORT_SYMBOL(scsi_remove_host); @@ -302,8 +304,8 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev, return error; /* - * Any host allocation in this function will be freed in - * scsi_host_dev_release(). + * Any resources associated with the SCSI host in this function except + * the tag set will be freed by scsi_host_dev_release(). */ out_del_dev: device_del(&shost->shost_dev); @@ -319,6 +321,7 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev, pm_runtime_disable(&shost->shost_gendev); pm_runtime_set_suspended(&shost->shost_gendev); pm_runtime_put_noidle(&shost->shost_gendev); + scsi_mq_destroy_tags(shost); fail: return error; } @@ -352,9 +355,6 @@ static void scsi_host_dev_release(struct device *dev) kfree(dev_name(&shost->shost_dev)); } - if (shost->tag_set.tags) - scsi_mq_destroy_tags(shost); - kfree(shost->shost_data); ida_free(&host_index_ida, shost->host_no); diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 2aca0a838ca5..295c48fdb650 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1990,7 +1990,10 @@ int scsi_mq_setup_tags(struct Scsi_Host *shost) void scsi_mq_destroy_tags(struct Scsi_Host *shost) { + if (!shost->tag_set.tags) + return; blk_mq_free_tag_set(&shost->tag_set); + WARN_ON_ONCE(shost->tag_set.tags); } /**