Skip to content

Commit

Permalink
sctp: Fix SKB list traversal in sctp_intl_store_reasm().
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
David S. Miller committed Nov 11, 2018
1 parent 9e73317 commit 348bbc2
Showing 1 changed file with 12 additions and 5 deletions.
17 changes: 12 additions & 5 deletions net/sctp/stream_interleave.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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(
Expand Down

0 comments on commit 348bbc2

Please sign in to comment.