Skip to content

Commit

Permalink
pptp: pptp_rcv_core() misses pskb_may_pull() call
Browse files Browse the repository at this point in the history
e1000e uses paged frags, so any layer incorrectly pulling bytes from skb
can trigger a BUG in skb_pull()

[951.142737]  [<ffffffff813d2f36>] skb_pull+0x15/0x17
[951.142737]  [<ffffffffa0286824>] pptp_rcv_core+0x126/0x19a [pptp]
[951.152725]  [<ffffffff813d17c4>] sk_receive_skb+0x69/0x105
[951.163558]  [<ffffffffa0286993>] pptp_rcv+0xc8/0xdc [pptp]
[951.165092]  [<ffffffffa02800a3>] gre_rcv+0x62/0x75 [gre]
[951.165092]  [<ffffffff81410784>] ip_local_deliver_finish+0x150/0x1c1
[951.177599]  [<ffffffff81410634>] ? ip_local_deliver_finish+0x0/0x1c1
[951.177599]  [<ffffffff81410846>] NF_HOOK.clone.7+0x51/0x58
[951.177599]  [<ffffffff81410996>] ip_local_deliver+0x51/0x55
[951.177599]  [<ffffffff814105b9>] ip_rcv_finish+0x31a/0x33e
[951.177599]  [<ffffffff8141029f>] ? ip_rcv_finish+0x0/0x33e
[951.204898]  [<ffffffff81410846>] NF_HOOK.clone.7+0x51/0x58
[951.214651]  [<ffffffff81410bb5>] ip_rcv+0x21b/0x246

pptp_rcv_core() is a nice example of a function assuming everything it
needs is available in skb head.

Reported-by: Bradley Peterson <despite@gmail.com>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Eric Dumazet authored and David S. Miller committed Oct 19, 2011
1 parent 58af19e commit 4ea2739
Showing 1 changed file with 12 additions and 8 deletions.
20 changes: 12 additions & 8 deletions drivers/net/pptp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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;
Expand Down

0 comments on commit 4ea2739

Please sign in to comment.