aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/sctp/inqueue.c33
-rw-r--r--net/sctp/sm_statefuns.c3
2 files changed, 10 insertions, 26 deletions
diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c
index 4de12afa13d4..7e8a16c77039 100644
--- a/net/sctp/inqueue.c
+++ b/net/sctp/inqueue.c
@@ -140,18 +140,9 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue)
140 } else { 140 } else {
141 /* Nothing to do. Next chunk in the packet, please. */ 141 /* Nothing to do. Next chunk in the packet, please. */
142 ch = (sctp_chunkhdr_t *) chunk->chunk_end; 142 ch = (sctp_chunkhdr_t *) chunk->chunk_end;
143
144 /* Force chunk->skb->data to chunk->chunk_end. */ 143 /* Force chunk->skb->data to chunk->chunk_end. */
145 skb_pull(chunk->skb, 144 skb_pull(chunk->skb, chunk->chunk_end - chunk->skb->data);
146 chunk->chunk_end - chunk->skb->data); 145 /* We are guaranteed to pull a SCTP header. */
147
148 /* Verify that we have at least chunk headers
149 * worth of buffer left.
150 */
151 if (skb_headlen(chunk->skb) < sizeof(sctp_chunkhdr_t)) {
152 sctp_chunk_free(chunk);
153 chunk = queue->in_progress = NULL;
154 }
155 } 146 }
156 } 147 }
157 148
@@ -187,24 +178,14 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue)
187 skb_pull(chunk->skb, sizeof(sctp_chunkhdr_t)); 178 skb_pull(chunk->skb, sizeof(sctp_chunkhdr_t));
188 chunk->subh.v = NULL; /* Subheader is no longer valid. */ 179 chunk->subh.v = NULL; /* Subheader is no longer valid. */
189 180
190 if (chunk->chunk_end < skb_tail_pointer(chunk->skb)) { 181 if (chunk->chunk_end + sizeof(sctp_chunkhdr_t) <
182 skb_tail_pointer(chunk->skb)) {
191 /* This is not a singleton */ 183 /* This is not a singleton */
192 chunk->singleton = 0; 184 chunk->singleton = 0;
193 } else if (chunk->chunk_end > skb_tail_pointer(chunk->skb)) { 185 } else if (chunk->chunk_end > skb_tail_pointer(chunk->skb)) {
194 /* RFC 2960, Section 6.10 Bundling 186 /* Discard inside state machine. */
195 * 187 chunk->pdiscard = 1;
196 * Partial chunks MUST NOT be placed in an SCTP packet. 188 chunk->chunk_end = skb_tail_pointer(chunk->skb);
197 * If the receiver detects a partial chunk, it MUST drop
198 * the chunk.
199 *
200 * Since the end of the chunk is past the end of our buffer
201 * (which contains the whole packet, we can freely discard
202 * the whole packet.
203 */
204 sctp_chunk_free(chunk);
205 chunk = queue->in_progress = NULL;
206
207 return NULL;
208 } else { 189 } else {
209 /* We are at the end of the packet, so mark the chunk 190 /* We are at the end of the packet, so mark the chunk
210 * in case we need to send a SACK. 191 * in case we need to send a SACK.
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index bdea3dfbad31..3ee27b7704ff 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -170,6 +170,9 @@ sctp_chunk_length_valid(struct sctp_chunk *chunk,
170{ 170{
171 __u16 chunk_length = ntohs(chunk->chunk_hdr->length); 171 __u16 chunk_length = ntohs(chunk->chunk_hdr->length);
172 172
173 /* Previously already marked? */
174 if (unlikely(chunk->pdiscard))
175 return 0;
173 if (unlikely(chunk_length < required_length)) 176 if (unlikely(chunk_length < required_length))
174 return 0; 177 return 0;
175 178