Skip to content

Commit 348bbc2

Browse files
committed
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>
1 parent 9e73317 commit 348bbc2

File tree

1 file changed

+12
-5
lines changed

1 file changed

+12
-5
lines changed

net/sctp/stream_interleave.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ static void sctp_intl_store_reasm(struct sctp_ulpq *ulpq,
140140
struct sctp_ulpevent *event)
141141
{
142142
struct sctp_ulpevent *cevent;
143-
struct sk_buff *pos;
143+
struct sk_buff *pos, *loc;
144144

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

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

172173
if (event->stream < cevent->stream ||
173174
(event->stream == cevent->stream &&
174-
MID_lt(event->mid, cevent->mid)))
175+
MID_lt(event->mid, cevent->mid))) {
176+
loc = pos;
175177
break;
176-
178+
}
177179
if (event->stream == cevent->stream &&
178180
event->mid == cevent->mid &&
179181
!(cevent->msg_flags & SCTP_DATA_FIRST_FRAG) &&
180182
(event->msg_flags & SCTP_DATA_FIRST_FRAG ||
181-
event->fsn < cevent->fsn))
183+
event->fsn < cevent->fsn)) {
184+
loc = pos;
182185
break;
186+
}
183187
}
184188

185-
__skb_queue_before(&ulpq->reasm, pos, sctp_event2skb(event));
189+
if (!loc)
190+
__skb_queue_tail(&ulpq->reasm, sctp_event2skb(event));
191+
else
192+
__skb_queue_before(&ulpq->reasm, loc, sctp_event2skb(event));
186193
}
187194

188195
static struct sctp_ulpevent *sctp_intl_retrieve_partial(

0 commit comments

Comments
 (0)