sctp: validate chunk len before actually using it
[cascardo/linux.git] / net / sctp / sm_statefuns.c
index d88bb2b..8ec20a6 100644 (file)
@@ -3422,6 +3422,12 @@ sctp_disposition_t sctp_sf_ootb(struct net *net,
                        return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
                                                  commands);
 
+               /* Report violation if chunk len overflows */
+               ch_end = ((__u8 *)ch) + SCTP_PAD4(ntohs(ch->length));
+               if (ch_end > skb_tail_pointer(skb))
+                       return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
+                                                 commands);
+
                /* Now that we know we at least have a chunk header,
                 * do things that are type appropriate.
                 */
@@ -3453,12 +3459,6 @@ sctp_disposition_t sctp_sf_ootb(struct net *net,
                        }
                }
 
-               /* Report violation if chunk len overflows */
-               ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length));
-               if (ch_end > skb_tail_pointer(skb))
-                       return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
-                                                 commands);
-
                ch = (sctp_chunkhdr_t *) ch_end;
        } while (ch_end < skb_tail_pointer(skb));
 
@@ -4185,7 +4185,7 @@ sctp_disposition_t sctp_sf_unk_chunk(struct net *net,
                hdr = unk_chunk->chunk_hdr;
                err_chunk = sctp_make_op_error(asoc, unk_chunk,
                                               SCTP_ERROR_UNKNOWN_CHUNK, hdr,
-                                              WORD_ROUND(ntohs(hdr->length)),
+                                              SCTP_PAD4(ntohs(hdr->length)),
                                               0);
                if (err_chunk) {
                        sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
@@ -4203,7 +4203,7 @@ sctp_disposition_t sctp_sf_unk_chunk(struct net *net,
                hdr = unk_chunk->chunk_hdr;
                err_chunk = sctp_make_op_error(asoc, unk_chunk,
                                               SCTP_ERROR_UNKNOWN_CHUNK, hdr,
-                                              WORD_ROUND(ntohs(hdr->length)),
+                                              SCTP_PAD4(ntohs(hdr->length)),
                                               0);
                if (err_chunk) {
                        sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,