lkml.org 
[lkml]   [2019]   [Jan]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 16/99] scsi: target: iscsi: cxgbit: fix csk leak
    Date
    4.19-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    [ Upstream commit 801df68d617e3cb831f531c99fa6003620e6b343 ]

    csk leak can happen if a new TCP connection gets established after
    cxgbit_accept_np() returns, to fix this leak free remaining csk in
    cxgbit_free_np().

    Signed-off-by: Varun Prakash <varun@chelsio.com>
    Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/target/iscsi/cxgbit/cxgbit_cm.c | 23 ++++++++++++++++++++---
    1 file changed, 20 insertions(+), 3 deletions(-)

    diff --git a/drivers/target/iscsi/cxgbit/cxgbit_cm.c b/drivers/target/iscsi/cxgbit/cxgbit_cm.c
    index 8de16016b6de..71888b979ab5 100644
    --- a/drivers/target/iscsi/cxgbit/cxgbit_cm.c
    +++ b/drivers/target/iscsi/cxgbit/cxgbit_cm.c
    @@ -598,9 +598,12 @@ static void cxgbit_free_cdev_np(struct cxgbit_np *cnp)
    mutex_unlock(&cdev_list_lock);
    }

    +static void __cxgbit_free_conn(struct cxgbit_sock *csk);
    +
    void cxgbit_free_np(struct iscsi_np *np)
    {
    struct cxgbit_np *cnp = np->np_context;
    + struct cxgbit_sock *csk, *tmp;

    cnp->com.state = CSK_STATE_DEAD;
    if (cnp->com.cdev)
    @@ -608,6 +611,13 @@ void cxgbit_free_np(struct iscsi_np *np)
    else
    cxgbit_free_all_np(cnp);

    + spin_lock_bh(&cnp->np_accept_lock);
    + list_for_each_entry_safe(csk, tmp, &cnp->np_accept_list, accept_node) {
    + list_del_init(&csk->accept_node);
    + __cxgbit_free_conn(csk);
    + }
    + spin_unlock_bh(&cnp->np_accept_lock);
    +
    np->np_context = NULL;
    cxgbit_put_cnp(cnp);
    }
    @@ -705,9 +715,9 @@ void cxgbit_abort_conn(struct cxgbit_sock *csk)
    csk->tid, 600, __func__);
    }

    -void cxgbit_free_conn(struct iscsi_conn *conn)
    +static void __cxgbit_free_conn(struct cxgbit_sock *csk)
    {
    - struct cxgbit_sock *csk = conn->context;
    + struct iscsi_conn *conn = csk->conn;
    bool release = false;

    pr_debug("%s: state %d\n",
    @@ -716,7 +726,7 @@ void cxgbit_free_conn(struct iscsi_conn *conn)
    spin_lock_bh(&csk->lock);
    switch (csk->com.state) {
    case CSK_STATE_ESTABLISHED:
    - if (conn->conn_state == TARG_CONN_STATE_IN_LOGOUT) {
    + if (conn && (conn->conn_state == TARG_CONN_STATE_IN_LOGOUT)) {
    csk->com.state = CSK_STATE_CLOSING;
    cxgbit_send_halfclose(csk);
    } else {
    @@ -741,6 +751,11 @@ void cxgbit_free_conn(struct iscsi_conn *conn)
    cxgbit_put_csk(csk);
    }

    +void cxgbit_free_conn(struct iscsi_conn *conn)
    +{
    + __cxgbit_free_conn(conn->context);
    +}
    +
    static void cxgbit_set_emss(struct cxgbit_sock *csk, u16 opt)
    {
    csk->emss = csk->com.cdev->lldi.mtus[TCPOPT_MSS_G(opt)] -
    @@ -803,6 +818,7 @@ void _cxgbit_free_csk(struct kref *kref)
    spin_unlock_bh(&cdev->cskq.lock);

    cxgbit_free_skb(csk);
    + cxgbit_put_cnp(csk->cnp);
    cxgbit_put_cdev(cdev);

    kfree(csk);
    @@ -1351,6 +1367,7 @@ cxgbit_pass_accept_req(struct cxgbit_device *cdev, struct sk_buff *skb)
    goto rel_skb;
    }

    + cxgbit_get_cnp(cnp);
    cxgbit_get_cdev(cdev);

    spin_lock(&cdev->cskq.lock);
    --
    2.19.1


    \
     
     \ /
      Last update: 2019-01-21 15:08    [W:4.026 / U:0.560 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site