Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 348bbc25 authored by David S. Miller's avatar David S. Miller
Browse files

sctp: Fix SKB list traversal in sctp_intl_store_reasm().



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: default avatarDavid S. Miller <davem@davemloft.net>
parent 9e733177
Loading
Loading
Loading
Loading
+12 −5
Original line number Diff line number Diff line
@@ -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(