diff options
-rw-r--r-- | net/sctp/sm_statefuns.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index b6adef8a1e93..e92079d27eae 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -1055,6 +1055,7 @@ sctp_disposition_t sctp_sf_beat_8_3(struct net *net, | |||
1055 | void *arg, | 1055 | void *arg, |
1056 | sctp_cmd_seq_t *commands) | 1056 | sctp_cmd_seq_t *commands) |
1057 | { | 1057 | { |
1058 | sctp_paramhdr_t *param_hdr; | ||
1058 | struct sctp_chunk *chunk = arg; | 1059 | struct sctp_chunk *chunk = arg; |
1059 | struct sctp_chunk *reply; | 1060 | struct sctp_chunk *reply; |
1060 | size_t paylen = 0; | 1061 | size_t paylen = 0; |
@@ -1072,12 +1073,17 @@ sctp_disposition_t sctp_sf_beat_8_3(struct net *net, | |||
1072 | * Information field copied from the received HEARTBEAT chunk. | 1073 | * Information field copied from the received HEARTBEAT chunk. |
1073 | */ | 1074 | */ |
1074 | chunk->subh.hb_hdr = (sctp_heartbeathdr_t *) chunk->skb->data; | 1075 | chunk->subh.hb_hdr = (sctp_heartbeathdr_t *) chunk->skb->data; |
1076 | param_hdr = (sctp_paramhdr_t *) chunk->subh.hb_hdr; | ||
1075 | paylen = ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t); | 1077 | paylen = ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t); |
1078 | |||
1079 | if (ntohs(param_hdr->length) > paylen) | ||
1080 | return sctp_sf_violation_paramlen(net, ep, asoc, type, arg, | ||
1081 | param_hdr, commands); | ||
1082 | |||
1076 | if (!pskb_pull(chunk->skb, paylen)) | 1083 | if (!pskb_pull(chunk->skb, paylen)) |
1077 | goto nomem; | 1084 | goto nomem; |
1078 | 1085 | ||
1079 | reply = sctp_make_heartbeat_ack(asoc, chunk, | 1086 | reply = sctp_make_heartbeat_ack(asoc, chunk, param_hdr, paylen); |
1080 | chunk->subh.hb_hdr, paylen); | ||
1081 | if (!reply) | 1087 | if (!reply) |
1082 | goto nomem; | 1088 | goto nomem; |
1083 | 1089 | ||