From cf091f2c3109b5b38fea8af844df74c6c673910e Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 17 Oct 2011 17:59:53 +0000 Subject: [PATCH] --- yaml --- r: 264387 b: refs/heads/master c: 4ea2739ea89883ddf79980a8aa27d5e57093e464 h: refs/heads/master i: 264385: 176db11da7a5694c0563d51e262fd2d9a085fcfb 264383: 5086f7f72bee4c7a1768a03d49013ef70b0d5336 v: v3 --- [refs] | 2 +- trunk/drivers/net/pptp.c | 20 ++++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/[refs] b/[refs] index a2824035b9c7..e9d890ea32a1 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 58af19e387d8821927e49be3f467da5e6a0aa8fd +refs/heads/master: 4ea2739ea89883ddf79980a8aa27d5e57093e464 diff --git a/trunk/drivers/net/pptp.c b/trunk/drivers/net/pptp.c index 9c0403d0107c..89f829f5f725 100644 --- a/trunk/drivers/net/pptp.c +++ b/trunk/drivers/net/pptp.c @@ -307,11 +307,18 @@ static int pptp_rcv_core(struct sock *sk, struct sk_buff *skb) } header = (struct pptp_gre_header *)(skb->data); + headersize = sizeof(*header); /* test if acknowledgement present */ if (PPTP_GRE_IS_A(header->ver)) { - __u32 ack = (PPTP_GRE_IS_S(header->flags)) ? - header->ack : header->seq; /* ack in different place if S = 0 */ + __u32 ack; + + if (!pskb_may_pull(skb, headersize)) + goto drop; + header = (struct pptp_gre_header *)(skb->data); + + /* ack in different place if S = 0 */ + ack = PPTP_GRE_IS_S(header->flags) ? header->ack : header->seq; ack = ntohl(ack); @@ -320,21 +327,18 @@ static int pptp_rcv_core(struct sock *sk, struct sk_buff *skb) /* also handle sequence number wrap-around */ if (WRAPPED(ack, opt->ack_recv)) opt->ack_recv = ack; + } else { + headersize -= sizeof(header->ack); } - /* test if payload present */ if (!PPTP_GRE_IS_S(header->flags)) goto drop; - headersize = sizeof(*header); payload_len = ntohs(header->payload_len); seq = ntohl(header->seq); - /* no ack present? */ - if (!PPTP_GRE_IS_A(header->ver)) - headersize -= sizeof(header->ack); /* check for incomplete packet (length smaller than expected) */ - if (skb->len - headersize < payload_len) + if (!pskb_may_pull(skb, headersize + payload_len)) goto drop; payload = skb->data + headersize;