queue->malloced = 0;
}
-/* Create an initialized sctp_inq. */
-struct sctp_inq *sctp_inq_new(void)
-{
- struct sctp_inq *retval;
-
- retval = t_new(struct sctp_inq, GFP_ATOMIC);
- if (retval) {
- sctp_inq_init(retval);
- retval->malloced = 1;
- }
- return retval;
-}
-
/* Release the memory associated with an SCTP inqueue. */
void sctp_inq_free(struct sctp_inq *queue)
{
}
chunk->chunk_hdr = ch;
- chunk->chunk_end = ((__u8 *) ch)
- + WORD_ROUND(ntohs(ch->length));
+ chunk->chunk_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length));
+ /* In the unlikely case of an IP reassembly, the skb could be
+ * non-linear. If so, update chunk_end so that it doesn't go past
+ * the skb->tail.
+ */
+ if (unlikely(skb_is_nonlinear(chunk->skb))) {
+ if (chunk->chunk_end > chunk->skb->tail)
+ chunk->chunk_end = chunk->skb->tail;
+ }
skb_pull(chunk->skb, sizeof(sctp_chunkhdr_t));
chunk->subh.v = NULL; /* Subheader is no longer valid. */
if (chunk->chunk_end < chunk->skb->tail) {
/* This is not a singleton */
chunk->singleton = 0;
+ } else if (chunk->chunk_end > chunk->skb->tail) {
+ /* RFC 2960, Section 6.10 Bundling
+ *
+ * Partial chunks MUST NOT be placed in an SCTP packet.
+ * If the receiver detects a partial chunk, it MUST drop
+ * the chunk.
+ *
+ * Since the end of the chunk is past the end of our buffer
+ * (which contains the whole packet, we can freely discard
+ * the whole packet.
+ */
+ sctp_chunk_free(chunk);
+ chunk = queue->in_progress = NULL;
+
+ return NULL;
} else {
/* We are at the end of the packet, so mark the chunk
* in case we need to send a SACK.