lkml.org 
[lkml]   [2019]   [Jan]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 4.20 040/304] sctp: Fix SKB list traversal in sctp_intl_store_reasm().
    Date
    From: "David S. Miller" <davem@davemloft.net>

    [ Upstream commit 348bbc25c40844c5efa083a3842c7f53d70a815e ]

    To be fully correct, an iterator has an undefined value when something
    like skb_queue_walk() naturally terminates.

    This will actually matter when SKB queues are converted over to
    list_head.

    Formalize what this code ends up doing with the current
    implementation.

    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    net/sctp/stream_interleave.c | 17 ++++++++++++-----
    1 file changed, 12 insertions(+), 5 deletions(-)

    diff --git a/net/sctp/stream_interleave.c b/net/sctp/stream_interleave.c
    index 500449b72eca..2b499a85db0e 100644
    --- a/net/sctp/stream_interleave.c
    +++ b/net/sctp/stream_interleave.c
    @@ -140,7 +140,7 @@ static void sctp_intl_store_reasm(struct sctp_ulpq *ulpq,
    struct sctp_ulpevent *event)
    {
    struct sctp_ulpevent *cevent;
    - struct sk_buff *pos;
    + struct sk_buff *pos, *loc;

    pos = skb_peek_tail(&ulpq->reasm);
    if (!pos) {
    @@ -166,23 +166,30 @@ static void sctp_intl_store_reasm(struct sctp_ulpq *ulpq,
    return;
    }

    + loc = NULL;
    skb_queue_walk(&ulpq->reasm, pos) {
    cevent = sctp_skb2event(pos);

    if (event->stream < cevent->stream ||
    (event->stream == cevent->stream &&
    - MID_lt(event->mid, cevent->mid)))
    + MID_lt(event->mid, cevent->mid))) {
    + loc = pos;
    break;
    -
    + }
    if (event->stream == cevent->stream &&
    event->mid == cevent->mid &&
    !(cevent->msg_flags & SCTP_DATA_FIRST_FRAG) &&
    (event->msg_flags & SCTP_DATA_FIRST_FRAG ||
    - event->fsn < cevent->fsn))
    + event->fsn < cevent->fsn)) {
    + loc = pos;
    break;
    + }
    }

    - __skb_queue_before(&ulpq->reasm, pos, sctp_event2skb(event));
    + if (!loc)
    + __skb_queue_tail(&ulpq->reasm, sctp_event2skb(event));
    + else
    + __skb_queue_before(&ulpq->reasm, loc, sctp_event2skb(event));
    }

    static struct sctp_ulpevent *sctp_intl_retrieve_partial(
    --
    2.19.1
    \
     
     \ /
      Last update: 2019-01-28 16:45    [W:4.133 / U:0.096 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site