Commit 4ea2739e authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller

pptp: pptp_rcv_core() misses pskb_may_pull() call

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: default avatarBradley Peterson <despite@gmail.com>
Signed-off-by: default avatarEric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 58af19e3
...@@ -307,11 +307,18 @@ static int pptp_rcv_core(struct sock *sk, struct sk_buff *skb) ...@@ -307,11 +307,18 @@ static int pptp_rcv_core(struct sock *sk, struct sk_buff *skb)
} }
header = (struct pptp_gre_header *)(skb->data); header = (struct pptp_gre_header *)(skb->data);
headersize = sizeof(*header);
/* test if acknowledgement present */ /* test if acknowledgement present */
if (PPTP_GRE_IS_A(header->ver)) { if (PPTP_GRE_IS_A(header->ver)) {
__u32 ack = (PPTP_GRE_IS_S(header->flags)) ? __u32 ack;
header->ack : header->seq; /* ack in different place if S = 0 */
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); ack = ntohl(ack);
...@@ -320,21 +327,18 @@ static int pptp_rcv_core(struct sock *sk, struct sk_buff *skb) ...@@ -320,21 +327,18 @@ static int pptp_rcv_core(struct sock *sk, struct sk_buff *skb)
/* also handle sequence number wrap-around */ /* also handle sequence number wrap-around */
if (WRAPPED(ack, opt->ack_recv)) if (WRAPPED(ack, opt->ack_recv))
opt->ack_recv = ack; opt->ack_recv = ack;
} else {
headersize -= sizeof(header->ack);
} }
/* test if payload present */ /* test if payload present */
if (!PPTP_GRE_IS_S(header->flags)) if (!PPTP_GRE_IS_S(header->flags))
goto drop; goto drop;
headersize = sizeof(*header);
payload_len = ntohs(header->payload_len); payload_len = ntohs(header->payload_len);
seq = ntohl(header->seq); 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) */ /* check for incomplete packet (length smaller than expected) */
if (skb->len - headersize < payload_len) if (!pskb_may_pull(skb, headersize + payload_len))
goto drop; goto drop;
payload = skb->data + headersize; payload = skb->data + headersize;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment