diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/pptp.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/drivers/net/pptp.c b/drivers/net/pptp.c index 9c0403d0107c..89f829f5f725 100644 --- a/drivers/net/pptp.c +++ b/drivers/net/pptp.c | |||
@@ -307,11 +307,18 @@ static int pptp_rcv_core(struct sock *sk, struct sk_buff *skb) | |||
307 | } | 307 | } |
308 | 308 | ||
309 | header = (struct pptp_gre_header *)(skb->data); | 309 | header = (struct pptp_gre_header *)(skb->data); |
310 | headersize = sizeof(*header); | ||
310 | 311 | ||
311 | /* test if acknowledgement present */ | 312 | /* test if acknowledgement present */ |
312 | if (PPTP_GRE_IS_A(header->ver)) { | 313 | if (PPTP_GRE_IS_A(header->ver)) { |
313 | __u32 ack = (PPTP_GRE_IS_S(header->flags)) ? | 314 | __u32 ack; |
314 | header->ack : header->seq; /* ack in different place if S = 0 */ | 315 | |
316 | if (!pskb_may_pull(skb, headersize)) | ||
317 | goto drop; | ||
318 | header = (struct pptp_gre_header *)(skb->data); | ||
319 | |||
320 | /* ack in different place if S = 0 */ | ||
321 | ack = PPTP_GRE_IS_S(header->flags) ? header->ack : header->seq; | ||
315 | 322 | ||
316 | ack = ntohl(ack); | 323 | ack = ntohl(ack); |
317 | 324 | ||
@@ -320,21 +327,18 @@ static int pptp_rcv_core(struct sock *sk, struct sk_buff *skb) | |||
320 | /* also handle sequence number wrap-around */ | 327 | /* also handle sequence number wrap-around */ |
321 | if (WRAPPED(ack, opt->ack_recv)) | 328 | if (WRAPPED(ack, opt->ack_recv)) |
322 | opt->ack_recv = ack; | 329 | opt->ack_recv = ack; |
330 | } else { | ||
331 | headersize -= sizeof(header->ack); | ||
323 | } | 332 | } |
324 | |||
325 | /* test if payload present */ | 333 | /* test if payload present */ |
326 | if (!PPTP_GRE_IS_S(header->flags)) | 334 | if (!PPTP_GRE_IS_S(header->flags)) |
327 | goto drop; | 335 | goto drop; |
328 | 336 | ||
329 | headersize = sizeof(*header); | ||
330 | payload_len = ntohs(header->payload_len); | 337 | payload_len = ntohs(header->payload_len); |
331 | seq = ntohl(header->seq); | 338 | seq = ntohl(header->seq); |
332 | 339 | ||
333 | /* no ack present? */ | ||
334 | if (!PPTP_GRE_IS_A(header->ver)) | ||
335 | headersize -= sizeof(header->ack); | ||
336 | /* check for incomplete packet (length smaller than expected) */ | 340 | /* check for incomplete packet (length smaller than expected) */ |
337 | if (skb->len - headersize < payload_len) | 341 | if (!pskb_may_pull(skb, headersize + payload_len)) |
338 | goto drop; | 342 | goto drop; |
339 | 343 | ||
340 | payload = skb->data + headersize; | 344 | payload = skb->data + headersize; |