diff options
author | Tsutomu Fujii <t-fujii@nb.jp.nec.com> | 2006-01-17 20:57:09 +0100 |
---|---|---|
committer | Sridhar Samudrala <sri@us.ibm.com> | 2006-01-17 20:57:09 +0100 |
commit | a7d1f1b66c05ef4ebb58a34be7caad9af15546a4 (patch) | |
tree | 10395b7c00460c63576b06e7e252b9de60a2504a /net/sctp | |
parent | [SCTP]: Fix couple of races between sctp_peeloff() and sctp_rcv(). (diff) | |
download | linux-a7d1f1b66c05ef4ebb58a34be7caad9af15546a4.tar.xz linux-a7d1f1b66c05ef4ebb58a34be7caad9af15546a4.zip |
[SCTP]: Fix sctp_rcv_ootb() to handle the last chunk of a packet correctly.
Signed-off-by: Tsutomu Fujii <t-fujii@nb.jp.nec.com>
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
Diffstat (limited to 'net/sctp')
-rw-r--r-- | net/sctp/input.c | 13 | ||||
-rw-r--r-- | net/sctp/sm_statefuns.c | 2 |
2 files changed, 11 insertions, 4 deletions
diff --git a/net/sctp/input.c b/net/sctp/input.c index 71fd56375641..cb78b50868ee 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c @@ -588,10 +588,16 @@ int sctp_rcv_ootb(struct sk_buff *skb) sctp_errhdr_t *err; ch = (sctp_chunkhdr_t *) skb->data; - ch_end = ((__u8 *) ch) + WORD_ROUND(ntohs(ch->length)); /* Scan through all the chunks in the packet. */ - while (ch_end > (__u8 *)ch && ch_end < skb->tail) { + do { + /* Break out if chunk length is less then minimal. */ + if (ntohs(ch->length) < sizeof(sctp_chunkhdr_t)) + break; + + ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length)); + if (ch_end > skb->tail) + break; /* RFC 8.4, 2) If the OOTB packet contains an ABORT chunk, the * receiver MUST silently discard the OOTB packet and take no @@ -622,8 +628,7 @@ int sctp_rcv_ootb(struct sk_buff *skb) } ch = (sctp_chunkhdr_t *) ch_end; - ch_end = ((__u8 *) ch) + WORD_ROUND(ntohs(ch->length)); - } + } while (ch_end < skb->tail); return 0; diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 477d7f80dba6..71c9a961c321 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c @@ -3090,6 +3090,8 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep, break; ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length)); + if (ch_end > skb->tail) + break; if (SCTP_CID_SHUTDOWN_ACK == ch->type) ootb_shut_ack = 1; |