]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/commitdiff
scsi: target: Fix xcopy sess release leak
authorMike Christie <michael.christie@oracle.com>
Thu, 2 Jul 2020 01:43:18 +0000 (20:43 -0500)
committerKhalid Elmously <khalid.elmously@canonical.com>
Wed, 16 Sep 2020 09:15:01 +0000 (05:15 -0400)
BugLink: https://bugs.launchpad.net/bugs/1895174
[ Upstream commit 3c006c7d23aac928279f7cbe83bbac4361255d53 ]

transport_init_session can allocate memory via percpu_ref_init, and
target_xcopy_release_pt never frees it. This adds a
transport_uninit_session function to handle cleanup of resources allocated
in the init function.

Link: https://lore.kernel.org/r/1593654203-12442-3-git-send-email-michael.christie@oracle.com
Signed-off-by: Mike Christie <michael.christie@oracle.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
Signed-off-by: Khalid Elmously <khalid.elmously@canonical.com>
drivers/target/target_core_internal.h
drivers/target/target_core_transport.c
drivers/target/target_core_xcopy.c

index 853344415963579ccfa116d961c5a8a2fcd63a56..e7b3c6e5d5744ca75cff1d17ac000f2e2125213d 100644 (file)
@@ -138,6 +138,7 @@ int init_se_kmem_caches(void);
 void   release_se_kmem_caches(void);
 u32    scsi_get_new_index(scsi_index_t);
 void   transport_subsystem_check_init(void);
+void   transport_uninit_session(struct se_session *);
 unsigned char *transport_dump_cmd_direction(struct se_cmd *);
 void   transport_dump_dev_state(struct se_device *, char *, int *);
 void   transport_dump_dev_info(struct se_device *, struct se_lun *,
index 7c78a5d02c0832f52d20d919e6450851be5a3a66..b1f4be055f838f0bcc59aaec7a66ee01e6009731 100644 (file)
@@ -236,6 +236,11 @@ int transport_init_session(struct se_session *se_sess)
 }
 EXPORT_SYMBOL(transport_init_session);
 
+void transport_uninit_session(struct se_session *se_sess)
+{
+       percpu_ref_exit(&se_sess->cmd_count);
+}
+
 /**
  * transport_alloc_session - allocate a session object and initialize it
  * @sup_prot_ops: bitmask that defines which T10-PI modes are supported.
@@ -579,7 +584,7 @@ void transport_free_session(struct se_session *se_sess)
                sbitmap_queue_free(&se_sess->sess_tag_pool);
                kvfree(se_sess->sess_cmd_map);
        }
-       percpu_ref_exit(&se_sess->cmd_count);
+       transport_uninit_session(se_sess);
        kmem_cache_free(se_sess_cache, se_sess);
 }
 EXPORT_SYMBOL(transport_free_session);
index b9b1e92c6f8dbdbd0fa5524d10004a18c48e9a22..9d24e85b086316a021b14f98b77e221b204fcb06 100644 (file)
@@ -479,7 +479,7 @@ int target_xcopy_setup_pt(void)
        memset(&xcopy_pt_sess, 0, sizeof(struct se_session));
        ret = transport_init_session(&xcopy_pt_sess);
        if (ret < 0)
-               return ret;
+               goto destroy_wq;
 
        xcopy_pt_nacl.se_tpg = &xcopy_pt_tpg;
        xcopy_pt_nacl.nacl_sess = &xcopy_pt_sess;
@@ -488,12 +488,19 @@ int target_xcopy_setup_pt(void)
        xcopy_pt_sess.se_node_acl = &xcopy_pt_nacl;
 
        return 0;
+
+destroy_wq:
+       destroy_workqueue(xcopy_wq);
+       xcopy_wq = NULL;
+       return ret;
 }
 
 void target_xcopy_release_pt(void)
 {
-       if (xcopy_wq)
+       if (xcopy_wq) {
                destroy_workqueue(xcopy_wq);
+               transport_uninit_session(&xcopy_pt_sess);
+       }
 }
 
 /*