]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
scsi: core: Fix race on creating sense cache
authorMing Lei <ming.lei@redhat.com>
Fri, 12 Jul 2019 02:08:19 +0000 (10:08 +0800)
committerKleber Sacilotto de Souza <kleber.souza@canonical.com>
Wed, 14 Aug 2019 09:18:49 +0000 (11:18 +0200)
BugLink: https://bugs.launchpad.net/bugs/1839036
commit f9b0530fa02e0c73f31a49ef743e8f44eb8e32cc upstream.

When scsi_init_sense_cache(host) is called concurrently from different
hosts, each code path may find that no cache has been created and
allocate a new one. The lack of locking can lead to potentially
overriding a cache allocated by a different host.

Fix the issue by moving 'mutex_lock(&scsi_sense_cache_mutex)' before
scsi_select_sense_cache().

Fixes: 0a6ac4ee7c21 ("scsi: respect unchecked_isa_dma for blk-mq")
Cc: Stable <stable@vger.kernel.org>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Hannes Reinecke <hare@suse.com>
Cc: Ewan D. Milne <emilne@redhat.com>
Signed-off-by: Ming Lei <ming.lei@redhat.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
Signed-off-by: Khalid Elmously <khalid.elmously@canonical.com>
drivers/scsi/scsi_lib.c

index a8f175e0d78dcf5d5b8b8738680ea35e2144c447..92b82c52c27bc81a15491968c7d7ee4a56e3065d 100644 (file)
@@ -71,11 +71,11 @@ int scsi_init_sense_cache(struct Scsi_Host *shost)
        struct kmem_cache *cache;
        int ret = 0;
 
+       mutex_lock(&scsi_sense_cache_mutex);
        cache = scsi_select_sense_cache(shost->unchecked_isa_dma);
        if (cache)
-               return 0;
+               goto exit;
 
-       mutex_lock(&scsi_sense_cache_mutex);
        if (shost->unchecked_isa_dma) {
                scsi_sense_isadma_cache =
                        kmem_cache_create("scsi_sense_cache(DMA)",
@@ -90,7 +90,7 @@ int scsi_init_sense_cache(struct Scsi_Host *shost)
                if (!scsi_sense_cache)
                        ret = -ENOMEM;
        }
-
+ exit:
        mutex_unlock(&scsi_sense_cache_mutex);
        return ret;
 }