Skip to content

Commit

Permalink
sctp: shrink stream outq when fails to do addstream reconf
Browse files Browse the repository at this point in the history
[ Upstream commit 3ecdda3 ]

When adding a stream with stream reconf, the new stream firstly is in
CLOSED state but new out chunks can still be enqueued. Then once gets
the confirmation from the peer, the state will change to OPEN.

However, if the peer denies, it needs to roll back the stream. But when
doing that, it only sets the stream outcnt back, and the chunks already
in the new stream don't get purged. It caused these chunks can still be
dequeued in sctp_outq_dequeue_data().

As its stream is still in CLOSE, the chunk will be enqueued to the head
again by sctp_outq_head_data(). This chunk will never be sent out, and
the chunks after it can never be dequeued. The assoc will be 'hung' in
a dead loop of sending this chunk.

To fix it, this patch is to purge these chunks already in the new
stream by calling sctp_stream_shrink_out() when failing to do the
addstream reconf.

Fixes: 11ae76e ("sctp: implement receiver-side procedures for the Reconf Response Parameter")
Reported-by: Ying Xu <yinxu@redhat.com>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Xin Long authored and Greg Kroah-Hartman committed Jul 31, 2020
1 parent f2ee813 commit f971676
Showing 1 changed file with 4 additions and 2 deletions.
6 changes: 4 additions & 2 deletions net/sctp/stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -1143,11 +1143,13 @@ struct sctp_chunk *sctp_process_strreset_resp(
nums = ntohs(addstrm->number_of_streams);
number = stream->outcnt - nums;

if (result == SCTP_STRRESET_PERFORMED)
if (result == SCTP_STRRESET_PERFORMED) {
for (i = number; i < stream->outcnt; i++)
SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;
else
} else {
sctp_stream_shrink_out(stream, number);
stream->outcnt = number;
}

*evp = sctp_ulpevent_make_stream_change_event(asoc, flags,
0, nums, GFP_ATOMIC);
Expand Down

0 comments on commit f971676

Please sign in to comment.