lkml.org 
[lkml]   [2015]   [Sep]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.1 25/78] libfc: Fix fc_exch_recv_req() error path
    Date
    4.1-stable review patch.  If anyone has any objections, please let me know.

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

    From: Bart Van Assche <bart.vanassche@sandisk.com>

    commit f6979adeaab578f8ca14fdd32b06ddee0d9d3314 upstream.

    Due to patch "libfc: Do not invoke the response handler after
    fc_exch_done()" (commit ID 7030fd62) the lport_recv() call
    in fc_exch_recv_req() is passed a dangling pointer. Avoid this
    by moving the fc_frame_free() call from fc_invoke_resp() to its
    callers. This patch fixes the following crash:

    general protection fault: 0000 [#3] PREEMPT SMP
    RIP: fc_lport_recv_req+0x72/0x280 [libfc]
    Call Trace:
    fc_exch_recv+0x642/0xde0 [libfc]
    fcoe_percpu_receive_thread+0x46a/0x5ed [fcoe]
    kthread+0x10a/0x120
    ret_from_fork+0x42/0x70

    Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
    Signed-off-by: Vasu Dev <vasu.dev@intel.com>
    Signed-off-by: James Bottomley <JBottomley@Odin.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/scsi/libfc/fc_exch.c | 8 ++++----
    1 file changed, 4 insertions(+), 4 deletions(-)

    --- a/drivers/scsi/libfc/fc_exch.c
    +++ b/drivers/scsi/libfc/fc_exch.c
    @@ -733,8 +733,6 @@ static bool fc_invoke_resp(struct fc_exc
    if (resp) {
    resp(sp, fp, arg);
    res = true;
    - } else if (!IS_ERR(fp)) {
    - fc_frame_free(fp);
    }

    spin_lock_bh(&ep->ex_lock);
    @@ -1596,7 +1594,8 @@ static void fc_exch_recv_seq_resp(struct
    * If new exch resp handler is valid then call that
    * first.
    */
    - fc_invoke_resp(ep, sp, fp);
    + if (!fc_invoke_resp(ep, sp, fp))
    + fc_frame_free(fp);

    fc_exch_release(ep);
    return;
    @@ -1695,7 +1694,8 @@ static void fc_exch_abts_resp(struct fc_
    fc_exch_hold(ep);
    if (!rc)
    fc_exch_delete(ep);
    - fc_invoke_resp(ep, sp, fp);
    + if (!fc_invoke_resp(ep, sp, fp))
    + fc_frame_free(fp);
    if (has_rec)
    fc_exch_timer_set(ep, ep->r_a_tov);
    fc_exch_release(ep);



    \
     
     \ /
      Last update: 2015-09-12 01:21    [W:2.678 / U:0.120 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site