aboutsummaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorTsutomu Fujii <t-fujii@nb.jp.nec.com>2006-01-17 11:57:09 -0800
committerSridhar Samudrala <sri@us.ibm.com>2006-01-17 11:57:09 -0800
commita7d1f1b66c05ef4ebb58a34be7caad9af15546a4 (patch)
tree10395b7c00460c63576b06e7e252b9de60a2504a /net
parentc4d2444e992c4eda1d7fc3287e93ba58295bf6b9 (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.c13
-rw-r--r--net/sctp/sm_statefuns.c2
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;