lkml.org 
[lkml]   [2020]   [Oct]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.9 015/757] net/smc: fix use-after-free of delayed events
    Date
    From: Karsten Graul <kgraul@linux.ibm.com>

    [ Upstream commit d535ca1367787ddc8bff22d679a11f864c8228bc ]

    When a delayed event is enqueued then the event worker will send this
    event the next time it is running and no other flow is currently
    active. The event handler is called for the delayed event, and the
    pointer to the event keeps set in lgr->delayed_event. This pointer is
    cleared later in the processing by smc_llc_flow_start().
    This can lead to a use-after-free condition when the processing does not
    reach smc_llc_flow_start(), but frees the event because of an error
    situation. Then the delayed_event pointer is still set but the event is
    freed.
    Fix this by always clearing the delayed event pointer when the event is
    provided to the event handler for processing, and remove the code to
    clear it in smc_llc_flow_start().

    Fixes: 555da9af827d ("net/smc: add event-based llc_flow framework")
    Signed-off-by: Karsten Graul <kgraul@linux.ibm.com>
    Signed-off-by: Jakub Kicinski <kuba@kernel.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    net/smc/smc_llc.c | 13 +++++--------
    1 file changed, 5 insertions(+), 8 deletions(-)

    --- a/net/smc/smc_llc.c
    +++ b/net/smc/smc_llc.c
    @@ -233,8 +233,6 @@ static bool smc_llc_flow_start(struct sm
    default:
    flow->type = SMC_LLC_FLOW_NONE;
    }
    - if (qentry == lgr->delayed_event)
    - lgr->delayed_event = NULL;
    smc_llc_flow_qentry_set(flow, qentry);
    spin_unlock_bh(&lgr->llc_flow_lock);
    return true;
    @@ -1603,13 +1601,12 @@ static void smc_llc_event_work(struct wo
    struct smc_llc_qentry *qentry;

    if (!lgr->llc_flow_lcl.type && lgr->delayed_event) {
    - if (smc_link_usable(lgr->delayed_event->link)) {
    - smc_llc_event_handler(lgr->delayed_event);
    - } else {
    - qentry = lgr->delayed_event;
    - lgr->delayed_event = NULL;
    + qentry = lgr->delayed_event;
    + lgr->delayed_event = NULL;
    + if (smc_link_usable(qentry->link))
    + smc_llc_event_handler(qentry);
    + else
    kfree(qentry);
    - }
    }

    again:

    \
     
     \ /
      Last update: 2020-10-27 17:40    [W:2.949 / U:0.076 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site