sctp: Add check for the TSN field of the SHUTDOWN chunk

If SHUTDOWN chunk is received Cumulative TSN Ack beyond the max tsn currently
send, SHUTDOWN chunk be accepted and the association will be broken. New data
is send, but after received SACK it will be drop because TSN in SACK is less
than the Cumulative TSN, data will be retrans again and again even if correct
SACK is received.

The packet sequence is like this:

Endpoint A Endpoint B ULP
(ESTABLISHED) (ESTABLISHED)

<----------- DATA (TSN=x-1)

<----------- DATA (TSN=x)

SHUTDOWN -----------> (Now Cumulative TSN=x+1000)
(TSN=x+1000)
<----------- DATA (TSN=x+1)

SACK -----------> drop the SACK
(TSN=x+1)
<----------- DATA (TSN=x+1)(retrans)

This patch fix this problem by terminating the association and respond to
the sender with an ABORT.

Signed-off-by: Wei Yongjun <yjwei@cn.fujitsu.com>
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by Wei Yongjun and committed by David S. Miller df10eec4 91bd6b1e

+9
+9
net/sctp/sm_statefuns.c
··· 2544 sctp_shutdownhdr_t *sdh; 2545 sctp_disposition_t disposition; 2546 struct sctp_ulpevent *ev; 2547 2548 if (!sctp_vtag_verify(chunk, asoc)) 2549 return sctp_sf_pdiscard(ep, asoc, type, arg, commands); ··· 2559 sdh = (sctp_shutdownhdr_t *)chunk->skb->data; 2560 skb_pull(chunk->skb, sizeof(sctp_shutdownhdr_t)); 2561 chunk->subh.shutdown_hdr = sdh; 2562 2563 /* API 5.3.1.5 SCTP_SHUTDOWN_EVENT 2564 * When a peer sends a SHUTDOWN, SCTP delivers this notification to
··· 2544 sctp_shutdownhdr_t *sdh; 2545 sctp_disposition_t disposition; 2546 struct sctp_ulpevent *ev; 2547 + __u32 ctsn; 2548 2549 if (!sctp_vtag_verify(chunk, asoc)) 2550 return sctp_sf_pdiscard(ep, asoc, type, arg, commands); ··· 2558 sdh = (sctp_shutdownhdr_t *)chunk->skb->data; 2559 skb_pull(chunk->skb, sizeof(sctp_shutdownhdr_t)); 2560 chunk->subh.shutdown_hdr = sdh; 2561 + ctsn = ntohl(sdh->cum_tsn_ack); 2562 + 2563 + /* If Cumulative TSN Ack beyond the max tsn currently 2564 + * send, terminating the association and respond to the 2565 + * sender with an ABORT. 2566 + */ 2567 + if (!TSN_lt(ctsn, asoc->next_tsn)) 2568 + return sctp_sf_violation_ctsn(ep, asoc, type, arg, commands); 2569 2570 /* API 5.3.1.5 SCTP_SHUTDOWN_EVENT 2571 * When a peer sends a SHUTDOWN, SCTP delivers this notification to