aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/sm_statefuns.c
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2012-11-29 21:16:27 -0500
committerDavid S. Miller <davem@davemloft.net>2012-11-30 12:25:52 -0500
commit06a31e2b918dd992dd104e082ec8a33d6235c7b3 (patch)
tree42973ed278206d0342f35001dd78f0fa09390f8a /net/sctp/sm_statefuns.c
parentc07135633bee3f01a6454d15b6411f32cfbeb2fd (diff)
sctp: verify length provided in heartbeat information parameter
If the variable parameter length provided in the mandatory heartbeat information parameter exceeds the calculated payload length the packet has been corrupted. Reply with a parameter length protocol violation message. Signed-off-by: Thomas Graf <tgraf@suug.ch> Acked-by: Neil Horman <nhorman@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/sm_statefuns.c')
-rw-r--r--net/sctp/sm_statefuns.c10
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