* [PATCH net] ip6_gre: fix ip6gre_err() invalid reads
@ 2017-02-05 7:18 Eric Dumazet
2017-02-05 22:23 ` David Miller
0 siblings, 1 reply; 2+ messages in thread
From: Eric Dumazet @ 2017-02-05 7:18 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Andrey Konovalov
From: Eric Dumazet <edumazet@google.com>
Andrey Konovalov reported out of bound accesses in ip6gre_err()
If GRE flags contains GRE_KEY, the following expression
*(((__be32 *)p) + (grehlen / 4) - 1)
accesses data ~40 bytes after the expected point, since
grehlen includes the size of IPv6 headers.
Let's use a "struct gre_base_hdr *greh" pointer to make this
code more readable.
p[1] becomes greh->protocol.
grhlen is the GRE header length.
Fixes: c12b395a4664 ("gre: Support GRE over IPv6")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: Andrey Konovalov <andreyknvl@google.com>
---
net/ipv6/ip6_gre.c | 40 +++++++++++++++++++++-------------------
1 file changed, 21 insertions(+), 19 deletions(-)
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 558631860d91bbcb1321a4b566b6e92ddcaf7163..630b73be599977599c0021849fc6eb689cfefad7 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -367,35 +367,37 @@ static void ip6gre_tunnel_uninit(struct net_device *dev)
static void ip6gre_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
- u8 type, u8 code, int offset, __be32 info)
+ u8 type, u8 code, int offset, __be32 info)
{
- const struct ipv6hdr *ipv6h = (const struct ipv6hdr *)skb->data;
- __be16 *p = (__be16 *)(skb->data + offset);
- int grehlen = offset + 4;
+ const struct gre_base_hdr *greh;
+ const struct ipv6hdr *ipv6h;
+ int grehlen = sizeof(*greh);
struct ip6_tnl *t;
+ int key_off = 0;
__be16 flags;
+ __be32 key;
- flags = p[0];
- if (flags&(GRE_CSUM|GRE_KEY|GRE_SEQ|GRE_ROUTING|GRE_VERSION)) {
- if (flags&(GRE_VERSION|GRE_ROUTING))
- return;
- if (flags&GRE_KEY) {
- grehlen += 4;
- if (flags&GRE_CSUM)
- grehlen += 4;
- }
+ if (!pskb_may_pull(skb, offset + grehlen))
+ return;
+ greh = (const struct gre_base_hdr *)(skb->data + offset);
+ flags = greh->flags;
+ if (flags & (GRE_VERSION | GRE_ROUTING))
+ return;
+ if (flags & GRE_CSUM)
+ grehlen += 4;
+ if (flags & GRE_KEY) {
+ key_off = grehlen + offset;
+ grehlen += 4;
}
- /* If only 8 bytes returned, keyed message will be dropped here */
- if (!pskb_may_pull(skb, grehlen))
+ if (!pskb_may_pull(skb, offset + grehlen))
return;
ipv6h = (const struct ipv6hdr *)skb->data;
- p = (__be16 *)(skb->data + offset);
+ greh = (const struct gre_base_hdr *)(skb->data + offset);
+ key = key_off ? *(__be32 *)(skb->data + key_off) : 0;
t = ip6gre_tunnel_lookup(skb->dev, &ipv6h->daddr, &ipv6h->saddr,
- flags & GRE_KEY ?
- *(((__be32 *)p) + (grehlen / 4) - 1) : 0,
- p[1]);
+ key, greh->protocol);
if (!t)
return;
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH net] ip6_gre: fix ip6gre_err() invalid reads
2017-02-05 7:18 [PATCH net] ip6_gre: fix ip6gre_err() invalid reads Eric Dumazet
@ 2017-02-05 22:23 ` David Miller
0 siblings, 0 replies; 2+ messages in thread
From: David Miller @ 2017-02-05 22:23 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev, andreyknvl
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Sat, 04 Feb 2017 23:18:55 -0800
> From: Eric Dumazet <edumazet@google.com>
>
> Andrey Konovalov reported out of bound accesses in ip6gre_err()
>
> If GRE flags contains GRE_KEY, the following expression
> *(((__be32 *)p) + (grehlen / 4) - 1)
>
> accesses data ~40 bytes after the expected point, since
> grehlen includes the size of IPv6 headers.
>
> Let's use a "struct gre_base_hdr *greh" pointer to make this
> code more readable.
>
> p[1] becomes greh->protocol.
> grhlen is the GRE header length.
>
> Fixes: c12b395a4664 ("gre: Support GRE over IPv6")
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Reported-by: Andrey Konovalov <andreyknvl@google.com>
So the bug is that we include offset twice in the calculation.
Applied and queued up for -stable, thanks.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2017-02-05 22:23 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-02-05 7:18 [PATCH net] ip6_gre: fix ip6gre_err() invalid reads Eric Dumazet
2017-02-05 22:23 ` David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).