diff options
author | Tsutomu Fujii <t-fujii@nb.jp.nec.com> | 2006-01-17 11:57:09 -0800 |
---|---|---|
committer | Sridhar Samudrala <sri@us.ibm.com> | 2006-01-17 11:57:09 -0800 |
commit | a7d1f1b66c05ef4ebb58a34be7caad9af15546a4 (patch) | |
tree | 10395b7c00460c63576b06e7e252b9de60a2504a /net | |
parent | c4d2444e992c4eda1d7fc3287e93ba58295bf6b9 (diff) |
[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')
-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 71fd5637564..cb78b50868e 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 477d7f80dba..71c9a961c32 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; |