lkml.org 
[lkml]   [2018]   [Nov]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.14 025/100] sctp: clear the transport of some out_chunk_list chunks in sctp_assoc_rm_peer
    Date
    4.14-stable review patch.  If anyone has any objections, please let me know.

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

    From: Xin Long <lucien.xin@gmail.com>

    commit df132eff463873e14e019a07f387b4d577d6d1f9 upstream.

    If a transport is removed by asconf but there still are some chunks with
    this transport queuing on out_chunk_list, later an use-after-free issue
    will be caused when accessing this transport from these chunks in
    sctp_outq_flush().

    This is an old bug, we fix it by clearing the transport of these chunks
    in out_chunk_list when removing a transport in sctp_assoc_rm_peer().

    Reported-by: syzbot+56a40ceee5fb35932f4d@syzkaller.appspotmail.com
    Signed-off-by: Xin Long <lucien.xin@gmail.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    net/sctp/associola.c | 10 +++++++---
    1 file changed, 7 insertions(+), 3 deletions(-)

    --- a/net/sctp/associola.c
    +++ b/net/sctp/associola.c
    @@ -497,8 +497,9 @@ void sctp_assoc_set_primary(struct sctp_
    void sctp_assoc_rm_peer(struct sctp_association *asoc,
    struct sctp_transport *peer)
    {
    - struct list_head *pos;
    - struct sctp_transport *transport;
    + struct sctp_transport *transport;
    + struct list_head *pos;
    + struct sctp_chunk *ch;

    pr_debug("%s: association:%p addr:%pISpc\n",
    __func__, asoc, &peer->ipaddr.sa);
    @@ -562,7 +563,6 @@ void sctp_assoc_rm_peer(struct sctp_asso
    */
    if (!list_empty(&peer->transmitted)) {
    struct sctp_transport *active = asoc->peer.active_path;
    - struct sctp_chunk *ch;

    /* Reset the transport of each chunk on this list */
    list_for_each_entry(ch, &peer->transmitted,
    @@ -584,6 +584,10 @@ void sctp_assoc_rm_peer(struct sctp_asso
    sctp_transport_hold(active);
    }

    + list_for_each_entry(ch, &asoc->outqueue.out_chunk_list, list)
    + if (ch->transport == peer)
    + ch->transport = NULL;
    +
    asoc->peer.transport_count--;

    sctp_transport_free(peer);

    \
     
     \ /
      Last update: 2018-11-29 15:50    [W:6.287 / U:0.580 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site