From ca7ceedfad928f06e8e00c7b403810d866143de3 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 16 Jan 2015 00:15:01 +0000 Subject: [PATCH] Add two security fixes svn path=/dists/sid/linux/; revision=22262 --- debian/changelog | 3 + ...ack-disable-generic-tracking-for-kno.patch | 87 ++++++++++++ ...the-vdso-address-randomization-algor.patch | 124 ++++++++++++++++++ debian/patches/series | 2 + 4 files changed, 216 insertions(+) create mode 100644 debian/patches/bugfix/all/netfilter-conntrack-disable-generic-tracking-for-kno.patch create mode 100644 debian/patches/bugfix/x86/x86_64-vdso-fix-the-vdso-address-randomization-algor.patch diff --git a/debian/changelog b/debian/changelog index 88349f0fd..b459048bb 100644 --- a/debian/changelog +++ b/debian/changelog @@ -265,6 +265,9 @@ linux (3.16.7-ckt4-1) UNRELEASED; urgency=medium (Closes: #748398) (thanks to John Paul Adrian Glaubitz for thoroughly testing this change) * userns: Fix ABI change in 3.16.7-ckt4 + * netfilter: conntrack: disable generic tracking for known protocols + (CVE-2014-8160) + * [amd64] vdso: Fix the vdso address randomization algorithm (CVE-2014-9585) [ Ian Campbell ] * [armhf] Enable support for support OMAP5432 uEVM by enabling: diff --git a/debian/patches/bugfix/all/netfilter-conntrack-disable-generic-tracking-for-kno.patch b/debian/patches/bugfix/all/netfilter-conntrack-disable-generic-tracking-for-kno.patch new file mode 100644 index 000000000..ede639194 --- /dev/null +++ b/debian/patches/bugfix/all/netfilter-conntrack-disable-generic-tracking-for-kno.patch @@ -0,0 +1,87 @@ +From: Florian Westphal +Date: Fri, 26 Sep 2014 11:35:42 +0200 +Subject: netfilter: conntrack: disable generic tracking for known protocols +Origin: https://git.kernel.org/linus/db29a9508a9246e77087c5531e45b2c88ec6988b + +Given following iptables ruleset: + +-P FORWARD DROP +-A FORWARD -m sctp --dport 9 -j ACCEPT +-A FORWARD -p tcp --dport 80 -j ACCEPT +-A FORWARD -p tcp -m conntrack -m state ESTABLISHED,RELATED -j ACCEPT + +One would assume that this allows SCTP on port 9 and TCP on port 80. +Unfortunately, if the SCTP conntrack module is not loaded, this allows +*all* SCTP communication, to pass though, i.e. -p sctp -j ACCEPT, +which we think is a security issue. + +This is because on the first SCTP packet on port 9, we create a dummy +"generic l4" conntrack entry without any port information (since +conntrack doesn't know how to extract this information). + +All subsequent packets that are unknown will then be in established +state since they will fallback to proto_generic and will match the +'generic' entry. + +Our originally proposed version [1] completely disabled generic protocol +tracking, but Jozsef suggests to not track protocols for which a more +suitable helper is available, hence we now mitigate the issue for in +tree known ct protocol helpers only, so that at least NAT and direction +information will still be preserved for others. + + [1] http://www.spinics.net/lists/netfilter-devel/msg33430.html + +Joint work with Daniel Borkmann. + +Signed-off-by: Florian Westphal +Signed-off-by: Daniel Borkmann +Acked-by: Jozsef Kadlecsik +Signed-off-by: Pablo Neira Ayuso +--- + net/netfilter/nf_conntrack_proto_generic.c | 26 +++++++++++++++++++++++++- + 1 file changed, 25 insertions(+), 1 deletion(-) + +diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c +index d25f293..957c1db 100644 +--- a/net/netfilter/nf_conntrack_proto_generic.c ++++ b/net/netfilter/nf_conntrack_proto_generic.c +@@ -14,6 +14,30 @@ + + static unsigned int nf_ct_generic_timeout __read_mostly = 600*HZ; + ++static bool nf_generic_should_process(u8 proto) ++{ ++ switch (proto) { ++#ifdef CONFIG_NF_CT_PROTO_SCTP_MODULE ++ case IPPROTO_SCTP: ++ return false; ++#endif ++#ifdef CONFIG_NF_CT_PROTO_DCCP_MODULE ++ case IPPROTO_DCCP: ++ return false; ++#endif ++#ifdef CONFIG_NF_CT_PROTO_GRE_MODULE ++ case IPPROTO_GRE: ++ return false; ++#endif ++#ifdef CONFIG_NF_CT_PROTO_UDPLITE_MODULE ++ case IPPROTO_UDPLITE: ++ return false; ++#endif ++ default: ++ return true; ++ } ++} ++ + static inline struct nf_generic_net *generic_pernet(struct net *net) + { + return &net->ct.nf_ct_proto.generic; +@@ -67,7 +91,7 @@ static int generic_packet(struct nf_conn *ct, + static bool generic_new(struct nf_conn *ct, const struct sk_buff *skb, + unsigned int dataoff, unsigned int *timeouts) + { +- return true; ++ return nf_generic_should_process(nf_ct_protonum(ct)); + } + + #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) diff --git a/debian/patches/bugfix/x86/x86_64-vdso-fix-the-vdso-address-randomization-algor.patch b/debian/patches/bugfix/x86/x86_64-vdso-fix-the-vdso-address-randomization-algor.patch new file mode 100644 index 000000000..76a33ae26 --- /dev/null +++ b/debian/patches/bugfix/x86/x86_64-vdso-fix-the-vdso-address-randomization-algor.patch @@ -0,0 +1,124 @@ +From: Andy Lutomirski +Date: Fri, 19 Dec 2014 16:04:11 -0800 +Subject: x86_64, vdso: Fix the vdso address randomization algorithm +Origin: https://git.kernel.org/linus/394f56fe480140877304d342dec46d50dc823d46 + +The theory behind vdso randomization is that it's mapped at a random +offset above the top of the stack. To avoid wasting a page of +memory for an extra page table, the vdso isn't supposed to extend +past the lowest PMD into which it can fit. Other than that, the +address should be a uniformly distributed address that meets all of +the alignment requirements. + +The current algorithm is buggy: the vdso has about a 50% probability +of being at the very end of a PMD. The current algorithm also has a +decent chance of failing outright due to incorrect handling of the +case where the top of the stack is near the top of its PMD. + +This fixes the implementation. The paxtest estimate of vdso +"randomisation" improves from 11 bits to 18 bits. (Disclaimer: I +don't know what the paxtest code is actually calculating.) + +It's worth noting that this algorithm is inherently biased: the vdso +is more likely to end up near the end of its PMD than near the +beginning. Ideally we would either nix the PMD sharing requirement +or jointly randomize the vdso and the stack to reduce the bias. + +In the mean time, this is a considerable improvement with basically +no risk of compatibility issues, since the allowed outputs of the +algorithm are unchanged. + +As an easy test, doing this: + +for i in `seq 10000` + do grep -P vdso /proc/self/maps |cut -d- -f1 +done |sort |uniq -d + +used to produce lots of output (1445 lines on my most recent run). +A tiny subset looks like this: + +7fffdfffe000 +7fffe01fe000 +7fffe05fe000 +7fffe07fe000 +7fffe09fe000 +7fffe0bfe000 +7fffe0dfe000 + +Note the suspicious fe000 endings. With the fix, I get a much more +palatable 76 repeated addresses. + +Reviewed-by: Kees Cook +Cc: stable@vger.kernel.org +Signed-off-by: Andy Lutomirski +--- + arch/x86/vdso/vma.c | 45 +++++++++++++++++++++++++++++---------------- + 1 file changed, 29 insertions(+), 16 deletions(-) + +--- a/arch/x86/vdso/vma.c ++++ b/arch/x86/vdso/vma.c +@@ -54,12 +54,17 @@ subsys_initcall(init_vdso); + + struct linux_binprm; + +-/* Put the vdso above the (randomized) stack with another randomized offset. +- This way there is no hole in the middle of address space. +- To save memory make sure it is still in the same PTE as the stack top. +- This doesn't give that many random bits. +- +- Only used for the 64-bit and x32 vdsos. */ ++/* ++ * Put the vdso above the (randomized) stack with another randomized ++ * offset. This way there is no hole in the middle of address space. ++ * To save memory make sure it is still in the same PTE as the stack ++ * top. This doesn't give that many random bits. ++ * ++ * Note that this algorithm is imperfect: the distribution of the vdso ++ * start address within a PMD is biased toward the end. ++ * ++ * Only used for the 64-bit and x32 vdsos. ++ */ + static unsigned long vdso_addr(unsigned long start, unsigned len) + { + #ifdef CONFIG_X86_32 +@@ -67,22 +72,30 @@ static unsigned long vdso_addr(unsigned + #else + unsigned long addr, end; + unsigned offset; +- end = (start + PMD_SIZE - 1) & PMD_MASK; ++ ++ /* ++ * Round up the start address. It can start out unaligned as a result ++ * of stack start randomization. ++ */ ++ start = PAGE_ALIGN(start); ++ ++ /* Round the lowest possible end address up to a PMD boundary. */ ++ end = (start + len + PMD_SIZE - 1) & PMD_MASK; + if (end >= TASK_SIZE_MAX) + end = TASK_SIZE_MAX; + end -= len; +- /* This loses some more bits than a modulo, but is cheaper */ +- offset = get_random_int() & (PTRS_PER_PTE - 1); +- addr = start + (offset << PAGE_SHIFT); +- if (addr >= end) +- addr = end; ++ ++ if (end > start) { ++ offset = get_random_int() % (((end - start) >> PAGE_SHIFT) + 1); ++ addr = start + (offset << PAGE_SHIFT); ++ } else { ++ addr = start; ++ } + + /* +- * page-align it here so that get_unmapped_area doesn't +- * align it wrongfully again to the next page. addr can come in 4K +- * unaligned here as a result of stack start randomization. ++ * Forcibly align the final address in case we have a hardware ++ * issue that requires alignment for performance reasons. + */ +- addr = PAGE_ALIGN(addr); + addr = align_vdso_addr(addr); + + return addr; diff --git a/debian/patches/series b/debian/patches/series index 4dd02191d..506d74a5a 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -486,3 +486,5 @@ debian/arm-thread_info-fix-abi-change-in-3.16.7-ckt3.patch debian/pci-fix-abi-change-in-3.16.7-ckt3.patch debian/vfs-avoid-abi-change-for-dentry-union-changes.patch debian/userns-fix-abi-change-in-3.16.7-ckt4.patch +bugfix/all/netfilter-conntrack-disable-generic-tracking-for-kno.patch +bugfix/x86/x86_64-vdso-fix-the-vdso-address-randomization-algor.patch