diff options
author | John Stultz <john.stultz@linaro.org> | 2011-10-26 13:48:49 -0700 |
---|---|---|
committer | John Stultz <john.stultz@linaro.org> | 2011-10-26 13:48:49 -0700 |
commit | 2216773fc021964a413409141d439de4f6a108f7 (patch) | |
tree | 7b2f8cdcdf5fb05d75bd92f0c8d9ac635ceec48c /drivers/net/pptp.c | |
parent | 42ac8ca89aef66618e8ae2d6e48e3f523bfcd69d (diff) | |
parent | af1bdb79ca64ceadc7b44b11929b384eff66ce59 (diff) |
Merge branch 'upstream/linaro-3.1' into linaro-android-3.1-agreen-rebaselinux-linaro-3.1-2011.10-2-android-0
Diffstat (limited to 'drivers/net/pptp.c')
-rw-r--r-- | drivers/net/pptp.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/drivers/net/pptp.c b/drivers/net/pptp.c index eae542a7e98..89f829f5f72 100644 --- a/drivers/net/pptp.c +++ b/drivers/net/pptp.c @@ -285,8 +285,10 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb) ip_send_check(iph); ip_local_out(skb); + return 1; tx_error: + kfree_skb(skb); return 1; } @@ -305,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); @@ -318,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; |