--- /dev/null
+From 2570a4f5428bcdb1077622342181755741e7fa60 Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Wed, 13 Jan 2010 17:27:37 -0800
+Subject: ipv6: skb_dst() can be NULL in ipv6_hop_jumbo().
+
+From: David S. Miller <davem@davemloft.net>
+
+commit 2570a4f5428bcdb1077622342181755741e7fa60 upstream.
+
+This fixes CERT-FI FICORA #341748
+
+Discovered by Olli Jarva and Tuomo Untinen from the CROSS
+project at Codenomicon Ltd.
+
+Just like in CVE-2007-4567, we can't rely upon skb_dst() being
+non-NULL at this point. We fixed that in commit
+e76b2b2567b83448c2ee85a896433b96150c92e6 ("[IPV6]: Do no rely on
+skb->dst before it is assigned.")
+
+However commit 483a47d2fe794328d29950fe00ce26dd405d9437 ("ipv6: added
+net argument to IP6_INC_STATS_BH") put a new version of the same bug
+into this function.
+
+Complicating analysis further, this bug can only trigger when network
+namespaces are enabled in the build. When namespaces are turned off,
+the dev_net() does not evaluate it's argument, so the dereference
+would not occur.
+
+So, for a long time, namespaces couldn't be turned on unless SYSFS was
+disabled. Therefore, this code has largely been disabled except by
+people turning it on explicitly for namespace development.
+
+With help from Eugene Teo <eugene@redhat.com>
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/ipv6/exthdrs.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/net/ipv6/exthdrs.c
++++ b/net/ipv6/exthdrs.c
+@@ -559,6 +559,11 @@ static inline struct inet6_dev *ipv6_skb
+ return skb_dst(skb) ? ip6_dst_idev(skb_dst(skb)) : __in6_dev_get(skb->dev);
+ }
+
++static inline struct net *ipv6_skb_net(struct sk_buff *skb)
++{
++ return skb_dst(skb) ? dev_net(skb_dst(skb)->dev) : dev_net(skb->dev);
++}
++
+ /* Router Alert as of RFC 2711 */
+
+ static int ipv6_hop_ra(struct sk_buff *skb, int optoff)
+@@ -580,8 +585,8 @@ static int ipv6_hop_ra(struct sk_buff *s
+ static int ipv6_hop_jumbo(struct sk_buff *skb, int optoff)
+ {
+ const unsigned char *nh = skb_network_header(skb);
++ struct net *net = ipv6_skb_net(skb);
+ u32 pkt_len;
+- struct net *net = dev_net(skb_dst(skb)->dev);
+
+ if (nh[optoff + 1] != 4 || (optoff & 3) != 2) {
+ LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n",
--- /dev/null
+From d4703aefdbc8f9f347f6dcefcddd791294314eb7 Mon Sep 17 00:00:00 2001
+From: Rusty Russell <rusty@rustcorp.com.au>
+Date: Tue, 15 Dec 2009 16:28:32 -0600
+Subject: module: handle ppc64 relocating kcrctabs when CONFIG_RELOCATABLE=y
+
+From: Rusty Russell <rusty@rustcorp.com.au>
+
+commit d4703aefdbc8f9f347f6dcefcddd791294314eb7 upstream.
+
+powerpc applies relocations to the kcrctab. They're absolute symbols,
+but it's not completely unreasonable: other archs may too, but the
+relocation is often 0.
+
+http://lists.ozlabs.org/pipermail/linuxppc-dev/2009-November/077972.html
+
+Inspired-by: Neil Horman <nhorman@tuxdriver.com>
+Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
+Tested-by: Neil Horman <nhorman@tuxdriver.com>
+Acked-by: Paul Mackerras <paulus@samba.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/powerpc/include/asm/module.h | 5 +++++
+ arch/powerpc/kernel/vmlinux.lds.S | 3 +++
+ kernel/module.c | 28 +++++++++++++++++++++-------
+ 3 files changed, 29 insertions(+), 7 deletions(-)
+
+--- a/arch/powerpc/include/asm/module.h
++++ b/arch/powerpc/include/asm/module.h
+@@ -87,5 +87,10 @@ struct exception_table_entry;
+ void sort_ex_table(struct exception_table_entry *start,
+ struct exception_table_entry *finish);
+
++#ifdef CONFIG_MODVERSIONS
++#define ARCH_RELOCATES_KCRCTAB
++
++extern const unsigned long reloc_start[];
++#endif
+ #endif /* __KERNEL__ */
+ #endif /* _ASM_POWERPC_MODULE_H */
+--- a/arch/powerpc/kernel/vmlinux.lds.S
++++ b/arch/powerpc/kernel/vmlinux.lds.S
+@@ -38,6 +38,9 @@ jiffies = jiffies_64 + 4;
+ #endif
+ SECTIONS
+ {
++ . = 0;
++ reloc_start = .;
++
+ . = KERNELBASE;
+
+ /*
+--- a/kernel/module.c
++++ b/kernel/module.c
+@@ -1030,11 +1030,23 @@ static int try_to_force_load(struct modu
+ }
+
+ #ifdef CONFIG_MODVERSIONS
++/* If the arch applies (non-zero) relocations to kernel kcrctab, unapply it. */
++static unsigned long maybe_relocated(unsigned long crc,
++ const struct module *crc_owner)
++{
++#ifdef ARCH_RELOCATES_KCRCTAB
++ if (crc_owner == NULL)
++ return crc - (unsigned long)reloc_start;
++#endif
++ return crc;
++}
++
+ static int check_version(Elf_Shdr *sechdrs,
+ unsigned int versindex,
+ const char *symname,
+ struct module *mod,
+- const unsigned long *crc)
++ const unsigned long *crc,
++ const struct module *crc_owner)
+ {
+ unsigned int i, num_versions;
+ struct modversion_info *versions;
+@@ -1055,10 +1067,10 @@ static int check_version(Elf_Shdr *sechd
+ if (strcmp(versions[i].name, symname) != 0)
+ continue;
+
+- if (versions[i].crc == *crc)
++ if (versions[i].crc == maybe_relocated(*crc, crc_owner))
+ return 1;
+ DEBUGP("Found checksum %lX vs module %lX\n",
+- *crc, versions[i].crc);
++ maybe_relocated(*crc, crc_owner), versions[i].crc);
+ goto bad_version;
+ }
+
+@@ -1081,7 +1093,8 @@ static inline int check_modstruct_versio
+ if (!find_symbol(MODULE_SYMBOL_PREFIX "module_layout", NULL,
+ &crc, true, false))
+ BUG();
+- return check_version(sechdrs, versindex, "module_layout", mod, crc);
++ return check_version(sechdrs, versindex, "module_layout", mod, crc,
++ NULL);
+ }
+
+ /* First part is kernel version, which we ignore if module has crcs. */
+@@ -1099,7 +1112,8 @@ static inline int check_version(Elf_Shdr
+ unsigned int versindex,
+ const char *symname,
+ struct module *mod,
+- const unsigned long *crc)
++ const unsigned long *crc,
++ const struct module *crc_owner)
+ {
+ return 1;
+ }
+@@ -1134,8 +1148,8 @@ static const struct kernel_symbol *resol
+ /* use_module can fail due to OOM,
+ or module initialization or unloading */
+ if (sym) {
+- if (!check_version(sechdrs, versindex, name, mod, crc) ||
+- !use_module(mod, owner))
++ if (!check_version(sechdrs, versindex, name, mod, crc, owner)
++ || !use_module(mod, owner))
+ sym = NULL;
+ }
+ return sym;