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: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
9e733177c7
commit
348bbc25c4
|
@ -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(
|
||||
|
|
Loading…
Reference in New Issue