lkml.org 
[lkml]   [2020]   [Aug]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 5.7 32/61] scsi: target: Fix xcopy sess release leak
    Date
    From: Mike Christie <michael.christie@oracle.com>

    [ 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>
    ---
    drivers/target/target_core_internal.h | 1 +
    drivers/target/target_core_transport.c | 7 ++++++-
    drivers/target/target_core_xcopy.c | 11 +++++++++--
    3 files changed, 16 insertions(+), 3 deletions(-)

    diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h
    index 8533444159635..e7b3c6e5d5744 100644
    --- a/drivers/target/target_core_internal.h
    +++ b/drivers/target/target_core_internal.h
    @@ -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 *,
    diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
    index 264a822c0bfac..989d5e5924816 100644
    --- a/drivers/target/target_core_transport.c
    +++ b/drivers/target/target_core_transport.c
    @@ -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);
    diff --git a/drivers/target/target_core_xcopy.c b/drivers/target/target_core_xcopy.c
    index bd3ed6ce75719..4a01d7c195da7 100644
    --- a/drivers/target/target_core_xcopy.c
    +++ b/drivers/target/target_core_xcopy.c
    @@ -474,7 +474,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;
    @@ -483,12 +483,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);
    + }
    }

    /*
    --
    2.25.1
    \
     
     \ /
      Last update: 2020-08-21 19:20    [W:5.792 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site