|
@@ -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;
|