]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/sctp/inqueue.c
SCTP: Validate buffer room when processing sequential chunks
[linux-2.6-omap-h63xx.git] / net / sctp / inqueue.c
index c30629e177814cc1313f7a710999ffdfe67b873c..e4ea7fdf36ed798c23d3b2dfb6e3f2a0e54e893b 100644 (file)
@@ -130,6 +130,14 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue)
                        /* Force chunk->skb->data to chunk->chunk_end.  */
                        skb_pull(chunk->skb,
                                 chunk->chunk_end - chunk->skb->data);
+
+                       /* Verify that we have at least chunk headers
+                        * worth of buffer left.
+                        */
+                       if (skb_headlen(chunk->skb) < sizeof(sctp_chunkhdr_t)) {
+                               sctp_chunk_free(chunk);
+                               chunk = queue->in_progress = NULL;
+                       }
                }
        }
 
@@ -159,16 +167,16 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue)
         * the skb->tail.
         */
        if (unlikely(skb_is_nonlinear(chunk->skb))) {
-               if (chunk->chunk_end > chunk->skb->tail)
-                       chunk->chunk_end = chunk->skb->tail;
+               if (chunk->chunk_end > skb_tail_pointer(chunk->skb))
+                       chunk->chunk_end = skb_tail_pointer(chunk->skb);
        }
        skb_pull(chunk->skb, sizeof(sctp_chunkhdr_t));
        chunk->subh.v = NULL; /* Subheader is no longer valid.  */
 
-       if (chunk->chunk_end < chunk->skb->tail) {
+       if (chunk->chunk_end < skb_tail_pointer(chunk->skb)) {
                /* This is not a singleton */
                chunk->singleton = 0;
-       } else if (chunk->chunk_end > chunk->skb->tail) {
+       } else if (chunk->chunk_end > skb_tail_pointer(chunk->skb)) {
                /* RFC 2960, Section 6.10  Bundling
                 *
                 * Partial chunks MUST NOT be placed in an SCTP packet.