From 8843cd40eee75a5ceeeddcde5040391d5a996e46 Mon Sep 17 00:00:00 2001 From: "Justin M. Forbes" Date: Tue, 7 Feb 2017 08:15:40 -0600 Subject: [PATCH] CVE-2017-5897 ip6_gre: Invalid reads in ip6gre_err (rhbz 1419848 1419851) --- ip6_gre-fix-ip6gre_err-invalid-reads.patch | 91 ++++++++++++++++++++++ kernel.spec | 6 ++ 2 files changed, 97 insertions(+) create mode 100644 ip6_gre-fix-ip6gre_err-invalid-reads.patch diff --git a/ip6_gre-fix-ip6gre_err-invalid-reads.patch b/ip6_gre-fix-ip6gre_err-invalid-reads.patch new file mode 100644 index 000000000..756663c11 --- /dev/null +++ b/ip6_gre-fix-ip6gre_err-invalid-reads.patch @@ -0,0 +1,91 @@ +From 7892032cfe67f4bde6fc2ee967e45a8fbaf33756 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Sat, 4 Feb 2017 23:18:55 -0800 +Subject: ip6_gre: fix ip6gre_err() invalid reads + +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 +Reported-by: Andrey Konovalov +Signed-off-by: David S. Miller +--- + 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 5586318..630b73b 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; + +-- +cgit v0.12 + diff --git a/kernel.spec b/kernel.spec index bfa167c4a..984f6be9d 100644 --- a/kernel.spec +++ b/kernel.spec @@ -640,6 +640,9 @@ Patch855: kvm-fix-page-struct-leak-in-handle_vmon.patch # rhbz 1418858 Patch856: PCI-ASPM-Handle-PCI-to-PCIe-bridges-as-roots-of-PCIe-hierarchies.patch +#CVE-2017-5897 rhbz 1419848 1419851 +Patch857: ip6_gre-fix-ip6gre_err-invalid-reads.patch + # END OF PATCH DEFINITIONS %endif @@ -2187,6 +2190,9 @@ fi # # %changelog +* Tue Feb 7 2017 Justin M. Forbes +- CVE-2017-5897 ip6_gre: Invalid reads in ip6gre_err (rhbz 1419848 1419851) + * Tue Feb 7 2017 Peter Robinson 4.9.8-201 - Drop "fixes" for bcm238x as they seem to break other Raspberry Pi 3 things