]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 23 Jul 2024 13:33:05 +0000 (15:33 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 23 Jul 2024 13:33:05 +0000 (15:33 +0200)
added patches:
scsi-core-fix-a-use-after-free.patch

queue-5.15/scsi-core-fix-a-use-after-free.patch [new file with mode: 0644]
queue-5.15/series

diff --git a/queue-5.15/scsi-core-fix-a-use-after-free.patch b/queue-5.15/scsi-core-fix-a-use-after-free.patch
new file mode 100644 (file)
index 0000000..78f86d5
--- /dev/null
@@ -0,0 +1,190 @@
+From 8fe4ce5836e932f5766317cb651c1ff2a4cd0506 Mon Sep 17 00:00:00 2001
+From: Bart Van Assche <bvanassche@acm.org>
+Date: Thu, 25 Aug 2022 17:26:34 -0700
+Subject: scsi: core: Fix a use-after-free
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+commit 8fe4ce5836e932f5766317cb651c1ff2a4cd0506 upstream.
+
+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 waiting inside
+scsi_remove_host() until the tag set has been freed.
+
+This commit 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:
+ <TASK>
+ 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
+
+Link: https://lore.kernel.org/r/20220826002635.919423-1-bvanassche@acm.org
+Fixes: 65ca846a5314 ("scsi: core: Introduce {init,exit}_cmd_priv()")
+Cc: Ming Lei <ming.lei@redhat.com>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Mike Christie <michael.christie@oracle.com>
+Cc: Hannes Reinecke <hare@suse.de>
+Cc: John Garry <john.garry@huawei.com>
+Cc: Li Zhijian <lizhijian@fujitsu.com>
+Reported-by: Li Zhijian <lizhijian@fujitsu.com>
+Tested-by: Li Zhijian <lizhijian@fujitsu.com>
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+[mheyne: fixed contextual conflicts:
+  - drivers/scsi/hosts.c: due to missing commit 973dac8a8a14 ("scsi: core: Refine how we set tag_set NUMA node")
+  - drivers/scsi/scsi_sysfs.c: due to missing commit 6f8191fdf41d ("block: simplify disk shutdown")]
+Signed-off-by: Maximilian Heyne <mheyne@amazon.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/scsi/hosts.c      |   16 +++++++++++++---
+ drivers/scsi/scsi_lib.c   |    6 +++++-
+ drivers/scsi/scsi_priv.h  |    2 +-
+ drivers/scsi/scsi_scan.c  |    1 +
+ drivers/scsi/scsi_sysfs.c |    1 +
+ include/scsi/scsi_host.h  |    2 ++
+ 6 files changed, 23 insertions(+), 5 deletions(-)
+
+--- a/drivers/scsi/hosts.c
++++ b/drivers/scsi/hosts.c
+@@ -182,6 +182,15 @@ void scsi_remove_host(struct Scsi_Host *
+       scsi_proc_host_rm(shost);
+       scsi_proc_hostdir_rm(shost->hostt);
++      /*
++       * New SCSI devices cannot be attached anymore because of the SCSI host
++       * state so drop the tag set refcnt. Wait until the tag set refcnt drops
++       * to zero because .exit_cmd_priv implementations may need the host
++       * pointer.
++       */
++      kref_put(&shost->tagset_refcnt, scsi_mq_free_tags);
++      wait_for_completion(&shost->tagset_freed);
++
+       spin_lock_irqsave(shost->host_lock, flags);
+       if (scsi_host_set_state(shost, SHOST_DEL))
+               BUG_ON(scsi_host_set_state(shost, SHOST_DEL_RECOVERY));
+@@ -240,6 +249,9 @@ int scsi_add_host_with_dma(struct Scsi_H
+       shost->dma_dev = dma_dev;
++      kref_init(&shost->tagset_refcnt);
++      init_completion(&shost->tagset_freed);
++
+       /*
+        * Increase usage count temporarily here so that calling
+        * scsi_autopm_put_host() will trigger runtime idle if there is
+@@ -312,6 +324,7 @@ int scsi_add_host_with_dma(struct Scsi_H
+       pm_runtime_disable(&shost->shost_gendev);
+       pm_runtime_set_suspended(&shost->shost_gendev);
+       pm_runtime_put_noidle(&shost->shost_gendev);
++      kref_put(&shost->tagset_refcnt, scsi_mq_free_tags);
+  fail:
+       return error;
+ }
+@@ -344,9 +357,6 @@ static void scsi_host_dev_release(struct
+               kfree(dev_name(&shost->shost_dev));
+       }
+-      if (shost->tag_set.tags)
+-              scsi_mq_destroy_tags(shost);
+-
+       kfree(shost->shost_data);
+       ida_simple_remove(&host_index_ida, shost->host_no);
+--- a/drivers/scsi/scsi_lib.c
++++ b/drivers/scsi/scsi_lib.c
+@@ -1949,9 +1949,13 @@ int scsi_mq_setup_tags(struct Scsi_Host
+       return blk_mq_alloc_tag_set(tag_set);
+ }
+-void scsi_mq_destroy_tags(struct Scsi_Host *shost)
++void scsi_mq_free_tags(struct kref *kref)
+ {
++      struct Scsi_Host *shost = container_of(kref, typeof(*shost),
++                                             tagset_refcnt);
++
+       blk_mq_free_tag_set(&shost->tag_set);
++      complete(&shost->tagset_freed);
+ }
+ /**
+--- a/drivers/scsi/scsi_priv.h
++++ b/drivers/scsi/scsi_priv.h
+@@ -95,7 +95,7 @@ extern void scsi_run_host_queues(struct
+ extern void scsi_requeue_run_queue(struct work_struct *work);
+ extern void scsi_start_queue(struct scsi_device *sdev);
+ extern int scsi_mq_setup_tags(struct Scsi_Host *shost);
+-extern void scsi_mq_destroy_tags(struct Scsi_Host *shost);
++extern void scsi_mq_free_tags(struct kref *kref);
+ extern void scsi_exit_queue(void);
+ extern void scsi_evt_thread(struct work_struct *work);
+--- a/drivers/scsi/scsi_scan.c
++++ b/drivers/scsi/scsi_scan.c
+@@ -324,6 +324,7 @@ static struct scsi_device *scsi_alloc_sd
+               kfree(sdev);
+               goto out;
+       }
++      kref_get(&sdev->host->tagset_refcnt);
+       sdev->request_queue = q;
+       q->queuedata = sdev;
+       __scsi_init_queue(sdev->host, q);
+--- a/drivers/scsi/scsi_sysfs.c
++++ b/drivers/scsi/scsi_sysfs.c
+@@ -1490,6 +1490,7 @@ void __scsi_remove_device(struct scsi_de
+       mutex_unlock(&sdev->state_mutex);
+       blk_cleanup_queue(sdev->request_queue);
++      kref_put(&sdev->host->tagset_refcnt, scsi_mq_free_tags);
+       cancel_work_sync(&sdev->requeue_work);
+       if (sdev->host->hostt->slave_destroy)
+--- a/include/scsi/scsi_host.h
++++ b/include/scsi/scsi_host.h
+@@ -565,6 +565,8 @@ struct Scsi_Host {
+       struct scsi_host_template *hostt;
+       struct scsi_transport_template *transportt;
++      struct kref             tagset_refcnt;
++      struct completion       tagset_freed;
+       /* Area to keep a shared tag map */
+       struct blk_mq_tag_set   tag_set;
index 324a13706ee659970f32e494285b8ac6532e7e01..80c2e65e8372abde4c348491245d5f71f4c101f7 100644 (file)
@@ -3,6 +3,7 @@ filelock-remove-locks-reliably-when-fcntl-close-race-is-detected.patch
 arm-9324-1-fix-get_user-broken-with-veneer.patch
 acpi-processor_idle-fix-invalid-comparison-with-insertion-sort-for-latency.patch
 bpf-fix-overrunning-reservations-in-ringbuf.patch
+scsi-core-fix-a-use-after-free.patch
 scsi-core-alua-i-o-errors-for-alua-state-transitions.patch
 scsi-qedf-don-t-process-stag-work-during-unload-and-.patch
 scsi-qedf-wait-for-stag-work-during-unload.patch