sctp: verify length provided in heartbeat information parameter
authorThomas Graf <tgraf@suug.ch>
Fri, 30 Nov 2012 02:16:27 +0000 (02:16 +0000)
committerDavid S. Miller <davem@davemloft.net>
Fri, 30 Nov 2012 17:25:52 +0000 (12:25 -0500)
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>
net/sctp/sm_statefuns.c

index b6adef8a1e938d22b5cab026597e6f82c917794d..e92079d27eae8d2ff777963b8ca1baaf013de973 100644 (file)
@@ -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;