summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2012-11-30 06:16:27 +0400
committerDavid S. Miller <davem@davemloft.net>2012-11-30 21:25:52 +0400
commit06a31e2b918dd992dd104e082ec8a33d6235c7b3 (patch)
tree42973ed278206d0342f35001dd78f0fa09390f8a /net
parentc07135633bee3f01a6454d15b6411f32cfbeb2fd (diff)
downloadlinux-06a31e2b918dd992dd104e082ec8a33d6235c7b3.tar.xz
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')
-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,
void *arg,
sctp_cmd_seq_t *commands)
{
+ sctp_paramhdr_t *param_hdr;
struct sctp_chunk *chunk = arg;
struct sctp_chunk *reply;
size_t paylen = 0;
@@ -1072,12 +1073,17 @@ sctp_disposition_t sctp_sf_beat_8_3(struct net *net,
* Information field copied from the received HEARTBEAT chunk.
*/
chunk->subh.hb_hdr = (sctp_heartbeathdr_t *) chunk->skb->data;
+ param_hdr = (sctp_paramhdr_t *) chunk->subh.hb_hdr;
paylen = ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t);
+
+ if (ntohs(param_hdr->length) > paylen)
+ return sctp_sf_violation_paramlen(net, ep, asoc, type, arg,
+ param_hdr, commands);
+
if (!pskb_pull(chunk->skb, paylen))
goto nomem;
- reply = sctp_make_heartbeat_ack(asoc, chunk,
- chunk->subh.hb_hdr, paylen);
+ reply = sctp_make_heartbeat_ack(asoc, chunk, param_hdr, paylen);
if (!reply)
goto nomem;