diff options
author | Leonardo Arena <rnalrd@alpinelinux.org> | 2014-09-15 07:47:46 +0000 |
---|---|---|
committer | Leonardo Arena <rnalrd@alpinelinux.org> | 2014-09-15 07:47:54 +0000 |
commit | 1ef3fa5b3301483540b0df259d240fddda3606a4 (patch) | |
tree | 72f6d19146da3cab7bc5a3faab8f888923c5a80b | |
parent | 2ba05c483c3b74eba64a8b09f9e24406a1b7f1c6 (diff) | |
download | aports-1ef3fa5b3301483540b0df259d240fddda3606a4.tar.bz2 aports-1ef3fa5b3301483540b0df259d240fddda3606a4.tar.xz |
main/linux-virt-grsec: upgrade to 3.14.18
-rw-r--r-- | main/linux-virt-grsec/APKBUILD | 16 | ||||
-rw-r--r-- | main/linux-virt-grsec/grsecurity-3.0-3.14.18-201409141906.patch (renamed from main/linux-virt-grsec/grsecurity-3.0-3.14.16-201408110024.patch) | 3452 |
2 files changed, 2187 insertions, 1281 deletions
diff --git a/main/linux-virt-grsec/APKBUILD b/main/linux-virt-grsec/APKBUILD index 057f0bab38..a21ed668df 100644 --- a/main/linux-virt-grsec/APKBUILD +++ b/main/linux-virt-grsec/APKBUILD @@ -3,7 +3,7 @@ _flavor=virt-grsec pkgname=linux-${_flavor} -pkgver=3.14.16 +pkgver=3.14.18 case $pkgver in *.*.*) _kernver=${pkgver%.*};; *.*) _kernver=${pkgver};; @@ -18,7 +18,7 @@ _config=${config:-kernelconfig.${CARCH}} install= source="http://ftp.kernel.org/pub/linux/kernel/v3.x/linux-$_kernver.tar.xz http://ftp.kernel.org/pub/linux/kernel/v3.x/patch-$pkgver.xz - grsecurity-3.0-$pkgver-201408110024.patch + grsecurity-3.0-$pkgver-201409141906.patch fix-memory-map-for-PIE-applications.patch imx6q-no-unclocked-sleep.patch @@ -146,22 +146,22 @@ dev() { } md5sums="b621207b3f6ecbb67db18b13258f8ea8 linux-3.14.tar.xz -0c17d6e79e240062a36d4a71a2f7d1f2 patch-3.14.16.xz -cba8b3e01874c01f982a360cc3aad33f grsecurity-3.0-3.14.16-201408110024.patch +f00741b35127573c3cf085fc43f6e3f0 patch-3.14.18.xz +eb7a53b063df0e0018014049a08f5b40 grsecurity-3.0-3.14.18-201409141906.patch c6a4ae7e8ca6159e1631545515805216 fix-memory-map-for-PIE-applications.patch 1a307fc1d63231bf01d22493a4f14378 imx6q-no-unclocked-sleep.patch 6b30dd8284f37ecc244d556bebf32046 kernelconfig.x86 8df8378d305bdd302b01293ff44e982d kernelconfig.x86_64" sha256sums="61558aa490855f42b6340d1a1596be47454909629327c49a5e4e10268065dffa linux-3.14.tar.xz -3d3e79fd9795812f293aa38799c056aaea0f14da8294b31067f7768e9f38db2d patch-3.14.16.xz -e27fc08381e4937347b426e5f68149a0917dce79ef4f962b106ae158cdb4a619 grsecurity-3.0-3.14.16-201408110024.patch +3723d8d91e1bba0ed57a4951e8089ebfaa21ac186c3b729b4d2bad2da3eaed9f patch-3.14.18.xz +a9f82ac307226ea1726e7c7e904627e69ee8016985b73fd4cb8dec4f5768b222 grsecurity-3.0-3.14.18-201409141906.patch 500f3577310be52e87b9fecdc2e9c4ca43210fd97d69089f9005d484563f74c7 fix-memory-map-for-PIE-applications.patch 21179fbb22a5b74af0a609350ae1a170e232908572b201d02e791d2ce0a685d3 imx6q-no-unclocked-sleep.patch 5e06e22ca723e50ae9f4bfabdda2e738f7b28cbbfe77b6be295285d6cd75c916 kernelconfig.x86 0ec1e1eb4445bd9751cb98a55afd4a430bed08e8d8c3c0a107d2f14ec5746dd2 kernelconfig.x86_64" sha512sums="5730d83a7a81134c1e77c0bf89e42dee4f8251ad56c1ac2be20c59e26fdfaa7bea55f277e7af156b637f22e1584914a46089af85039177cb43485089c74ac26e linux-3.14.tar.xz -3004ce119ee9d6a13c8d1af6c3e1bd96794c89a98e914c0a0d80ff96c2a6f41ed3d2108aa86312d4b08646a38c9b47478c136252418a4964476b624e5e1fae70 patch-3.14.16.xz -f4a1dec548fb2bb2791d3b4a3e53a4f5f52fef95cd81e4d2dac0749474ff646b51b7f06eb9d83b27c9882e803164f7e60139d9781b144a7eba0819d565cf23b3 grsecurity-3.0-3.14.16-201408110024.patch +c7c5b281986819cb69592cc4c2b7c7d79f34aa86f21db1dd64b795dda79b5f9df95626dada5c8e0613c58d8d7979f37baf0a87cd458f340018ce61b42e4eb6c5 patch-3.14.18.xz +ff711fc291a3a795a1421936f0e3168ef8a6b92bcad21f9b7a1468945ee33cf9dcb3e56a5424be99af4cc660bd00e1770812ee2beb0fad9b34dd610558bd9cd9 grsecurity-3.0-3.14.18-201409141906.patch 4665c56ae1bbac311f9205d64918e84ee8b01d47d6e2396ff6b8adfb10aada7f7254531ce62e31edbb65c2a54a830f09ad05d314dfcd75d6272f4068945ad7c7 fix-memory-map-for-PIE-applications.patch 87d1ad59732f265a5b0db54490dc1762c14ea4b868e7eb1aedc3ce57b48046de7bbc08cf5cfcf6f1380fa84063b0edb16ba3d5e3c5670be9bbb229275c88b221 imx6q-no-unclocked-sleep.patch 29dc4bbde6052bb16200d87b7137717a053ad3c716a305a51d2b523531f35c1a7e144099f7a251c85849c9117a65ed961262dd314e0832f58750f489aeb1440e kernelconfig.x86 diff --git a/main/linux-virt-grsec/grsecurity-3.0-3.14.16-201408110024.patch b/main/linux-virt-grsec/grsecurity-3.0-3.14.18-201409141906.patch index cd58a6f54d..54a332ad20 100644 --- a/main/linux-virt-grsec/grsecurity-3.0-3.14.16-201408110024.patch +++ b/main/linux-virt-grsec/grsecurity-3.0-3.14.18-201409141906.patch @@ -287,7 +287,7 @@ index 7116fda..d8ed6e8 100644 pcd. [PARIDE] diff --git a/Makefile b/Makefile -index 8b22e24..7f4d29b 100644 +index 05279d4..c24e149 100644 --- a/Makefile +++ b/Makefile @@ -244,8 +244,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ @@ -876,7 +876,7 @@ index 4733d32..b142a40 100644 kexec is a system call that implements the ability to shutdown your current kernel, and to start another kernel. It is like a reboot diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h -index 62d2cb5..09d45e3 100644 +index 62d2cb5..0d7f7f5 100644 --- a/arch/arm/include/asm/atomic.h +++ b/arch/arm/include/asm/atomic.h @@ -18,17 +18,35 @@ @@ -1379,7 +1379,7 @@ index 62d2cb5..09d45e3 100644 " sbc %R0, %R0, %R4\n" " strexd %1, %0, %H0, [%3]\n" " teq %1, #0\n" -@@ -344,16 +691,29 @@ static inline long long atomic64_sub_return(long long i, atomic64_t *v) +@@ -344,10 +691,25 @@ static inline long long atomic64_sub_return(long long i, atomic64_t *v) __asm__ __volatile__("@ atomic64_sub_return\n" "1: ldrexd %0, %H0, [%3]\n" " subs %Q0, %Q0, %Q4\n" @@ -1406,13 +1406,7 @@ index 62d2cb5..09d45e3 100644 : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) : "r" (&v->counter), "r" (i) : "cc"); - -- smp_mb(); -- - return result; - } - -@@ -382,6 +742,31 @@ static inline long long atomic64_cmpxchg(atomic64_t *ptr, long long old, +@@ -382,6 +744,31 @@ static inline long long atomic64_cmpxchg(atomic64_t *ptr, long long old, return oldval; } @@ -1444,7 +1438,7 @@ index 62d2cb5..09d45e3 100644 static inline long long atomic64_xchg(atomic64_t *ptr, long long new) { long long result; -@@ -406,20 +791,34 @@ static inline long long atomic64_xchg(atomic64_t *ptr, long long new) +@@ -406,20 +793,34 @@ static inline long long atomic64_xchg(atomic64_t *ptr, long long new) static inline long long atomic64_dec_if_positive(atomic64_t *v) { long long result; @@ -1485,7 +1479,7 @@ index 62d2cb5..09d45e3 100644 : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) : "r" (&v->counter) : "cc"); -@@ -442,13 +841,25 @@ static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u) +@@ -442,13 +843,25 @@ static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u) " teq %0, %5\n" " teqeq %H0, %H5\n" " moveq %1, #0\n" @@ -1514,7 +1508,7 @@ index 62d2cb5..09d45e3 100644 : "=&r" (val), "+r" (ret), "=&r" (tmp), "+Qo" (v->counter) : "r" (&v->counter), "r" (u), "r" (a) : "cc"); -@@ -461,10 +872,13 @@ static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u) +@@ -461,10 +874,13 @@ static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u) #define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0) #define atomic64_inc(v) atomic64_add(1LL, (v)) @@ -3271,7 +3265,7 @@ index 7bcee5c..e2f3249 100644 __data_loc = .; #endif diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c -index bd18bb8..87ede26 100644 +index bd18bb8..2bf342f 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -57,7 +57,7 @@ static unsigned long hyp_default_vectors; @@ -3310,6 +3304,15 @@ index bd18bb8..87ede26 100644 kvm->arch.vmid = kvm_next_vmid; kvm_next_vmid++; +@@ -1033,7 +1033,7 @@ static void check_kvm_target_cpu(void *ret) + /** + * Initialize Hyp-mode and memory mappings on all CPUs. + */ +-int kvm_arch_init(void *opaque) ++int kvm_arch_init(const void *opaque) + { + int err; + int ret, cpu; diff --git a/arch/arm/lib/clear_user.S b/arch/arm/lib/clear_user.S index 14a0d98..7771a7d 100644 --- a/arch/arm/lib/clear_user.S @@ -3643,7 +3646,7 @@ index 78c02b3..c94109a 100644 struct omap_device *omap_device_alloc(struct platform_device *pdev, struct omap_hwmod **ohs, int oh_cnt); diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c -index 66c60fe..c78950d 100644 +index c914b00..8a653a7 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -194,10 +194,10 @@ struct omap_hwmod_soc_ops { @@ -5040,6 +5043,17 @@ index 0c8e553..112d734 100644 help kexec is a system call that implements the ability to shutdown your current kernel, and to start another kernel. It is like a reboot +diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile +index f37238f..810b95f 100644 +--- a/arch/ia64/Makefile ++++ b/arch/ia64/Makefile +@@ -99,5 +99,6 @@ endef + archprepare: make_nr_irqs_h FORCE + PHONY += make_nr_irqs_h FORCE + ++make_nr_irqs_h: KBUILD_CFLAGS := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS)) + make_nr_irqs_h: FORCE + $(Q)$(MAKE) $(build)=arch/ia64/kernel include/generated/nr-irqs.h diff --git a/arch/ia64/include/asm/atomic.h b/arch/ia64/include/asm/atomic.h index 6e6fe18..a6ae668 100644 --- a/arch/ia64/include/asm/atomic.h @@ -7136,6 +7150,19 @@ index 81e6ae0..6ab6e79 100644 info.si_code = FPE_INTOVF; info.si_signo = SIGFPE; +diff --git a/arch/mips/kvm/kvm_mips.c b/arch/mips/kvm/kvm_mips.c +index 3e0ff8d..9eafbf0b 100644 +--- a/arch/mips/kvm/kvm_mips.c ++++ b/arch/mips/kvm/kvm_mips.c +@@ -832,7 +832,7 @@ long kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) + return r; + } + +-int kvm_arch_init(void *opaque) ++int kvm_arch_init(const void *opaque) + { + int ret; + diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c index becc42b..9e43d4b 100644 --- a/arch/mips/mm/fault.c @@ -9883,142 +9910,6 @@ index 502f632..da1917f 100644 #define __S100 PAGE_READONLY #define __S101 PAGE_READONLY #define __S110 PAGE_SHARED -diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h -index 0f9e945..a949e55 100644 ---- a/arch/sparc/include/asm/pgtable_64.h -+++ b/arch/sparc/include/asm/pgtable_64.h -@@ -71,6 +71,23 @@ - - #include <linux/sched.h> - -+extern unsigned long sparc64_valid_addr_bitmap[]; -+ -+/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ -+static inline bool __kern_addr_valid(unsigned long paddr) -+{ -+ if ((paddr >> MAX_PHYS_ADDRESS_BITS) != 0UL) -+ return false; -+ return test_bit(paddr >> ILOG2_4MB, sparc64_valid_addr_bitmap); -+} -+ -+static inline bool kern_addr_valid(unsigned long addr) -+{ -+ unsigned long paddr = __pa(addr); -+ -+ return __kern_addr_valid(paddr); -+} -+ - /* Entries per page directory level. */ - #define PTRS_PER_PTE (1UL << (PAGE_SHIFT-3)) - #define PTRS_PER_PMD (1UL << PMD_BITS) -@@ -79,9 +96,12 @@ - /* Kernel has a separate 44bit address space. */ - #define FIRST_USER_ADDRESS 0 - --#define pte_ERROR(e) __builtin_trap() --#define pmd_ERROR(e) __builtin_trap() --#define pgd_ERROR(e) __builtin_trap() -+#define pmd_ERROR(e) \ -+ pr_err("%s:%d: bad pmd %p(%016lx) seen at (%pS)\n", \ -+ __FILE__, __LINE__, &(e), pmd_val(e), __builtin_return_address(0)) -+#define pgd_ERROR(e) \ -+ pr_err("%s:%d: bad pgd %p(%016lx) seen at (%pS)\n", \ -+ __FILE__, __LINE__, &(e), pgd_val(e), __builtin_return_address(0)) - - #endif /* !(__ASSEMBLY__) */ - -@@ -633,7 +653,7 @@ static inline unsigned long pmd_large(pmd_t pmd) - { - pte_t pte = __pte(pmd_val(pmd)); - -- return (pte_val(pte) & _PAGE_PMD_HUGE) && pte_present(pte); -+ return pte_val(pte) & _PAGE_PMD_HUGE; - } - - #ifdef CONFIG_TRANSPARENT_HUGEPAGE -@@ -719,20 +739,6 @@ static inline pmd_t pmd_mkwrite(pmd_t pmd) - return __pmd(pte_val(pte)); - } - --static inline pmd_t pmd_mknotpresent(pmd_t pmd) --{ -- unsigned long mask; -- -- if (tlb_type == hypervisor) -- mask = _PAGE_PRESENT_4V; -- else -- mask = _PAGE_PRESENT_4U; -- -- pmd_val(pmd) &= ~mask; -- -- return pmd; --} -- - static inline pmd_t pmd_mksplitting(pmd_t pmd) - { - pte_t pte = __pte(pmd_val(pmd)); -@@ -757,6 +763,20 @@ static inline int pmd_present(pmd_t pmd) - - #define pmd_none(pmd) (!pmd_val(pmd)) - -+/* pmd_bad() is only called on non-trans-huge PMDs. Our encoding is -+ * very simple, it's just the physical address. PTE tables are of -+ * size PAGE_SIZE so make sure the sub-PAGE_SIZE bits are clear and -+ * the top bits outside of the range of any physical address size we -+ * support are clear as well. We also validate the physical itself. -+ */ -+#define pmd_bad(pmd) ((pmd_val(pmd) & ~PAGE_MASK) || \ -+ !__kern_addr_valid(pmd_val(pmd))) -+ -+#define pud_none(pud) (!pud_val(pud)) -+ -+#define pud_bad(pud) ((pud_val(pud) & ~PAGE_MASK) || \ -+ !__kern_addr_valid(pud_val(pud))) -+ - #ifdef CONFIG_TRANSPARENT_HUGEPAGE - extern void set_pmd_at(struct mm_struct *mm, unsigned long addr, - pmd_t *pmdp, pmd_t pmd); -@@ -790,10 +810,7 @@ static inline unsigned long __pmd_page(pmd_t pmd) - #define pud_page_vaddr(pud) \ - ((unsigned long) __va(pud_val(pud))) - #define pud_page(pud) virt_to_page((void *)pud_page_vaddr(pud)) --#define pmd_bad(pmd) (0) - #define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0UL) --#define pud_none(pud) (!pud_val(pud)) --#define pud_bad(pud) (0) - #define pud_present(pud) (pud_val(pud) != 0U) - #define pud_clear(pudp) (pud_val(*(pudp)) = 0UL) - -@@ -893,6 +910,10 @@ extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *); - extern void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr, - pmd_t *pmd); - -+#define __HAVE_ARCH_PMDP_INVALIDATE -+extern void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, -+ pmd_t *pmdp); -+ - #define __HAVE_ARCH_PGTABLE_DEPOSIT - extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, - pgtable_t pgtable); -@@ -919,18 +940,6 @@ extern unsigned long pte_file(pte_t); - extern pte_t pgoff_to_pte(unsigned long); - #define PTE_FILE_MAX_BITS (64UL - PAGE_SHIFT - 1UL) - --extern unsigned long sparc64_valid_addr_bitmap[]; -- --/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ --static inline bool kern_addr_valid(unsigned long addr) --{ -- unsigned long paddr = __pa(addr); -- -- if ((paddr >> 41UL) != 0UL) -- return false; -- return test_bit(paddr >> 22, sparc64_valid_addr_bitmap); --} -- - extern int page_in_phys_avail(unsigned long paddr); - - /* diff --git a/arch/sparc/include/asm/pgtsrmmu.h b/arch/sparc/include/asm/pgtsrmmu.h index 79da178..c2eede8 100644 --- a/arch/sparc/include/asm/pgtsrmmu.h @@ -10196,20 +10087,6 @@ index a5f01ac..703b554 100644 /* * Thread-synchronous status. * -diff --git a/arch/sparc/include/asm/tsb.h b/arch/sparc/include/asm/tsb.h -index 2230f80..90916f9 100644 ---- a/arch/sparc/include/asm/tsb.h -+++ b/arch/sparc/include/asm/tsb.h -@@ -171,7 +171,8 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; - andcc REG1, REG2, %g0; \ - be,pt %xcc, 700f; \ - sethi %hi(4 * 1024 * 1024), REG2; \ -- andn REG1, REG2, REG1; \ -+ brgez,pn REG1, FAIL_LABEL; \ -+ andn REG1, REG2, REG1; \ - and VADDR, REG2, REG2; \ - brlz,pt REG1, PTE_LABEL; \ - or REG1, REG2, REG1; \ diff --git a/arch/sparc/include/asm/uaccess.h b/arch/sparc/include/asm/uaccess.h index 0167d26..767bb0c 100644 --- a/arch/sparc/include/asm/uaccess.h @@ -10458,7 +10335,7 @@ index c13c9f2..d572c34 100644 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c -index b085311..6f885f7 100644 +index 8416d7f..f83823c 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c @@ -870,8 +870,8 @@ extern unsigned long xcall_flush_dcache_page_cheetah; @@ -10958,37 +10835,10 @@ index 4ced92f..965eeed 100644 } EXPORT_SYMBOL(die_if_kernel); diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c -index 3c1a7cb..9046547 100644 +index 35ab8b6..9046547 100644 --- a/arch/sparc/kernel/unaligned_64.c +++ b/arch/sparc/kernel/unaligned_64.c -@@ -166,17 +166,23 @@ static unsigned long *fetch_reg_addr(unsigned int reg, struct pt_regs *regs) - unsigned long compute_effective_address(struct pt_regs *regs, - unsigned int insn, unsigned int rd) - { -+ int from_kernel = (regs->tstate & TSTATE_PRIV) != 0; - unsigned int rs1 = (insn >> 14) & 0x1f; - unsigned int rs2 = insn & 0x1f; -- int from_kernel = (regs->tstate & TSTATE_PRIV) != 0; -+ unsigned long addr; - - if (insn & 0x2000) { - maybe_flush_windows(rs1, 0, rd, from_kernel); -- return (fetch_reg(rs1, regs) + sign_extend_imm13(insn)); -+ addr = (fetch_reg(rs1, regs) + sign_extend_imm13(insn)); - } else { - maybe_flush_windows(rs1, rs2, rd, from_kernel); -- return (fetch_reg(rs1, regs) + fetch_reg(rs2, regs)); -+ addr = (fetch_reg(rs1, regs) + fetch_reg(rs2, regs)); - } -+ -+ if (!from_kernel && test_thread_flag(TIF_32BIT)) -+ addr &= 0xffffffff; -+ -+ return addr; - } - - /* This is just to make gcc think die_if_kernel does return... */ -@@ -289,7 +295,7 @@ static void log_unaligned(struct pt_regs *regs) +@@ -295,7 +295,7 @@ static void log_unaligned(struct pt_regs *regs) static DEFINE_RATELIMIT_STATE(ratelimit, 5 * HZ, 5); if (__ratelimit(&ratelimit)) { @@ -11578,7 +11428,7 @@ index 59dbd46..1dd7f5e 100644 if (!(vma->vm_flags & (VM_READ | VM_EXEC))) goto bad_area; diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c -index 69bb818..3542236 100644 +index 4ced3fc..234f1e4 100644 --- a/arch/sparc/mm/fault_64.c +++ b/arch/sparc/mm/fault_64.c @@ -22,6 +22,9 @@ @@ -11600,124 +11450,7 @@ index 69bb818..3542236 100644 printk(KERN_CRIT "OOPS: Fault was to vaddr[%lx]\n", vaddr); dump_stack(); unhandled_fault(regs->tpc, current, regs); -@@ -96,38 +99,51 @@ static unsigned int get_user_insn(unsigned long tpc) - pte_t *ptep, pte; - unsigned long pa; - u32 insn = 0; -- unsigned long pstate; - -- if (pgd_none(*pgdp)) -- goto outret; -+ if (pgd_none(*pgdp) || unlikely(pgd_bad(*pgdp))) -+ goto out; - pudp = pud_offset(pgdp, tpc); -- if (pud_none(*pudp)) -- goto outret; -- pmdp = pmd_offset(pudp, tpc); -- if (pmd_none(*pmdp)) -- goto outret; -+ if (pud_none(*pudp) || unlikely(pud_bad(*pudp))) -+ goto out; - - /* This disables preemption for us as well. */ -- __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate)); -- __asm__ __volatile__("wrpr %0, %1, %%pstate" -- : : "r" (pstate), "i" (PSTATE_IE)); -- ptep = pte_offset_map(pmdp, tpc); -- pte = *ptep; -- if (!pte_present(pte)) -- goto out; -+ local_irq_disable(); - -- pa = (pte_pfn(pte) << PAGE_SHIFT); -- pa += (tpc & ~PAGE_MASK); -+ pmdp = pmd_offset(pudp, tpc); -+ if (pmd_none(*pmdp) || unlikely(pmd_bad(*pmdp))) -+ goto out_irq_enable; - -- /* Use phys bypass so we don't pollute dtlb/dcache. */ -- __asm__ __volatile__("lduwa [%1] %2, %0" -- : "=r" (insn) -- : "r" (pa), "i" (ASI_PHYS_USE_EC)); -+#ifdef CONFIG_TRANSPARENT_HUGEPAGE -+ if (pmd_trans_huge(*pmdp)) { -+ if (pmd_trans_splitting(*pmdp)) -+ goto out_irq_enable; - -+ pa = pmd_pfn(*pmdp) << PAGE_SHIFT; -+ pa += tpc & ~HPAGE_MASK; -+ -+ /* Use phys bypass so we don't pollute dtlb/dcache. */ -+ __asm__ __volatile__("lduwa [%1] %2, %0" -+ : "=r" (insn) -+ : "r" (pa), "i" (ASI_PHYS_USE_EC)); -+ } else -+#endif -+ { -+ ptep = pte_offset_map(pmdp, tpc); -+ pte = *ptep; -+ if (pte_present(pte)) { -+ pa = (pte_pfn(pte) << PAGE_SHIFT); -+ pa += (tpc & ~PAGE_MASK); -+ -+ /* Use phys bypass so we don't pollute dtlb/dcache. */ -+ __asm__ __volatile__("lduwa [%1] %2, %0" -+ : "=r" (insn) -+ : "r" (pa), "i" (ASI_PHYS_USE_EC)); -+ } -+ pte_unmap(ptep); -+ } -+out_irq_enable: -+ local_irq_enable(); - out: -- pte_unmap(ptep); -- __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate)); --outret: - return insn; - } - -@@ -153,7 +169,8 @@ show_signal_msg(struct pt_regs *regs, int sig, int code, - } - - static void do_fault_siginfo(int code, int sig, struct pt_regs *regs, -- unsigned int insn, int fault_code) -+ unsigned long fault_addr, unsigned int insn, -+ int fault_code) - { - unsigned long addr; - siginfo_t info; -@@ -161,10 +178,18 @@ static void do_fault_siginfo(int code, int sig, struct pt_regs *regs, - info.si_code = code; - info.si_signo = sig; - info.si_errno = 0; -- if (fault_code & FAULT_CODE_ITLB) -+ if (fault_code & FAULT_CODE_ITLB) { - addr = regs->tpc; -- else -- addr = compute_effective_address(regs, insn, 0); -+ } else { -+ /* If we were able to probe the faulting instruction, use it -+ * to compute a precise fault address. Otherwise use the fault -+ * time provided address which may only have page granularity. -+ */ -+ if (insn) -+ addr = compute_effective_address(regs, insn, 0); -+ else -+ addr = fault_addr; -+ } - info.si_addr = (void __user *) addr; - info.si_trapno = 0; - -@@ -239,7 +264,7 @@ static void __kprobes do_kernel_fault(struct pt_regs *regs, int si_code, - /* The si_code was set to make clear whether - * this was a SEGV_MAPERR or SEGV_ACCERR fault. - */ -- do_fault_siginfo(si_code, SIGSEGV, regs, insn, fault_code); -+ do_fault_siginfo(si_code, SIGSEGV, regs, address, insn, fault_code); - return; - } - -@@ -271,6 +296,466 @@ static void noinline __kprobes bogus_32bit_fault_address(struct pt_regs *regs, +@@ -281,6 +284,466 @@ static void noinline __kprobes bogus_32bit_fault_tpc(struct pt_regs *regs) show_regs(regs); } @@ -12184,7 +11917,7 @@ index 69bb818..3542236 100644 asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) { enum ctx_state prev_state = exception_enter(); -@@ -344,6 +829,29 @@ retry: +@@ -352,6 +815,29 @@ retry: if (!vma) goto bad_area; @@ -12214,28 +11947,6 @@ index 69bb818..3542236 100644 /* Pure DTLB misses do not tell us whether the fault causing * load/store/atomic was a write or not, it only says that there * was no match. So in such a case we (carefully) read the -@@ -525,7 +1033,7 @@ do_sigbus: - * Send a sigbus, regardless of whether we were in kernel - * or user mode. - */ -- do_fault_siginfo(BUS_ADRERR, SIGBUS, regs, insn, fault_code); -+ do_fault_siginfo(BUS_ADRERR, SIGBUS, regs, address, insn, fault_code); - - /* Kernel mode? Handle exceptions or die */ - if (regs->tstate & TSTATE_PRIV) -diff --git a/arch/sparc/mm/gup.c b/arch/sparc/mm/gup.c -index c4d3da6..1aed043 100644 ---- a/arch/sparc/mm/gup.c -+++ b/arch/sparc/mm/gup.c -@@ -73,7 +73,7 @@ static int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr, - struct page *head, *page, *tail; - int refs; - -- if (!pmd_large(pmd)) -+ if (!(pmd_val(pmd) & _PAGE_VALID)) - return 0; - - if (write && !pmd_write(pmd)) diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c index d329537..2c3746a 100644 --- a/arch/sparc/mm/hugetlbpage.c @@ -12343,7 +12054,7 @@ index d329537..2c3746a 100644 pte_t *huge_pte_alloc(struct mm_struct *mm, diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c -index eafbc65..5a8070d 100644 +index 9686224..dfbdb10 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c @@ -188,9 +188,9 @@ unsigned long sparc64_kern_sec_context __read_mostly; @@ -12367,7 +12078,7 @@ index eafbc65..5a8070d 100644 #endif #ifdef DCACHE_ALIASING_POSSIBLE -@@ -466,10 +466,10 @@ void mmu_info(struct seq_file *m) +@@ -470,10 +470,10 @@ void mmu_info(struct seq_file *m) #ifdef CONFIG_DEBUG_DCFLUSH seq_printf(m, "DCPageFlushes\t: %d\n", @@ -12380,67 +12091,6 @@ index eafbc65..5a8070d 100644 #endif /* CONFIG_SMP */ #endif /* CONFIG_DEBUG_DCFLUSH */ } -diff --git a/arch/sparc/mm/tlb.c b/arch/sparc/mm/tlb.c -index b12cb5e..b89aba2 100644 ---- a/arch/sparc/mm/tlb.c -+++ b/arch/sparc/mm/tlb.c -@@ -134,7 +134,7 @@ no_cache_flush: - - #ifdef CONFIG_TRANSPARENT_HUGEPAGE - static void tlb_batch_pmd_scan(struct mm_struct *mm, unsigned long vaddr, -- pmd_t pmd, bool exec) -+ pmd_t pmd) - { - unsigned long end; - pte_t *pte; -@@ -142,8 +142,11 @@ static void tlb_batch_pmd_scan(struct mm_struct *mm, unsigned long vaddr, - pte = pte_offset_map(&pmd, vaddr); - end = vaddr + HPAGE_SIZE; - while (vaddr < end) { -- if (pte_val(*pte) & _PAGE_VALID) -+ if (pte_val(*pte) & _PAGE_VALID) { -+ bool exec = pte_exec(*pte); -+ - tlb_batch_add_one(mm, vaddr, exec); -+ } - pte++; - vaddr += PAGE_SIZE; - } -@@ -177,19 +180,30 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr, - } - - if (!pmd_none(orig)) { -- pte_t orig_pte = __pte(pmd_val(orig)); -- bool exec = pte_exec(orig_pte); -- - addr &= HPAGE_MASK; - if (pmd_trans_huge(orig)) { -+ pte_t orig_pte = __pte(pmd_val(orig)); -+ bool exec = pte_exec(orig_pte); -+ - tlb_batch_add_one(mm, addr, exec); - tlb_batch_add_one(mm, addr + REAL_HPAGE_SIZE, exec); - } else { -- tlb_batch_pmd_scan(mm, addr, orig, exec); -+ tlb_batch_pmd_scan(mm, addr, orig); - } - } - } - -+void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, -+ pmd_t *pmdp) -+{ -+ pmd_t entry = *pmdp; -+ -+ pmd_val(entry) &= ~_PAGE_VALID; -+ -+ set_pmd_at(vma->vm_mm, address, pmdp, entry); -+ flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE); -+} -+ - void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, - pgtable_t pgtable) - { diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig index b3692ce..e4517c9 100644 --- a/arch/tile/Kconfig @@ -12646,10 +12296,18 @@ index ad8f795..2c7eec6 100644 /* * Memory returned by kmalloc() may be used for DMA, so we must make diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig -index c718d9f..511e6fa 100644 +index e409891..8ec65be 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig -@@ -126,7 +126,7 @@ config X86 +@@ -22,6 +22,7 @@ config X86_64 + config X86 + def_bool y + select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS ++ select ARCH_HAS_FAST_MULTIPLIER + select ARCH_MIGHT_HAVE_PC_PARPORT + select ARCH_MIGHT_HAVE_PC_SERIO + select HAVE_AOUT if X86_32 +@@ -126,7 +127,7 @@ config X86 select RTC_LIB select HAVE_DEBUG_STACKOVERFLOW select HAVE_IRQ_EXIT_ON_IRQ_STACK if X86_64 @@ -12658,7 +12316,7 @@ index c718d9f..511e6fa 100644 select ARCH_SUPPORTS_ATOMIC_RMW config INSTRUCTION_DECODER -@@ -252,7 +252,7 @@ config X86_HT +@@ -252,7 +253,7 @@ config X86_HT config X86_32_LAZY_GS def_bool y @@ -12667,7 +12325,7 @@ index c718d9f..511e6fa 100644 config ARCH_HWEIGHT_CFLAGS string -@@ -590,6 +590,7 @@ config SCHED_OMIT_FRAME_POINTER +@@ -590,6 +591,7 @@ config SCHED_OMIT_FRAME_POINTER menuconfig HYPERVISOR_GUEST bool "Linux guest support" @@ -12675,7 +12333,7 @@ index c718d9f..511e6fa 100644 ---help--- Say Y here to enable options for running Linux under various hyper- visors. This option enables basic hypervisor detection and platform -@@ -1129,7 +1130,7 @@ choice +@@ -1129,7 +1131,7 @@ choice config NOHIGHMEM bool "off" @@ -12684,7 +12342,7 @@ index c718d9f..511e6fa 100644 ---help--- Linux can use up to 64 Gigabytes of physical memory on x86 systems. However, the address space of 32-bit x86 processors is only 4 -@@ -1166,7 +1167,7 @@ config NOHIGHMEM +@@ -1166,7 +1168,7 @@ config NOHIGHMEM config HIGHMEM4G bool "4GB" @@ -12693,7 +12351,7 @@ index c718d9f..511e6fa 100644 ---help--- Select this if you have a 32-bit processor and between 1 and 4 gigabytes of physical RAM. -@@ -1219,7 +1220,7 @@ config PAGE_OFFSET +@@ -1219,7 +1221,7 @@ config PAGE_OFFSET hex default 0xB0000000 if VMSPLIT_3G_OPT default 0x80000000 if VMSPLIT_2G @@ -12702,7 +12360,7 @@ index c718d9f..511e6fa 100644 default 0x40000000 if VMSPLIT_1G default 0xC0000000 depends on X86_32 -@@ -1623,6 +1624,7 @@ source kernel/Kconfig.hz +@@ -1624,6 +1626,7 @@ source kernel/Kconfig.hz config KEXEC bool "kexec system call" @@ -12710,7 +12368,7 @@ index c718d9f..511e6fa 100644 ---help--- kexec is a system call that implements the ability to shutdown your current kernel, and to start another kernel. It is like a reboot -@@ -1774,7 +1776,9 @@ config X86_NEED_RELOCS +@@ -1775,7 +1778,9 @@ config X86_NEED_RELOCS config PHYSICAL_ALIGN hex "Alignment value to which kernel should be aligned" @@ -12721,7 +12379,7 @@ index c718d9f..511e6fa 100644 range 0x2000 0x1000000 if X86_32 range 0x200000 0x1000000 if X86_64 ---help--- -@@ -1854,9 +1858,10 @@ config DEBUG_HOTPLUG_CPU0 +@@ -1855,9 +1860,10 @@ config DEBUG_HOTPLUG_CPU0 If unsure, say N. config COMPAT_VDSO @@ -16139,7 +15797,7 @@ index 69bbb48..32517fe 100644 #define smp_load_acquire(p) \ diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h -index 9fc1af7..776d75a 100644 +index 9fc1af7..98cab0b 100644 --- a/arch/x86/include/asm/bitops.h +++ b/arch/x86/include/asm/bitops.h @@ -49,7 +49,7 @@ @@ -16223,6 +15881,15 @@ index 9fc1af7..776d75a 100644 { int bitpos = -1; /* +@@ -499,8 +499,6 @@ static __always_inline int fls64(__u64 x) + + #include <asm-generic/bitops/sched.h> + +-#define ARCH_HAS_FAST_MULTIPLIER 1 +- + #include <asm/arch_hweight.h> + + #include <asm-generic/bitops/const_hweight.h> diff --git a/arch/x86/include/asm/boot.h b/arch/x86/include/asm/boot.h index 4fa687a..60f2d39 100644 --- a/arch/x86/include/asm/boot.h @@ -18545,7 +18212,7 @@ index b39e194..9d44fd1 100644 /* diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h -index fdedd38..95c02c2 100644 +index fdedd38..129b180 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -128,7 +128,7 @@ struct cpuinfo_x86 { @@ -18567,7 +18234,7 @@ index fdedd38..95c02c2 100644 +#define INVPCID_SINGLE_ADDRESS 0UL +#define INVPCID_SINGLE_CONTEXT 1UL +#define INVPCID_ALL_GLOBAL 2UL -+#define INVPCID_ALL_MONGLOBAL 3UL ++#define INVPCID_ALL_NONGLOBAL 3UL + +#define PCID_KERNEL 0UL +#define PCID_USER 1UL @@ -19672,7 +19339,7 @@ index e1940c0..ac50dd8 100644 #endif #endif /* _ASM_X86_THREAD_INFO_H */ diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h -index 04905bf..49203ca 100644 +index 04905bf..1178cdf 100644 --- a/arch/x86/include/asm/tlbflush.h +++ b/arch/x86/include/asm/tlbflush.h @@ -17,18 +17,44 @@ @@ -19683,7 +19350,7 @@ index 04905bf..49203ca 100644 + u64 descriptor[2]; + + descriptor[0] = PCID_KERNEL; -+ asm volatile(__ASM_INVPCID : : "d"(&descriptor), "a"(INVPCID_ALL_MONGLOBAL) : "memory"); ++ asm volatile(__ASM_INVPCID : : "d"(&descriptor), "a"(INVPCID_ALL_NONGLOBAL) : "memory"); + return; + } + @@ -23271,7 +22938,7 @@ index c5a9cb9..228d280 100644 /* diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S -index 03cd2a8..05a9aed 100644 +index 03cd2a8..d236ccb 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -60,6 +60,8 @@ @@ -24192,7 +23859,7 @@ index 03cd2a8..05a9aed 100644 je retint_kernel /* Interrupt came from user space */ -@@ -1027,12 +1500,16 @@ retint_swapgs: /* return to user-space */ +@@ -1027,12 +1500,35 @@ retint_swapgs: /* return to user-space */ * The iretq could re-enable interrupts: */ DISABLE_INTERRUPTS(CLBR_ANY) @@ -24205,11 +23872,30 @@ index 03cd2a8..05a9aed 100644 retint_restore_args: /* return to kernel space */ DISABLE_INTERRUPTS(CLBR_ANY) + pax_exit_kernel ++ ++#if defined(CONFIG_EFI) && defined(CONFIG_PAX_KERNEXEC) ++ /* This is a quirk to allow IRQs/NMIs/MCEs during early EFI setup, ++ * namely calling EFI runtime services with a phys mapping. We're ++ * starting off with NOPs and patch in the real instrumentation ++ * (BTS/OR) before starting any userland process; even before starting ++ * up the APs. ++ */ ++ .pushsection .altinstr_replacement, "a" ++ 601: pax_force_retaddr (RIP-ARGOFFSET) ++ 602: ++ .popsection ++ 603: .fill 602b-601b, 1, 0x90 ++ .pushsection .altinstructions, "a" ++ altinstruction_entry 603b, 601b, X86_FEATURE_ALWAYS, 602b-601b, 602b-601b ++ .popsection ++#else + pax_force_retaddr (RIP-ARGOFFSET) ++#endif ++ /* * The iretq could re-enable interrupts: */ -@@ -1145,7 +1622,7 @@ ENTRY(retint_kernel) +@@ -1145,7 +1641,7 @@ ENTRY(retint_kernel) jmp exit_intr #endif CFI_ENDPROC @@ -24218,7 +23904,7 @@ index 03cd2a8..05a9aed 100644 /* * If IRET takes a fault on the espfix stack, then we -@@ -1167,13 +1644,13 @@ __do_double_fault: +@@ -1167,13 +1663,13 @@ __do_double_fault: cmpq $native_irq_return_iret,%rax jne do_double_fault /* This shouldn't happen... */ movq PER_CPU_VAR(kernel_stack),%rax @@ -24234,7 +23920,7 @@ index 03cd2a8..05a9aed 100644 #else # define __do_double_fault do_double_fault #endif -@@ -1195,7 +1672,7 @@ ENTRY(\sym) +@@ -1195,7 +1691,7 @@ ENTRY(\sym) interrupt \do_sym jmp ret_from_intr CFI_ENDPROC @@ -24243,7 +23929,7 @@ index 03cd2a8..05a9aed 100644 .endm #ifdef CONFIG_TRACING -@@ -1283,7 +1760,7 @@ ENTRY(\sym) +@@ -1283,7 +1779,7 @@ ENTRY(\sym) call \do_sym jmp error_exit /* %ebx: no swapgs flag */ CFI_ENDPROC @@ -24252,7 +23938,7 @@ index 03cd2a8..05a9aed 100644 .endm .macro paranoidzeroentry sym do_sym -@@ -1301,10 +1778,10 @@ ENTRY(\sym) +@@ -1301,10 +1797,10 @@ ENTRY(\sym) call \do_sym jmp paranoid_exit /* %ebx: no swapgs flag */ CFI_ENDPROC @@ -24265,7 +23951,7 @@ index 03cd2a8..05a9aed 100644 .macro paranoidzeroentry_ist sym do_sym ist ENTRY(\sym) INTR_FRAME -@@ -1317,12 +1794,18 @@ ENTRY(\sym) +@@ -1317,12 +1813,18 @@ ENTRY(\sym) TRACE_IRQS_OFF_DEBUG movq %rsp,%rdi /* pt_regs pointer */ xorl %esi,%esi /* no error code */ @@ -24285,7 +23971,7 @@ index 03cd2a8..05a9aed 100644 .endm .macro errorentry sym do_sym -@@ -1340,7 +1823,7 @@ ENTRY(\sym) +@@ -1340,7 +1842,7 @@ ENTRY(\sym) call \do_sym jmp error_exit /* %ebx: no swapgs flag */ CFI_ENDPROC @@ -24294,7 +23980,7 @@ index 03cd2a8..05a9aed 100644 .endm #ifdef CONFIG_TRACING -@@ -1371,7 +1854,7 @@ ENTRY(\sym) +@@ -1371,7 +1873,7 @@ ENTRY(\sym) call \do_sym jmp paranoid_exit /* %ebx: no swapgs flag */ CFI_ENDPROC @@ -24303,7 +23989,7 @@ index 03cd2a8..05a9aed 100644 .endm zeroentry divide_error do_divide_error -@@ -1401,9 +1884,10 @@ gs_change: +@@ -1401,9 +1903,10 @@ gs_change: 2: mfence /* workaround */ SWAPGS popfq_cfi @@ -24315,7 +24001,7 @@ index 03cd2a8..05a9aed 100644 _ASM_EXTABLE(gs_change,bad_gs) .section .fixup,"ax" -@@ -1431,9 +1915,10 @@ ENTRY(do_softirq_own_stack) +@@ -1431,9 +1934,10 @@ ENTRY(do_softirq_own_stack) CFI_DEF_CFA_REGISTER rsp CFI_ADJUST_CFA_OFFSET -8 decl PER_CPU_VAR(irq_count) @@ -24327,7 +24013,7 @@ index 03cd2a8..05a9aed 100644 #ifdef CONFIG_XEN zeroentry xen_hypervisor_callback xen_do_hypervisor_callback -@@ -1471,7 +1956,7 @@ ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs) +@@ -1471,7 +1975,7 @@ ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs) decl PER_CPU_VAR(irq_count) jmp error_exit CFI_ENDPROC @@ -24336,7 +24022,7 @@ index 03cd2a8..05a9aed 100644 /* * Hypervisor uses this for application faults while it executes. -@@ -1530,7 +2015,7 @@ ENTRY(xen_failsafe_callback) +@@ -1530,7 +2034,7 @@ ENTRY(xen_failsafe_callback) SAVE_ALL jmp error_exit CFI_ENDPROC @@ -24345,7 +24031,7 @@ index 03cd2a8..05a9aed 100644 apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \ xen_hvm_callback_vector xen_evtchn_do_upcall -@@ -1582,18 +2067,33 @@ ENTRY(paranoid_exit) +@@ -1582,18 +2086,33 @@ ENTRY(paranoid_exit) DEFAULT_FRAME DISABLE_INTERRUPTS(CLBR_NONE) TRACE_IRQS_OFF_DEBUG @@ -24381,7 +24067,7 @@ index 03cd2a8..05a9aed 100644 jmp irq_return paranoid_userspace: GET_THREAD_INFO(%rcx) -@@ -1622,7 +2122,7 @@ paranoid_schedule: +@@ -1622,7 +2141,7 @@ paranoid_schedule: TRACE_IRQS_OFF jmp paranoid_userspace CFI_ENDPROC @@ -24390,7 +24076,7 @@ index 03cd2a8..05a9aed 100644 /* * Exception entry point. This expects an error code/orig_rax on the stack. -@@ -1649,12 +2149,23 @@ ENTRY(error_entry) +@@ -1649,12 +2168,23 @@ ENTRY(error_entry) movq_cfi r14, R14+8 movq_cfi r15, R15+8 xorl %ebx,%ebx @@ -24415,7 +24101,7 @@ index 03cd2a8..05a9aed 100644 ret /* -@@ -1681,7 +2192,7 @@ bstep_iret: +@@ -1681,7 +2211,7 @@ bstep_iret: movq %rcx,RIP+8(%rsp) jmp error_swapgs CFI_ENDPROC @@ -24424,7 +24110,7 @@ index 03cd2a8..05a9aed 100644 /* ebx: no swapgs flag (1: don't need swapgs, 0: need it) */ -@@ -1692,7 +2203,7 @@ ENTRY(error_exit) +@@ -1692,7 +2222,7 @@ ENTRY(error_exit) DISABLE_INTERRUPTS(CLBR_NONE) TRACE_IRQS_OFF GET_THREAD_INFO(%rcx) @@ -24433,7 +24119,7 @@ index 03cd2a8..05a9aed 100644 jne retint_kernel LOCKDEP_SYS_EXIT_IRQ movl TI_flags(%rcx),%edx -@@ -1701,7 +2212,7 @@ ENTRY(error_exit) +@@ -1701,7 +2231,7 @@ ENTRY(error_exit) jnz retint_careful jmp retint_swapgs CFI_ENDPROC @@ -24442,7 +24128,7 @@ index 03cd2a8..05a9aed 100644 /* * Test if a given stack is an NMI stack or not. -@@ -1759,9 +2270,11 @@ ENTRY(nmi) +@@ -1759,9 +2289,11 @@ ENTRY(nmi) * If %cs was not the kernel segment, then the NMI triggered in user * space, which means it is definitely not nested. */ @@ -24455,7 +24141,7 @@ index 03cd2a8..05a9aed 100644 /* * Check the special variable on the stack to see if NMIs are * executing. -@@ -1795,8 +2308,7 @@ nested_nmi: +@@ -1795,8 +2327,7 @@ nested_nmi: 1: /* Set up the interrupted NMIs stack to jump to repeat_nmi */ @@ -24465,7 +24151,7 @@ index 03cd2a8..05a9aed 100644 CFI_ADJUST_CFA_OFFSET 1*8 leaq -10*8(%rsp), %rdx pushq_cfi $__KERNEL_DS -@@ -1814,6 +2326,7 @@ nested_nmi_out: +@@ -1814,6 +2345,7 @@ nested_nmi_out: CFI_RESTORE rdx /* No need to check faults here */ @@ -24473,7 +24159,7 @@ index 03cd2a8..05a9aed 100644 INTERRUPT_RETURN CFI_RESTORE_STATE -@@ -1910,13 +2423,13 @@ end_repeat_nmi: +@@ -1910,13 +2442,13 @@ end_repeat_nmi: subq $ORIG_RAX-R15, %rsp CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15 /* @@ -24489,7 +24175,7 @@ index 03cd2a8..05a9aed 100644 DEFAULT_FRAME 0 /* -@@ -1926,9 +2439,9 @@ end_repeat_nmi: +@@ -1926,9 +2458,9 @@ end_repeat_nmi: * NMI itself takes a page fault, the page fault that was preempted * will read the information from the NMI page fault and not the * origin fault. Save it off and restore it if it changes. @@ -24501,7 +24187,7 @@ index 03cd2a8..05a9aed 100644 /* paranoidentry do_nmi, 0; without TRACE_IRQS_OFF */ movq %rsp,%rdi -@@ -1937,31 +2450,36 @@ end_repeat_nmi: +@@ -1937,31 +2469,36 @@ end_repeat_nmi: /* Did the NMI take a page fault? Restore cr2 if it did */ movq %cr2, %rcx @@ -28572,7 +28258,7 @@ index da6b35a..977e9cf 100644 #ifdef CONFIG_SMP diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c -index 1f96f93..6f29be7 100644 +index 09ce23a..9293938 100644 --- a/arch/x86/kernel/vsyscall_64.c +++ b/arch/x86/kernel/vsyscall_64.c @@ -56,15 +56,13 @@ @@ -28778,7 +28464,7 @@ index c697625..a032162 100644 out: diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c -index 0069118..c28ec0a 100644 +index 453e5fb..214168f 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -55,7 +55,7 @@ @@ -29524,7 +29210,7 @@ index f5cc9eb..51fa319 100644 CFI_ENDPROC ENDPROC(atomic64_inc_not_zero_cx8) diff --git a/arch/x86/lib/checksum_32.S b/arch/x86/lib/checksum_32.S -index e78b8ee..7e173a8 100644 +index e78b8eee..7e173a8 100644 --- a/arch/x86/lib/checksum_32.S +++ b/arch/x86/lib/checksum_32.S @@ -29,7 +29,8 @@ @@ -39221,28 +38907,10 @@ index 8320abd..ec48108 100644 if (cmd != SIOCWANDEV) diff --git a/drivers/char/random.c b/drivers/char/random.c -index 429b75b..a7f4145 100644 +index 429b75b..de805d0 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c -@@ -270,10 +270,17 @@ - /* - * Configuration information - */ -+#ifdef CONFIG_GRKERNSEC_RANDNET -+#define INPUT_POOL_SHIFT 14 -+#define INPUT_POOL_WORDS (1 << (INPUT_POOL_SHIFT-5)) -+#define OUTPUT_POOL_SHIFT 12 -+#define OUTPUT_POOL_WORDS (1 << (OUTPUT_POOL_SHIFT-5)) -+#else - #define INPUT_POOL_SHIFT 12 - #define INPUT_POOL_WORDS (1 << (INPUT_POOL_SHIFT-5)) - #define OUTPUT_POOL_SHIFT 10 - #define OUTPUT_POOL_WORDS (1 << (OUTPUT_POOL_SHIFT-5)) -+#endif - #define SEC_XFER_SIZE 512 - #define EXTRACT_SIZE 10 - -@@ -284,9 +291,6 @@ +@@ -284,9 +284,6 @@ /* * To allow fractional bits to be tracked, the entropy_count field is * denominated in units of 1/8th bits. @@ -39252,27 +38920,7 @@ index 429b75b..a7f4145 100644 */ #define ENTROPY_SHIFT 3 #define ENTROPY_BITS(r) ((r)->entropy_count >> ENTROPY_SHIFT) -@@ -361,12 +365,19 @@ static struct poolinfo { - #define S(x) ilog2(x)+5, (x), (x)*4, (x)*32, (x) << (ENTROPY_SHIFT+5) - int tap1, tap2, tap3, tap4, tap5; - } poolinfo_table[] = { -+#ifdef CONFIG_GRKERNSEC_RANDNET -+ /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */ -+ { S(512), 411, 308, 208, 104, 1 }, -+ /* x^128 + x^104 + x^76 + x^51 + x^25 + x + 1 -- 105 */ -+ { S(128), 104, 76, 51, 25, 1 }, -+#else - /* was: x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 */ - /* x^128 + x^104 + x^76 + x^51 +x^25 + x + 1 */ - { S(128), 104, 76, 51, 25, 1 }, - /* was: x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 */ - /* x^32 + x^26 + x^19 + x^14 + x^7 + x + 1 */ - { S(32), 26, 19, 14, 7, 1 }, -+#endif - #if 0 - /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */ - { S(2048), 1638, 1231, 819, 411, 1 }, -@@ -433,9 +444,9 @@ struct entropy_store { +@@ -433,9 +430,9 @@ struct entropy_store { }; static void push_to_pool(struct work_struct *work); @@ -39285,7 +38933,7 @@ index 429b75b..a7f4145 100644 static struct entropy_store input_pool = { .poolinfo = &poolinfo_table[0], -@@ -524,8 +535,8 @@ static void _mix_pool_bytes(struct entropy_store *r, const void *in, +@@ -524,8 +521,8 @@ static void _mix_pool_bytes(struct entropy_store *r, const void *in, input_rotate = (input_rotate + (i ? 7 : 14)) & 31; } @@ -39296,7 +38944,7 @@ index 429b75b..a7f4145 100644 smp_wmb(); if (out) -@@ -632,7 +643,7 @@ retry: +@@ -632,7 +629,7 @@ retry: /* The +2 corresponds to the /4 in the denominator */ do { @@ -39305,7 +38953,7 @@ index 429b75b..a7f4145 100644 unsigned int add = ((pool_size - entropy_count)*anfrac*3) >> s; -@@ -1151,7 +1162,7 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf, +@@ -1151,7 +1148,7 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf, extract_buf(r, tmp); i = min_t(int, nbytes, EXTRACT_SIZE); @@ -39314,7 +38962,7 @@ index 429b75b..a7f4145 100644 ret = -EFAULT; break; } -@@ -1507,7 +1518,7 @@ EXPORT_SYMBOL(generate_random_uuid); +@@ -1507,7 +1504,7 @@ EXPORT_SYMBOL(generate_random_uuid); #include <linux/sysctl.h> static int min_read_thresh = 8, min_write_thresh; @@ -39323,7 +38971,7 @@ index 429b75b..a7f4145 100644 static int max_write_thresh = INPUT_POOL_WORDS * 32; static char sysctl_bootid[16]; -@@ -1523,7 +1534,7 @@ static char sysctl_bootid[16]; +@@ -1523,7 +1520,7 @@ static char sysctl_bootid[16]; static int proc_do_uuid(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { @@ -39332,7 +38980,7 @@ index 429b75b..a7f4145 100644 unsigned char buf[64], tmp_uuid[16], *uuid; uuid = table->data; -@@ -1553,7 +1564,7 @@ static int proc_do_uuid(struct ctl_table *table, int write, +@@ -1553,7 +1550,7 @@ static int proc_do_uuid(struct ctl_table *table, int write, static int proc_do_entropy(ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { @@ -41223,7 +40871,7 @@ index d45d50d..72a5dd2 100644 int diff --git a/drivers/gpu/drm/nouveau/nouveau_vga.c b/drivers/gpu/drm/nouveau/nouveau_vga.c -index 471347e..5adc6b9 100644 +index 471347e..5adc6b9d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_vga.c +++ b/drivers/gpu/drm/nouveau/nouveau_vga.c @@ -67,7 +67,7 @@ nouveau_switcheroo_can_switch(struct pci_dev *pdev) @@ -42102,6 +41750,51 @@ index 7cd42ea..a367c48 100644 hid_debug_register(hdev, dev_name(&hdev->dev)); ret = device_add(&hdev->dev); +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index 3b43d1c..991ba79 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -290,6 +290,11 @@ static int magicmouse_raw_event(struct hid_device *hdev, + if (size < 4 || ((size - 4) % 9) != 0) + return 0; + npoints = (size - 4) / 9; ++ if (npoints > 15) { ++ hid_warn(hdev, "invalid size value (%d) for TRACKPAD_REPORT_ID\n", ++ size); ++ return 0; ++ } + msc->ntouches = 0; + for (ii = 0; ii < npoints; ii++) + magicmouse_emit_touch(msc, ii, data + ii * 9 + 4); +@@ -307,6 +312,11 @@ static int magicmouse_raw_event(struct hid_device *hdev, + if (size < 6 || ((size - 6) % 8) != 0) + return 0; + npoints = (size - 6) / 8; ++ if (npoints > 15) { ++ hid_warn(hdev, "invalid size value (%d) for MOUSE_REPORT_ID\n", ++ size); ++ return 0; ++ } + msc->ntouches = 0; + for (ii = 0; ii < npoints; ii++) + magicmouse_emit_touch(msc, ii, data + ii * 8 + 6); +diff --git a/drivers/hid/hid-picolcd_core.c b/drivers/hid/hid-picolcd_core.c +index acbb0210..020df3c 100644 +--- a/drivers/hid/hid-picolcd_core.c ++++ b/drivers/hid/hid-picolcd_core.c +@@ -350,6 +350,12 @@ static int picolcd_raw_event(struct hid_device *hdev, + if (!data) + return 1; + ++ if (size > 64) { ++ hid_warn(hdev, "invalid size value (%d) for picolcd raw event\n", ++ size); ++ return 0; ++ } ++ + if (report->id == REPORT_KEY_STATE) { + if (data->input_keys) + ret = picolcd_raw_keypad(data, report, raw_data+1, size-1); diff --git a/drivers/hid/hid-wiimote-debug.c b/drivers/hid/hid-wiimote-debug.c index c13fb5b..55a3802 100644 --- a/drivers/hid/hid-wiimote-debug.c @@ -44833,7 +44526,7 @@ index 56e24c0..e1c8e1f 100644 "md/raid1:%s: read error corrected " "(%d sectors at %llu on %s)\n", diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c -index cb882aa..9bd076e 100644 +index cb882aa..cb8aeca 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -1949,7 +1949,7 @@ static void end_sync_read(struct bio *bio, int error) @@ -44895,8 +44588,25 @@ index cb882aa..9bd076e 100644 } rdev_dec_pending(rdev, mddev); +@@ -2954,6 +2954,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, + */ + if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) { + end_reshape(conf); ++ close_sync(conf); + return 0; + } + +@@ -4411,7 +4412,7 @@ read_more: + read_bio->bi_private = r10_bio; + read_bio->bi_end_io = end_sync_read; + read_bio->bi_rw = READ; +- read_bio->bi_flags &= ~(BIO_POOL_MASK - 1); ++ read_bio->bi_flags &= (~0UL << BIO_RESET_BITS); + read_bio->bi_flags |= 1 << BIO_UPTODATE; + read_bio->bi_vcnt = 0; + read_bio->bi_iter.bi_size = 0; diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c -index 16f5c21..522b82e 100644 +index 16f5c21..c5d72c7 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -1707,6 +1707,10 @@ static int grow_one_stripe(struct r5conf *conf, int hash) @@ -44957,6 +44667,15 @@ index 16f5c21..522b82e 100644 > conf->max_nr_stripes) printk(KERN_WARNING "md/raid:%s: Too many read errors, failing device %s.\n", +@@ -3779,6 +3787,8 @@ static void handle_stripe(struct stripe_head *sh) + set_bit(R5_Wantwrite, &dev->flags); + if (prexor) + continue; ++ if (s.failed > 1) ++ continue; + if (!test_bit(R5_Insync, &dev->flags) || + ((i == sh->pd_idx || i == sh->qd_idx) && + s.failed == 0)) diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 983db75..ef9248c 100644 --- a/drivers/media/dvb-core/dvbdev.c @@ -45290,6 +45009,433 @@ index 2fd9009..278cc1e 100644 radio = devm_kzalloc(&pdev->dev, sizeof(*radio), GFP_KERNEL); if (!radio) +diff --git a/drivers/media/usb/dvb-usb/cinergyT2-core.c b/drivers/media/usb/dvb-usb/cinergyT2-core.c +index 9fd1527..8927230 100644 +--- a/drivers/media/usb/dvb-usb/cinergyT2-core.c ++++ b/drivers/media/usb/dvb-usb/cinergyT2-core.c +@@ -50,29 +50,73 @@ static struct dvb_usb_device_properties cinergyt2_properties; + + static int cinergyt2_streaming_ctrl(struct dvb_usb_adapter *adap, int enable) + { +- char buf[] = { CINERGYT2_EP1_CONTROL_STREAM_TRANSFER, enable ? 1 : 0 }; +- char result[64]; +- return dvb_usb_generic_rw(adap->dev, buf, sizeof(buf), result, +- sizeof(result), 0); ++ char *buf; ++ char *result; ++ int retval; ++ ++ buf = kmalloc(2, GFP_KERNEL); ++ if (buf == NULL) ++ return -ENOMEM; ++ result = kmalloc(64, GFP_KERNEL); ++ if (result == NULL) { ++ kfree(buf); ++ return -ENOMEM; ++ } ++ ++ buf[0] = CINERGYT2_EP1_CONTROL_STREAM_TRANSFER; ++ buf[1] = enable ? 1 : 0; ++ ++ retval = dvb_usb_generic_rw(adap->dev, buf, 2, result, 64, 0); ++ ++ kfree(buf); ++ kfree(result); ++ return retval; + } + + static int cinergyt2_power_ctrl(struct dvb_usb_device *d, int enable) + { +- char buf[] = { CINERGYT2_EP1_SLEEP_MODE, enable ? 0 : 1 }; +- char state[3]; +- return dvb_usb_generic_rw(d, buf, sizeof(buf), state, sizeof(state), 0); ++ char *buf; ++ char *state; ++ int retval; ++ ++ buf = kmalloc(2, GFP_KERNEL); ++ if (buf == NULL) ++ return -ENOMEM; ++ state = kmalloc(3, GFP_KERNEL); ++ if (state == NULL) { ++ kfree(buf); ++ return -ENOMEM; ++ } ++ ++ buf[0] = CINERGYT2_EP1_SLEEP_MODE; ++ buf[1] = enable ? 1 : 0; ++ ++ retval = dvb_usb_generic_rw(d, buf, 2, state, 3, 0); ++ ++ kfree(buf); ++ kfree(state); ++ return retval; + } + + static int cinergyt2_frontend_attach(struct dvb_usb_adapter *adap) + { +- char query[] = { CINERGYT2_EP1_GET_FIRMWARE_VERSION }; +- char state[3]; ++ char *query; ++ char *state; + int ret; ++ query = kmalloc(1, GFP_KERNEL); ++ if (query == NULL) ++ return -ENOMEM; ++ state = kmalloc(3, GFP_KERNEL); ++ if (state == NULL) { ++ kfree(query); ++ return -ENOMEM; ++ } ++ ++ query[0] = CINERGYT2_EP1_GET_FIRMWARE_VERSION; + + adap->fe_adap[0].fe = cinergyt2_fe_attach(adap->dev); + +- ret = dvb_usb_generic_rw(adap->dev, query, sizeof(query), state, +- sizeof(state), 0); ++ ret = dvb_usb_generic_rw(adap->dev, query, 1, state, 3, 0); + if (ret < 0) { + deb_rc("cinergyt2_power_ctrl() Failed to retrieve sleep " + "state info\n"); +@@ -80,7 +124,8 @@ static int cinergyt2_frontend_attach(struct dvb_usb_adapter *adap) + + /* Copy this pointer as we are gonna need it in the release phase */ + cinergyt2_usb_device = adap->dev; +- ++ kfree(query); ++ kfree(state); + return 0; + } + +@@ -141,12 +186,23 @@ static int repeatable_keys[] = { + static int cinergyt2_rc_query(struct dvb_usb_device *d, u32 *event, int *state) + { + struct cinergyt2_state *st = d->priv; +- u8 key[5] = {0, 0, 0, 0, 0}, cmd = CINERGYT2_EP1_GET_RC_EVENTS; ++ u8 *key, *cmd; + int i; + ++ cmd = kmalloc(1, GFP_KERNEL); ++ if (cmd == NULL) ++ return -EINVAL; ++ key = kzalloc(5, GFP_KERNEL); ++ if (key == NULL) { ++ kfree(cmd); ++ return -EINVAL; ++ } ++ ++ cmd[0] = CINERGYT2_EP1_GET_RC_EVENTS; ++ + *state = REMOTE_NO_KEY_PRESSED; + +- dvb_usb_generic_rw(d, &cmd, 1, key, sizeof(key), 0); ++ dvb_usb_generic_rw(d, cmd, 1, key, 5, 0); + if (key[4] == 0xff) { + /* key repeat */ + st->rc_counter++; +@@ -157,12 +213,12 @@ static int cinergyt2_rc_query(struct dvb_usb_device *d, u32 *event, int *state) + *event = d->last_event; + deb_rc("repeat key, event %x\n", + *event); +- return 0; ++ goto out; + } + } + deb_rc("repeated key (non repeatable)\n"); + } +- return 0; ++ goto out; + } + + /* hack to pass checksum on the custom field */ +@@ -174,6 +230,9 @@ static int cinergyt2_rc_query(struct dvb_usb_device *d, u32 *event, int *state) + + deb_rc("key: %*ph\n", 5, key); + } ++out: ++ kfree(cmd); ++ kfree(key); + return 0; + } + +diff --git a/drivers/media/usb/dvb-usb/cinergyT2-fe.c b/drivers/media/usb/dvb-usb/cinergyT2-fe.c +index c890fe4..f9b2ae6 100644 +--- a/drivers/media/usb/dvb-usb/cinergyT2-fe.c ++++ b/drivers/media/usb/dvb-usb/cinergyT2-fe.c +@@ -145,103 +145,176 @@ static int cinergyt2_fe_read_status(struct dvb_frontend *fe, + fe_status_t *status) + { + struct cinergyt2_fe_state *state = fe->demodulator_priv; +- struct dvbt_get_status_msg result; +- u8 cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS }; ++ struct dvbt_get_status_msg *result; ++ u8 *cmd; + int ret; + +- ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (u8 *)&result, +- sizeof(result), 0); ++ cmd = kmalloc(1, GFP_KERNEL); ++ if (cmd == NULL) ++ return -ENOMEM; ++ result = kmalloc(sizeof(*result), GFP_KERNEL); ++ if (result == NULL) { ++ kfree(cmd); ++ return -ENOMEM; ++ } ++ ++ cmd[0] = CINERGYT2_EP1_GET_TUNER_STATUS; ++ ++ ret = dvb_usb_generic_rw(state->d, cmd, 1, (u8 *)result, ++ sizeof(*result), 0); + if (ret < 0) +- return ret; ++ goto out; + + *status = 0; + +- if (0xffff - le16_to_cpu(result.gain) > 30) ++ if (0xffff - le16_to_cpu(result->gain) > 30) + *status |= FE_HAS_SIGNAL; +- if (result.lock_bits & (1 << 6)) ++ if (result->lock_bits & (1 << 6)) + *status |= FE_HAS_LOCK; +- if (result.lock_bits & (1 << 5)) ++ if (result->lock_bits & (1 << 5)) + *status |= FE_HAS_SYNC; +- if (result.lock_bits & (1 << 4)) ++ if (result->lock_bits & (1 << 4)) + *status |= FE_HAS_CARRIER; +- if (result.lock_bits & (1 << 1)) ++ if (result->lock_bits & (1 << 1)) + *status |= FE_HAS_VITERBI; + + if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) != + (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) + *status &= ~FE_HAS_LOCK; + +- return 0; ++out: ++ kfree(cmd); ++ kfree(result); ++ return ret; + } + + static int cinergyt2_fe_read_ber(struct dvb_frontend *fe, u32 *ber) + { + struct cinergyt2_fe_state *state = fe->demodulator_priv; +- struct dvbt_get_status_msg status; +- char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS }; ++ struct dvbt_get_status_msg *status; ++ char *cmd; + int ret; + +- ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status, +- sizeof(status), 0); ++ cmd = kmalloc(1, GFP_KERNEL); ++ if (cmd == NULL) ++ return -ENOMEM; ++ status = kmalloc(sizeof(*status), GFP_KERNEL); ++ if (status == NULL) { ++ kfree(cmd); ++ return -ENOMEM; ++ } ++ ++ cmd[0] = CINERGYT2_EP1_GET_TUNER_STATUS; ++ ++ ret = dvb_usb_generic_rw(state->d, cmd, 1, (char *)status, ++ sizeof(*status), 0); + if (ret < 0) +- return ret; ++ goto out; + +- *ber = le32_to_cpu(status.viterbi_error_rate); ++ *ber = le32_to_cpu(status->viterbi_error_rate); ++out: ++ kfree(cmd); ++ kfree(status); + return 0; + } + + static int cinergyt2_fe_read_unc_blocks(struct dvb_frontend *fe, u32 *unc) + { + struct cinergyt2_fe_state *state = fe->demodulator_priv; +- struct dvbt_get_status_msg status; +- u8 cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS }; ++ struct dvbt_get_status_msg *status; ++ u8 *cmd; + int ret; + +- ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (u8 *)&status, +- sizeof(status), 0); ++ cmd = kmalloc(1, GFP_KERNEL); ++ if (cmd == NULL) ++ return -ENOMEM; ++ status = kmalloc(sizeof(*status), GFP_KERNEL); ++ if (status == NULL) { ++ kfree(cmd); ++ return -ENOMEM; ++ } ++ ++ cmd[0] = CINERGYT2_EP1_GET_TUNER_STATUS; ++ ++ ret = dvb_usb_generic_rw(state->d, cmd, 1, (u8 *)status, ++ sizeof(*status), 0); + if (ret < 0) { + err("cinergyt2_fe_read_unc_blocks() Failed! (Error=%d)\n", + ret); +- return ret; ++ goto out; + } +- *unc = le32_to_cpu(status.uncorrected_block_count); +- return 0; ++ *unc = le32_to_cpu(status->uncorrected_block_count); ++ ++out: ++ kfree(cmd); ++ kfree(status); ++ return ret; + } + + static int cinergyt2_fe_read_signal_strength(struct dvb_frontend *fe, + u16 *strength) + { + struct cinergyt2_fe_state *state = fe->demodulator_priv; +- struct dvbt_get_status_msg status; +- char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS }; ++ struct dvbt_get_status_msg *status; ++ char *cmd; + int ret; + +- ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status, +- sizeof(status), 0); ++ cmd = kmalloc(1, GFP_KERNEL); ++ if (cmd == NULL) ++ return -ENOMEM; ++ status = kmalloc(sizeof(*status), GFP_KERNEL); ++ if (status == NULL) { ++ kfree(cmd); ++ return -ENOMEM; ++ } ++ ++ cmd[0] = CINERGYT2_EP1_GET_TUNER_STATUS; ++ ++ ret = dvb_usb_generic_rw(state->d, cmd, 1, (char *)status, ++ sizeof(*status), 0); + if (ret < 0) { + err("cinergyt2_fe_read_signal_strength() Failed!" + " (Error=%d)\n", ret); +- return ret; ++ goto out; + } +- *strength = (0xffff - le16_to_cpu(status.gain)); ++ *strength = (0xffff - le16_to_cpu(status->gain)); ++ ++out: ++ kfree(cmd); ++ kfree(status); + return 0; + } + + static int cinergyt2_fe_read_snr(struct dvb_frontend *fe, u16 *snr) + { + struct cinergyt2_fe_state *state = fe->demodulator_priv; +- struct dvbt_get_status_msg status; +- char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS }; ++ struct dvbt_get_status_msg *status; ++ char *cmd; + int ret; + +- ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status, +- sizeof(status), 0); ++ cmd = kmalloc(1, GFP_KERNEL); ++ if (cmd == NULL) ++ return -ENOMEM; ++ status = kmalloc(sizeof(*status), GFP_KERNEL); ++ if (status == NULL) { ++ kfree(cmd); ++ return -ENOMEM; ++ } ++ ++ cmd[0] = CINERGYT2_EP1_GET_TUNER_STATUS; ++ ++ ret = dvb_usb_generic_rw(state->d, cmd, 1, (char *)status, ++ sizeof(*status), 0); + if (ret < 0) { + err("cinergyt2_fe_read_snr() Failed! (Error=%d)\n", ret); +- return ret; ++ goto out; + } +- *snr = (status.snr << 8) | status.snr; +- return 0; ++ *snr = (status->snr << 8) | status->snr; ++ ++out: ++ kfree(cmd); ++ kfree(status); ++ return ret; + } + + static int cinergyt2_fe_init(struct dvb_frontend *fe) +@@ -266,35 +339,46 @@ static int cinergyt2_fe_set_frontend(struct dvb_frontend *fe) + { + struct dtv_frontend_properties *fep = &fe->dtv_property_cache; + struct cinergyt2_fe_state *state = fe->demodulator_priv; +- struct dvbt_set_parameters_msg param; +- char result[2]; ++ struct dvbt_set_parameters_msg *param; ++ char *result; + int err; + +- param.cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS; +- param.tps = cpu_to_le16(compute_tps(fep)); +- param.freq = cpu_to_le32(fep->frequency / 1000); +- param.flags = 0; ++ result = kmalloc(2, GFP_KERNEL); ++ if (result == NULL) ++ return -ENOMEM; ++ param = kmalloc(sizeof(*param), GFP_KERNEL); ++ if (param == NULL) { ++ kfree(result); ++ return -ENOMEM; ++ } ++ ++ param->cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS; ++ param->tps = cpu_to_le16(compute_tps(fep)); ++ param->freq = cpu_to_le32(fep->frequency / 1000); ++ param->flags = 0; + + switch (fep->bandwidth_hz) { + default: + case 8000000: +- param.bandwidth = 8; ++ param->bandwidth = 8; + break; + case 7000000: +- param.bandwidth = 7; ++ param->bandwidth = 7; + break; + case 6000000: +- param.bandwidth = 6; ++ param->bandwidth = 6; + break; + } + + err = dvb_usb_generic_rw(state->d, +- (char *)¶m, sizeof(param), +- result, sizeof(result), 0); ++ (char *)param, sizeof(*param), ++ result, 2, 0); + if (err < 0) + err("cinergyt2_fe_set_frontend() Failed! err=%d\n", err); + +- return (err < 0) ? err : 0; ++ kfree(result); ++ kfree(param); ++ return err; + } + + static void cinergyt2_fe_release(struct dvb_frontend *fe) diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c index a1c641e..3007da9 100644 --- a/drivers/media/usb/dvb-usb/cxusb.c @@ -47122,10 +47268,10 @@ index bf0d55e..82bcfbd1 100644 priv = netdev_priv(dev); priv->phy = phy; diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c -index 5adecc5..aec7730 100644 +index 7f1abb7..6434b33 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c -@@ -991,13 +991,15 @@ static const struct nla_policy macvlan_policy[IFLA_MACVLAN_MAX + 1] = { +@@ -992,13 +992,15 @@ static const struct nla_policy macvlan_policy[IFLA_MACVLAN_MAX + 1] = { int macvlan_link_register(struct rtnl_link_ops *ops) { /* common fields */ @@ -47148,7 +47294,7 @@ index 5adecc5..aec7730 100644 return rtnl_link_register(ops); }; -@@ -1051,7 +1053,7 @@ static int macvlan_device_event(struct notifier_block *unused, +@@ -1052,7 +1054,7 @@ static int macvlan_device_event(struct notifier_block *unused, return NOTIFY_DONE; } @@ -47201,19 +47347,6 @@ index 72ff14b..11d442d 100644 break; err = 0; break; -diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c -index 0180531..1aff970 100644 ---- a/drivers/net/ppp/pptp.c -+++ b/drivers/net/ppp/pptp.c -@@ -281,7 +281,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb) - nf_reset(skb); - - skb->ip_summed = CHECKSUM_NONE; -- ip_select_ident(skb, &rt->dst, NULL); -+ ip_select_ident(skb, NULL); - ip_send_check(iph); - - ip_local_out(skb); diff --git a/drivers/net/slip/slhc.c b/drivers/net/slip/slhc.c index 1252d9c..80e660b 100644 --- a/drivers/net/slip/slhc.c @@ -49715,7 +49848,7 @@ index f28ea07..34b16d3 100644 /* These three are default values which can be overridden */ diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c -index 868318a..e07ef3b 100644 +index 528bff5..84963854 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -571,7 +571,7 @@ static inline u32 next_command(struct ctlr_info *h, u8 q) @@ -52006,10 +52139,10 @@ index 9cd706d..6ff2de7 100644 if (cfg->uart_flags & UPF_CONS_FLOW) { diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c -index ece2049b..fba2524 100644 +index 25b8f68..3e23c14 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c -@@ -1448,7 +1448,7 @@ static void uart_hangup(struct tty_struct *tty) +@@ -1451,7 +1451,7 @@ static void uart_hangup(struct tty_struct *tty) uart_flush_buffer(tty); uart_shutdown(tty, state); spin_lock_irqsave(&port->lock, flags); @@ -52018,7 +52151,7 @@ index ece2049b..fba2524 100644 clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags); spin_unlock_irqrestore(&port->lock, flags); tty_port_tty_set(port, NULL); -@@ -1544,7 +1544,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp) +@@ -1547,7 +1547,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp) goto end; } @@ -52027,7 +52160,7 @@ index ece2049b..fba2524 100644 if (!state->uart_port || state->uart_port->flags & UPF_DEAD) { retval = -ENXIO; goto err_dec_count; -@@ -1572,7 +1572,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp) +@@ -1575,7 +1575,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp) /* * Make sure the device is in D0 state. */ @@ -52036,7 +52169,7 @@ index ece2049b..fba2524 100644 uart_change_pm(state, UART_PM_STATE_ON); /* -@@ -1590,7 +1590,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp) +@@ -1593,7 +1593,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp) end: return retval; err_dec_count: @@ -52846,7 +52979,7 @@ index 2a3bbdf..91d72cf 100644 file->f_version = event_count; return POLLIN | POLLRDNORM; diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c -index 90e18f6..5eeda46 100644 +index 9ca7716..a2ccc2e 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -187,7 +187,7 @@ static ssize_t usbdev_read(struct file *file, char __user *buf, size_t nbytes, @@ -52908,7 +53041,7 @@ index 2518c32..1c201bb 100644 wake_up(&usb_kill_urb_queue); usb_put_urb(urb); diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c -index 36b1e85..18fb0a4 100644 +index 6650df7..3a94427 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -27,6 +27,7 @@ @@ -52919,7 +53052,7 @@ index 36b1e85..18fb0a4 100644 #include <asm/uaccess.h> #include <asm/byteorder.h> -@@ -4502,6 +4503,10 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, +@@ -4549,6 +4550,10 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, goto done; return; } @@ -53151,7 +53284,7 @@ index 7a55fea..cc0ed4f 100644 #include "u_uac1.h" diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c -index 7ae0c4d..35521b7 100644 +index 7d6f64c..37a1efc 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -780,7 +780,7 @@ static struct urb *request_single_step_set_feature_urb( @@ -56922,7 +57055,7 @@ index ce25d75..dc09eeb 100644 &data); if (!inode) { diff --git a/fs/aio.c b/fs/aio.c -index 6d68e01..573d8dc 100644 +index 6d68e01..6bc8e9a 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -380,7 +380,7 @@ static int aio_setup_ring(struct kioctx *ctx) @@ -56934,6 +57067,19 @@ index 6d68e01..573d8dc 100644 return -EINVAL; file = aio_private_file(ctx, nr_pages); +@@ -1065,6 +1065,12 @@ static long aio_read_events_ring(struct kioctx *ctx, + tail = ring->tail; + kunmap_atomic(ring); + ++ /* ++ * Ensure that once we've read the current tail pointer, that ++ * we also see the events that were stored up to the tail. ++ */ ++ smp_rmb(); ++ + pr_debug("h%u t%u m%u\n", head, tail, ctx->nr_events); + + if (head == tail) diff --git a/fs/attr.c b/fs/attr.c index 6530ced..4a827e2 100644 --- a/fs/attr.c @@ -58405,10 +58551,33 @@ index ebaff36..7e3ea26 100644 kunmap(page); file_end_write(file); diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c -index 5e0982a..b7e82bc 100644 +index 5e0982a..ca18377 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c -@@ -248,7 +248,7 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx) +@@ -128,6 +128,8 @@ static int __dcache_readdir(struct file *file, struct dir_context *ctx) + struct dentry *dentry, *last; + struct ceph_dentry_info *di; + int err = 0; ++ char d_name[DNAME_INLINE_LEN]; ++ const unsigned char *name; + + /* claim ref on last dentry we returned */ + last = fi->dentry; +@@ -183,7 +185,12 @@ more: + dout(" %llu (%llu) dentry %p %.*s %p\n", di->offset, ctx->pos, + dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_inode); + ctx->pos = di->offset; +- if (!dir_emit(ctx, dentry->d_name.name, ++ name = dentry->d_name.name; ++ if (name == dentry->d_iname) { ++ memcpy(d_name, name, dentry->d_name.len); ++ name = d_name; ++ } ++ if (!dir_emit(ctx, name, + dentry->d_name.len, + ceph_translate_ino(dentry->d_sb, dentry->d_inode->i_ino), + dentry->d_inode->i_mode >> 12)) { +@@ -248,7 +255,7 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx) struct ceph_fs_client *fsc = ceph_inode_to_client(inode); struct ceph_mds_client *mdsc = fsc->mdsc; unsigned frag = fpos_frag(ctx->pos); @@ -59245,10 +59414,126 @@ index a93f7e6..d58bcbe 100644 return 0; while (nr) { diff --git a/fs/dcache.c b/fs/dcache.c -index 7f3b400..9c911f2 100644 +index 7f3b400..f91b141 100644 --- a/fs/dcache.c +++ b/fs/dcache.c -@@ -1495,7 +1495,7 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name) +@@ -106,8 +106,7 @@ static inline struct hlist_bl_head *d_hash(const struct dentry *parent, + unsigned int hash) + { + hash += (unsigned long) parent / L1_CACHE_BYTES; +- hash = hash + (hash >> d_hash_shift); +- return dentry_hashtable + (hash & d_hash_mask); ++ return dentry_hashtable + hash_32(hash, d_hash_shift); + } + + /* Statistics gathering. */ +@@ -251,7 +250,7 @@ static void __d_free(struct rcu_head *head) + */ + static void d_free(struct dentry *dentry) + { +- BUG_ON((int)dentry->d_lockref.count > 0); ++ BUG_ON((int)__lockref_read(&dentry->d_lockref) > 0); + this_cpu_dec(nr_dentry); + if (dentry->d_op && dentry->d_op->d_release) + dentry->d_op->d_release(dentry); +@@ -597,7 +596,7 @@ repeat: + dentry->d_flags |= DCACHE_REFERENCED; + dentry_lru_add(dentry); + +- dentry->d_lockref.count--; ++ __lockref_dec(&dentry->d_lockref); + spin_unlock(&dentry->d_lock); + return; + +@@ -652,7 +651,7 @@ int d_invalidate(struct dentry * dentry) + * We also need to leave mountpoints alone, + * directory or not. + */ +- if (dentry->d_lockref.count > 1 && dentry->d_inode) { ++ if (__lockref_read(&dentry->d_lockref) > 1 && dentry->d_inode) { + if (S_ISDIR(dentry->d_inode->i_mode) || d_mountpoint(dentry)) { + spin_unlock(&dentry->d_lock); + return -EBUSY; +@@ -668,7 +667,7 @@ EXPORT_SYMBOL(d_invalidate); + /* This must be called with d_lock held */ + static inline void __dget_dlock(struct dentry *dentry) + { +- dentry->d_lockref.count++; ++ __lockref_inc(&dentry->d_lockref); + } + + static inline void __dget(struct dentry *dentry) +@@ -709,8 +708,8 @@ repeat: + goto repeat; + } + rcu_read_unlock(); +- BUG_ON(!ret->d_lockref.count); +- ret->d_lockref.count++; ++ BUG_ON(!__lockref_read(&ret->d_lockref)); ++ __lockref_inc(&ret->d_lockref); + spin_unlock(&ret->d_lock); + return ret; + } +@@ -793,7 +792,7 @@ restart: + spin_lock(&inode->i_lock); + hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) { + spin_lock(&dentry->d_lock); +- if (!dentry->d_lockref.count) { ++ if (!__lockref_read(&dentry->d_lockref)) { + /* + * inform the fs via d_prune that this dentry + * is about to be unhashed and destroyed. +@@ -885,7 +884,7 @@ static void shrink_dentry_list(struct list_head *list) + * We found an inuse dentry which was not removed from + * the LRU because of laziness during lookup. Do not free it. + */ +- if (dentry->d_lockref.count) { ++ if (__lockref_read(&dentry->d_lockref)) { + spin_unlock(&dentry->d_lock); + continue; + } +@@ -931,7 +930,7 @@ dentry_lru_isolate(struct list_head *item, spinlock_t *lru_lock, void *arg) + * counts, just remove them from the LRU. Otherwise give them + * another pass through the LRU. + */ +- if (dentry->d_lockref.count) { ++ if (__lockref_read(&dentry->d_lockref) > 0) { + d_lru_isolate(dentry); + spin_unlock(&dentry->d_lock); + return LRU_REMOVED; +@@ -1269,7 +1268,7 @@ static enum d_walk_ret select_collect(void *_data, struct dentry *dentry) + * loop in shrink_dcache_parent() might not make any progress + * and loop forever. + */ +- if (dentry->d_lockref.count) { ++ if (__lockref_read(&dentry->d_lockref)) { + dentry_lru_del(dentry); + } else if (!(dentry->d_flags & DCACHE_SHRINK_LIST)) { + /* +@@ -1323,11 +1322,11 @@ static enum d_walk_ret umount_collect(void *_data, struct dentry *dentry) + struct select_data *data = _data; + enum d_walk_ret ret = D_WALK_CONTINUE; + +- if (dentry->d_lockref.count) { ++ if (__lockref_read(&dentry->d_lockref)) { + dentry_lru_del(dentry); + if (likely(!list_empty(&dentry->d_subdirs))) + goto out; +- if (dentry == data->start && dentry->d_lockref.count == 1) ++ if (dentry == data->start && __lockref_read(&dentry->d_lockref) == 1) + goto out; + printk(KERN_ERR + "BUG: Dentry %p{i=%lx,n=%s}" +@@ -1337,7 +1336,7 @@ static enum d_walk_ret umount_collect(void *_data, struct dentry *dentry) + dentry->d_inode ? + dentry->d_inode->i_ino : 0UL, + dentry->d_name.name, +- dentry->d_lockref.count, ++ __lockref_read(&dentry->d_lockref), + dentry->d_sb->s_type->name, + dentry->d_sb->s_id); + BUG(); +@@ -1495,7 +1494,7 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name) */ dentry->d_iname[DNAME_INLINE_LEN-1] = 0; if (name->len > DNAME_INLINE_LEN-1) { @@ -59257,7 +59542,43 @@ index 7f3b400..9c911f2 100644 if (!dname) { kmem_cache_free(dentry_cache, dentry); return NULL; -@@ -3430,7 +3430,8 @@ void __init vfs_caches_init(unsigned long mempages) +@@ -1513,7 +1512,7 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name) + smp_wmb(); + dentry->d_name.name = dname; + +- dentry->d_lockref.count = 1; ++ __lockref_set(&dentry->d_lockref, 1); + dentry->d_flags = 0; + spin_lock_init(&dentry->d_lock); + seqcount_init(&dentry->d_seq); +@@ -2276,7 +2275,7 @@ struct dentry *__d_lookup(const struct dentry *parent, const struct qstr *name) + goto next; + } + +- dentry->d_lockref.count++; ++ __lockref_inc(&dentry->d_lockref); + found = dentry; + spin_unlock(&dentry->d_lock); + break; +@@ -2375,7 +2374,7 @@ again: + spin_lock(&dentry->d_lock); + inode = dentry->d_inode; + isdir = S_ISDIR(inode->i_mode); +- if (dentry->d_lockref.count == 1) { ++ if (__lockref_read(&dentry->d_lockref) == 1) { + if (!spin_trylock(&inode->i_lock)) { + spin_unlock(&dentry->d_lock); + cpu_relax(); +@@ -3314,7 +3313,7 @@ static enum d_walk_ret d_genocide_kill(void *data, struct dentry *dentry) + + if (!(dentry->d_flags & DCACHE_GENOCIDE)) { + dentry->d_flags |= DCACHE_GENOCIDE; +- dentry->d_lockref.count--; ++ __lockref_dec(&dentry->d_lockref); + } + } + return D_WALK_CONTINUE; +@@ -3430,7 +3429,8 @@ void __init vfs_caches_init(unsigned long mempages) mempages -= reserve; names_cachep = kmem_cache_create("names_cache", PATH_MAX, 0, @@ -59268,7 +59589,7 @@ index 7f3b400..9c911f2 100644 dcache_init(); inode_init(); diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c -index 9c0444c..628490c 100644 +index 1576195..49a19ae 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -415,7 +415,11 @@ EXPORT_SYMBOL_GPL(debugfs_create_file); @@ -60263,10 +60584,10 @@ index e6574d7..c30cbe2 100644 brelse(bh); bh = NULL; diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c -index 502f0fd..bf3b3c1 100644 +index 242226a..f3eb6c1 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c -@@ -1880,7 +1880,7 @@ void ext4_mb_simple_scan_group(struct ext4_allocation_context *ac, +@@ -1882,7 +1882,7 @@ void ext4_mb_simple_scan_group(struct ext4_allocation_context *ac, BUG_ON(ac->ac_b_ex.fe_len != ac->ac_g_ex.fe_len); if (EXT4_SB(sb)->s_mb_stats) @@ -60275,7 +60596,7 @@ index 502f0fd..bf3b3c1 100644 break; } -@@ -2189,7 +2189,7 @@ repeat: +@@ -2191,7 +2191,7 @@ repeat: ac->ac_status = AC_STATUS_CONTINUE; ac->ac_flags |= EXT4_MB_HINT_FIRST; cr = 3; @@ -60284,7 +60605,7 @@ index 502f0fd..bf3b3c1 100644 goto repeat; } } -@@ -2697,25 +2697,25 @@ int ext4_mb_release(struct super_block *sb) +@@ -2699,25 +2699,25 @@ int ext4_mb_release(struct super_block *sb) if (sbi->s_mb_stats) { ext4_msg(sb, KERN_INFO, "mballoc: %u blocks %u reqs (%u success)", @@ -60320,7 +60641,7 @@ index 502f0fd..bf3b3c1 100644 } free_percpu(sbi->s_locality_groups); -@@ -3169,16 +3169,16 @@ static void ext4_mb_collect_stats(struct ext4_allocation_context *ac) +@@ -3171,16 +3171,16 @@ static void ext4_mb_collect_stats(struct ext4_allocation_context *ac) struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb); if (sbi->s_mb_stats && ac->ac_g_ex.fe_len > 1) { @@ -60343,7 +60664,7 @@ index 502f0fd..bf3b3c1 100644 } if (ac->ac_op == EXT4_MB_HISTORY_ALLOC) -@@ -3583,7 +3583,7 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac) +@@ -3607,7 +3607,7 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac) trace_ext4_mb_new_inode_pa(ac, pa); ext4_mb_use_inode_pa(ac, pa); @@ -60352,7 +60673,7 @@ index 502f0fd..bf3b3c1 100644 ei = EXT4_I(ac->ac_inode); grp = ext4_get_group_info(sb, ac->ac_b_ex.fe_group); -@@ -3643,7 +3643,7 @@ ext4_mb_new_group_pa(struct ext4_allocation_context *ac) +@@ -3667,7 +3667,7 @@ ext4_mb_new_group_pa(struct ext4_allocation_context *ac) trace_ext4_mb_new_group_pa(ac, pa); ext4_mb_use_group_pa(ac, pa); @@ -60361,7 +60682,7 @@ index 502f0fd..bf3b3c1 100644 grp = ext4_get_group_info(sb, ac->ac_b_ex.fe_group); lg = ac->ac_lg; -@@ -3732,7 +3732,7 @@ ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh, +@@ -3756,7 +3756,7 @@ ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh, * from the bitmap and continue. */ } @@ -60370,7 +60691,7 @@ index 502f0fd..bf3b3c1 100644 return err; } -@@ -3750,7 +3750,7 @@ ext4_mb_release_group_pa(struct ext4_buddy *e4b, +@@ -3774,7 +3774,7 @@ ext4_mb_release_group_pa(struct ext4_buddy *e4b, ext4_get_group_no_and_offset(sb, pa->pa_pstart, &group, &bit); BUG_ON(group != e4b->bd_group && pa->pa_len != 0); mb_free_blocks(pa->pa_inode, e4b, bit, pa->pa_len); @@ -60393,7 +60714,7 @@ index 04434ad..6404663 100644 "MMP failure info: last update time: %llu, last update " "node: %s, last update device: %s\n", diff --git a/fs/ext4/super.c b/fs/ext4/super.c -index 25b327e..56f169d 100644 +index a46030d..1477295 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1270,7 +1270,7 @@ static ext4_fsblk_t get_sb_block(void **data) @@ -62412,10 +62733,18 @@ index b29e42f..5ea7fdf 100644 #define MNT_NS_INTERNAL ERR_PTR(-EINVAL) /* distinct from any mnt_namespace */ diff --git a/fs/namei.c b/fs/namei.c -index bdea109..e242796 100644 +index bdea109..6e919ab 100644 --- a/fs/namei.c +++ b/fs/namei.c -@@ -330,17 +330,34 @@ int generic_permission(struct inode *inode, int mask) +@@ -34,6 +34,7 @@ + #include <linux/device_cgroup.h> + #include <linux/fs_struct.h> + #include <linux/posix_acl.h> ++#include <linux/hash.h> + #include <asm/uaccess.h> + + #include "internal.h" +@@ -330,17 +331,34 @@ int generic_permission(struct inode *inode, int mask) if (ret != -EACCES) return ret; @@ -62453,7 +62782,7 @@ index bdea109..e242796 100644 * Read/write DACs are always overridable. * Executable DACs are overridable when there is * at least one exec bit set. -@@ -349,14 +366,6 @@ int generic_permission(struct inode *inode, int mask) +@@ -349,14 +367,6 @@ int generic_permission(struct inode *inode, int mask) if (capable_wrt_inode_uidgid(inode, CAP_DAC_OVERRIDE)) return 0; @@ -62468,7 +62797,7 @@ index bdea109..e242796 100644 return -EACCES; } -@@ -822,7 +831,7 @@ follow_link(struct path *link, struct nameidata *nd, void **p) +@@ -822,7 +832,7 @@ follow_link(struct path *link, struct nameidata *nd, void **p) { struct dentry *dentry = link->dentry; int error; @@ -62477,7 +62806,7 @@ index bdea109..e242796 100644 BUG_ON(nd->flags & LOOKUP_RCU); -@@ -843,6 +852,12 @@ follow_link(struct path *link, struct nameidata *nd, void **p) +@@ -843,6 +853,12 @@ follow_link(struct path *link, struct nameidata *nd, void **p) if (error) goto out_put_nd_path; @@ -62490,7 +62819,7 @@ index bdea109..e242796 100644 nd->last_type = LAST_BIND; *p = dentry->d_inode->i_op->follow_link(dentry, nd); error = PTR_ERR(*p); -@@ -1591,6 +1606,8 @@ static inline int nested_symlink(struct path *path, struct nameidata *nd) +@@ -1591,6 +1607,8 @@ static inline int nested_symlink(struct path *path, struct nameidata *nd) if (res) break; res = walk_component(nd, path, LOOKUP_FOLLOW); @@ -62499,6 +62828,16 @@ index bdea109..e242796 100644 put_link(nd, &link, cookie); } while (res > 0); +@@ -1624,8 +1642,7 @@ static inline int nested_symlink(struct path *path, struct nameidata *nd) + + static inline unsigned int fold_hash(unsigned long hash) + { +- hash += hash >> (8*sizeof(int)); +- return hash; ++ return hash_64(hash, 32); + } + + #else /* 32-bit case */ @@ -1664,7 +1681,7 @@ EXPORT_SYMBOL(full_name_hash); static inline unsigned long hash_name(const char *name, unsigned int *hashp) { @@ -63138,19 +63477,6 @@ index 15f9d98..082c625 100644 } void nfs_fattr_init(struct nfs_fattr *fattr) -diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c -index 8f854dd..d0fec26 100644 ---- a/fs/nfs/nfs3acl.c -+++ b/fs/nfs/nfs3acl.c -@@ -256,7 +256,7 @@ nfs3_list_one_acl(struct inode *inode, int type, const char *name, void *data, - char *p = data + *result; - - acl = get_acl(inode, type); -- if (!acl) -+ if (IS_ERR_OR_NULL(acl)) - return 0; - - posix_acl_release(acl); diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index f23a6ca..730ddcc 100644 --- a/fs/nfsd/nfs4proc.c @@ -63178,7 +63504,7 @@ index 8657335..cd3e37f 100644 [OP_CLOSE] = (nfsd4_dec)nfsd4_decode_close, [OP_COMMIT] = (nfsd4_dec)nfsd4_decode_commit, diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c -index f8f060f..c4ba09a 100644 +index f8f060f..d9a7258 100644 --- a/fs/nfsd/nfscache.c +++ b/fs/nfsd/nfscache.c @@ -519,14 +519,17 @@ nfsd_cache_update(struct svc_rqst *rqstp, int cachetype, __be32 *statp) @@ -63202,6 +63528,15 @@ index f8f060f..c4ba09a 100644 /* Don't cache excessive amounts of data and XDR failures */ if (!statp || len > (256 >> 2)) { +@@ -537,7 +540,7 @@ nfsd_cache_update(struct svc_rqst *rqstp, int cachetype, __be32 *statp) + switch (cachetype) { + case RC_REPLSTAT: + if (len != 1) +- printk("nfsd: RC_REPLSTAT/reply len %d!\n",len); ++ printk("nfsd: RC_REPLSTAT/reply len %ld!\n",len); + rp->c_replstat = *statp; + break; + case RC_REPLBUFF: diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index eea5ad1..5a84ac7 100644 --- a/fs/nfsd/vfs.c @@ -63234,7 +63569,7 @@ index eea5ad1..5a84ac7 100644 if (host_err < 0) diff --git a/fs/nls/nls_base.c b/fs/nls/nls_base.c -index 52ccd34..43a53b1 100644 +index 52ccd34..7a6b202 100644 --- a/fs/nls/nls_base.c +++ b/fs/nls/nls_base.c @@ -234,21 +234,25 @@ EXPORT_SYMBOL(utf16s_to_utf8s); @@ -63286,6 +63621,24 @@ index 52ccd34..43a53b1 100644 spin_unlock(&nls_lock); return 0; } +@@ -272,7 +278,7 @@ int unregister_nls(struct nls_table * nls) + return -EINVAL; + } + +-static struct nls_table *find_nls(char *charset) ++static struct nls_table *find_nls(const char *charset) + { + struct nls_table *nls; + spin_lock(&nls_lock); +@@ -288,7 +294,7 @@ static struct nls_table *find_nls(char *charset) + return nls; + } + +-struct nls_table *load_nls(char *charset) ++struct nls_table *load_nls(const char *charset) + { + return try_then_request_module(find_nls(charset), "nls_%s", charset); + } diff --git a/fs/nls/nls_euc-jp.c b/fs/nls/nls_euc-jp.c index 162b3f1..6076a7c 100644 --- a/fs/nls/nls_euc-jp.c @@ -63344,6 +63697,28 @@ index 287a22c..4e56e4e 100644 group->fanotify_data.f_flags = event_f_flags; #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS oevent->response = 0; +diff --git a/fs/notify/fdinfo.c b/fs/notify/fdinfo.c +index 238a593..9d7e2b9 100644 +--- a/fs/notify/fdinfo.c ++++ b/fs/notify/fdinfo.c +@@ -42,7 +42,7 @@ static int show_mark_fhandle(struct seq_file *m, struct inode *inode) + { + struct { + struct file_handle handle; +- u8 pad[64]; ++ u8 pad[MAX_HANDLE_SZ]; + } f; + int size, ret, i; + +@@ -50,7 +50,7 @@ static int show_mark_fhandle(struct seq_file *m, struct inode *inode) + size = f.handle.handle_bytes >> 2; + + ret = exportfs_encode_inode_fh(inode, (struct fid *)f.handle.f_handle, &size, 0); +- if ((ret == 255) || (ret == -ENOSPC)) { ++ if ((ret == FILEID_INVALID) || (ret < 0)) { + WARN_ONCE(1, "Can't encode file handler for inotify: %d\n", ret); + return 0; + } diff --git a/fs/notify/notification.c b/fs/notify/notification.c index 1e58402..bb2d6f4 100644 --- a/fs/notify/notification.c @@ -65877,7 +66252,7 @@ index 467bb1c..cf9d65a 100644 return -EINVAL; diff --git a/fs/seq_file.c b/fs/seq_file.c -index 1d641bb..c2f4743 100644 +index 1d641bb..9ca7f61 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c @@ -10,6 +10,8 @@ @@ -65970,6 +66345,15 @@ index 1d641bb..c2f4743 100644 int res = -ENOMEM; if (op) { +@@ -605,7 +620,7 @@ EXPORT_SYMBOL(single_open); + int single_open_size(struct file *file, int (*show)(struct seq_file *, void *), + void *data, size_t size) + { +- char *buf = kmalloc(size, GFP_KERNEL); ++ char *buf = kmalloc(size, GFP_KERNEL | GFP_USERCOPY); + int ret; + if (!buf) + return -ENOMEM; @@ -620,6 +635,17 @@ int single_open_size(struct file *file, int (*show)(struct seq_file *, void *), } EXPORT_SYMBOL(single_open_size); @@ -66268,6 +66652,133 @@ index e18b988..f1d4ad0f 100644 { int err; +diff --git a/fs/udf/inode.c b/fs/udf/inode.c +index 982ce05..c693331 100644 +--- a/fs/udf/inode.c ++++ b/fs/udf/inode.c +@@ -51,7 +51,6 @@ MODULE_LICENSE("GPL"); + + static umode_t udf_convert_permissions(struct fileEntry *); + static int udf_update_inode(struct inode *, int); +-static void udf_fill_inode(struct inode *, struct buffer_head *); + static int udf_sync_inode(struct inode *inode); + static int udf_alloc_i_data(struct inode *inode, size_t size); + static sector_t inode_getblk(struct inode *, sector_t, int *, int *); +@@ -1271,13 +1270,25 @@ update_time: + return 0; + } + ++/* ++ * Maximum length of linked list formed by ICB hierarchy. The chosen number is ++ * arbitrary - just that we hopefully don't limit any real use of rewritten ++ * inode on write-once media but avoid looping for too long on corrupted media. ++ */ ++#define UDF_MAX_ICB_NESTING 1024 ++ + static void __udf_read_inode(struct inode *inode) + { + struct buffer_head *bh = NULL; + struct fileEntry *fe; ++ struct extendedFileEntry *efe; + uint16_t ident; + struct udf_inode_info *iinfo = UDF_I(inode); ++ struct udf_sb_info *sbi = UDF_SB(inode->i_sb); ++ unsigned int link_count; ++ unsigned int indirections = 0; + ++reread: + /* + * Set defaults, but the inode is still incomplete! + * Note: get_new_inode() sets the following on a new inode: +@@ -1307,6 +1318,7 @@ static void __udf_read_inode(struct inode *inode) + } + + fe = (struct fileEntry *)bh->b_data; ++ efe = (struct extendedFileEntry *)bh->b_data; + + if (fe->icbTag.strategyType == cpu_to_le16(4096)) { + struct buffer_head *ibh; +@@ -1314,28 +1326,26 @@ static void __udf_read_inode(struct inode *inode) + ibh = udf_read_ptagged(inode->i_sb, &iinfo->i_location, 1, + &ident); + if (ident == TAG_IDENT_IE && ibh) { +- struct buffer_head *nbh = NULL; + struct kernel_lb_addr loc; + struct indirectEntry *ie; + + ie = (struct indirectEntry *)ibh->b_data; + loc = lelb_to_cpu(ie->indirectICB.extLocation); + +- if (ie->indirectICB.extLength && +- (nbh = udf_read_ptagged(inode->i_sb, &loc, 0, +- &ident))) { +- if (ident == TAG_IDENT_FE || +- ident == TAG_IDENT_EFE) { +- memcpy(&iinfo->i_location, +- &loc, +- sizeof(struct kernel_lb_addr)); +- brelse(bh); +- brelse(ibh); +- brelse(nbh); +- __udf_read_inode(inode); ++ if (ie->indirectICB.extLength) { ++ brelse(bh); ++ brelse(ibh); ++ memcpy(&iinfo->i_location, &loc, ++ sizeof(struct kernel_lb_addr)); ++ if (++indirections > UDF_MAX_ICB_NESTING) { ++ udf_err(inode->i_sb, ++ "too many ICBs in ICB hierarchy" ++ " (max %d supported)\n", ++ UDF_MAX_ICB_NESTING); ++ make_bad_inode(inode); + return; + } +- brelse(nbh); ++ goto reread; + } + } + brelse(ibh); +@@ -1346,22 +1356,6 @@ static void __udf_read_inode(struct inode *inode) + make_bad_inode(inode); + return; + } +- udf_fill_inode(inode, bh); +- +- brelse(bh); +-} +- +-static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) +-{ +- struct fileEntry *fe; +- struct extendedFileEntry *efe; +- struct udf_sb_info *sbi = UDF_SB(inode->i_sb); +- struct udf_inode_info *iinfo = UDF_I(inode); +- unsigned int link_count; +- +- fe = (struct fileEntry *)bh->b_data; +- efe = (struct extendedFileEntry *)bh->b_data; +- + if (fe->icbTag.strategyType == cpu_to_le16(4)) + iinfo->i_strat4096 = 0; + else /* if (fe->icbTag.strategyType == cpu_to_le16(4096)) */ +@@ -1551,6 +1545,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) + } else + make_bad_inode(inode); + } ++ brelse(bh); + } + + static int udf_alloc_i_data(struct inode *inode, size_t size) +@@ -1664,7 +1659,7 @@ static int udf_update_inode(struct inode *inode, int do_sync) + FE_PERM_U_DELETE | FE_PERM_U_CHATTR)); + fe->permissions = cpu_to_le32(udfperms); + +- if (S_ISDIR(inode->i_mode)) ++ if (S_ISDIR(inode->i_mode) && inode->i_nlink > 0) + fe->fileLinkCount = cpu_to_le16(inode->i_nlink - 1); + else + fe->fileLinkCount = cpu_to_le16(inode->i_nlink); diff --git a/fs/udf/misc.c b/fs/udf/misc.c index c175b4d..8f36a16 100644 --- a/fs/udf/misc.c @@ -66526,10 +67037,10 @@ index 78e62cc..eec3706 100644 diff --git a/grsecurity/Kconfig b/grsecurity/Kconfig new file mode 100644 -index 0000000..bfd482c +index 0000000..27cec32 --- /dev/null +++ b/grsecurity/Kconfig -@@ -0,0 +1,1176 @@ +@@ -0,0 +1,1166 @@ +# +# grecurity configuration +# @@ -67462,16 +67973,6 @@ index 0000000..bfd482c +menu "Network Protections" +depends on GRKERNSEC + -+config GRKERNSEC_RANDNET -+ bool "Larger entropy pools" -+ default y if GRKERNSEC_CONFIG_AUTO -+ help -+ If you say Y here, the entropy pools used for many features of Linux -+ and grsecurity will be doubled in size. Since several grsecurity -+ features use additional randomness, it is recommended that you say Y -+ here. Saying Y here has a similar effect as modifying -+ /proc/sys/kernel/random/poolsize. -+ +config GRKERNSEC_BLACKHOLE + bool "TCP/UDP blackhole and LAST_ACK DoS prevention" + default y if GRKERNSEC_CONFIG_AUTO @@ -70564,10 +71065,10 @@ index 0000000..18ffbbd +} diff --git a/grsecurity/gracl_cap.c b/grsecurity/gracl_cap.c new file mode 100644 -index 0000000..bdd51ea +index 0000000..1a94c11 --- /dev/null +++ b/grsecurity/gracl_cap.c -@@ -0,0 +1,110 @@ +@@ -0,0 +1,127 @@ +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/sched.h> @@ -70578,6 +71079,29 @@ index 0000000..bdd51ea +extern const char *captab_log[]; +extern int captab_log_entries; + ++int gr_learn_cap(const struct task_struct *task, const struct cred *cred, const int cap) ++{ ++ struct acl_subject_label *curracl; ++ ++ if (!gr_acl_is_enabled()) ++ return 1; ++ ++ curracl = task->acl; ++ ++ if (curracl->mode & (GR_LEARN | GR_INHERITLEARN)) { ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, ++ task->role->roletype, GR_GLOBAL_UID(cred->uid), ++ GR_GLOBAL_GID(cred->gid), task->exec_file ? ++ gr_to_filename(task->exec_file->f_path.dentry, ++ task->exec_file->f_path.mnt) : curracl->filename, ++ curracl->filename, 0UL, ++ 0UL, "", (unsigned long) cap, &task->signal->saved_ip); ++ return 1; ++ } ++ ++ return 0; ++} ++ +int gr_task_acl_is_capable(const struct task_struct *task, const struct cred *cred, const int cap) +{ + struct acl_subject_label *curracl; @@ -70614,19 +71138,13 @@ index 0000000..bdd51ea + return 1; + } + -+ curracl = task->acl; -+ -+ if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) -+ && cap_raised(cred->cap_effective, cap)) { -+ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, -+ task->role->roletype, GR_GLOBAL_UID(cred->uid), -+ GR_GLOBAL_GID(cred->gid), task->exec_file ? -+ gr_to_filename(task->exec_file->f_path.dentry, -+ task->exec_file->f_path.mnt) : curracl->filename, -+ curracl->filename, 0UL, -+ 0UL, "", (unsigned long) cap, &task->signal->saved_ip); ++ /* only learn the capability use if the process has the capability in the ++ general case, the two uses in sys.c of gr_learn_cap are an exception ++ to this rule to ensure any role transition involves what the full-learned ++ policy believes in a privileged process ++ */ ++ if (cap_raised(cred->cap_effective, cap) && gr_learn_cap(task, cred, cap)) + return 1; -+ } + + if ((cap >= 0) && (cap < captab_log_entries) && cap_raised(cred->cap_effective, cap) && !cap_raised(cap_audit, cap)) + gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]); @@ -74649,10 +75167,10 @@ index 0000000..baa635c +} diff --git a/grsecurity/grsec_disabled.c b/grsecurity/grsec_disabled.c new file mode 100644 -index 0000000..4d6fce8 +index 0000000..1e028d7 --- /dev/null +++ b/grsecurity/grsec_disabled.c -@@ -0,0 +1,433 @@ +@@ -0,0 +1,439 @@ +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/sched.h> @@ -74694,6 +75212,12 @@ index 0000000..4d6fce8 + return 0; +} + ++int ++gr_learn_cap(const struct task_struct *task, const struct cred *cred, const int cap) ++{ ++ return 0; ++} ++ +void +gr_handle_proc_create(const struct dentry *dentry, const struct inode *inode) +{ @@ -75088,10 +75612,10 @@ index 0000000..4d6fce8 +#endif diff --git a/grsecurity/grsec_exec.c b/grsecurity/grsec_exec.c new file mode 100644 -index 0000000..f35f454 +index 0000000..14638ff --- /dev/null +++ b/grsecurity/grsec_exec.c -@@ -0,0 +1,187 @@ +@@ -0,0 +1,188 @@ +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/file.h> @@ -75226,7 +75750,8 @@ index 0000000..f35f454 + "CAP_MAC_OVERRIDE", + "CAP_MAC_ADMIN", + "CAP_SYSLOG", -+ "CAP_WAKE_ALARM" ++ "CAP_WAKE_ALARM", ++ "CAP_BLOCK_SUSPEND" +}; + +int captab_log_entries = sizeof(captab_log)/sizeof(captab_log[0]); @@ -77334,10 +77859,10 @@ index 0000000..61b514e +EXPORT_SYMBOL_GPL(gr_log_timechange); diff --git a/grsecurity/grsec_tpe.c b/grsecurity/grsec_tpe.c new file mode 100644 -index 0000000..ee57dcf +index 0000000..d1953de --- /dev/null +++ b/grsecurity/grsec_tpe.c -@@ -0,0 +1,73 @@ +@@ -0,0 +1,78 @@ +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/file.h> @@ -77351,6 +77876,7 @@ index 0000000..ee57dcf +{ +#ifdef CONFIG_GRKERNSEC + struct inode *inode = file->f_path.dentry->d_parent->d_inode; ++ struct inode *file_inode = file->f_path.dentry->d_inode; + const struct cred *cred = current_cred(); + char *msg = NULL; + char *msg2 = NULL; @@ -77383,6 +77909,8 @@ index 0000000..ee57dcf + msg2 = "file in world-writable directory"; + else if (inode->i_mode & S_IWGRP) + msg2 = "file in group-writable directory"; ++ else if (file_inode->i_mode & S_IWOTH) ++ msg2 = "file is world-writable"; + + if (msg && msg2) { + char fullmsg[70] = {0}; @@ -77402,6 +77930,8 @@ index 0000000..ee57dcf + msg = "file in world-writable directory"; + else if (inode->i_mode & S_IWGRP) + msg = "file in group-writable directory"; ++ else if (file_inode->i_mode & S_IWOTH) ++ msg = "file is world-writable"; + + if (msg) { + gr_log_str_fs(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, msg, file->f_path.dentry, file->f_path.mnt); @@ -80455,10 +80985,10 @@ index 0000000..b02ba9d +#define GR_MSRWRITE_MSG "denied write to CPU MSR by " diff --git a/include/linux/grsecurity.h b/include/linux/grsecurity.h new file mode 100644 -index 0000000..b87dd26 +index 0000000..acda855 --- /dev/null +++ b/include/linux/grsecurity.h -@@ -0,0 +1,252 @@ +@@ -0,0 +1,254 @@ +#ifndef GR_SECURITY_H +#define GR_SECURITY_H +#include <linux/fs.h> @@ -80498,6 +81028,8 @@ index 0000000..b87dd26 +int gr_check_user_change(kuid_t real, kuid_t effective, kuid_t fs); +int gr_check_group_change(kgid_t real, kgid_t effective, kgid_t fs); + ++int gr_learn_cap(const struct task_struct *task, const struct cred *cred, const int cap); ++ +void gr_del_task_from_ip_table(struct task_struct *p); + +int gr_pid_is_chrooted(struct task_struct *p); @@ -80737,10 +81269,28 @@ index 0000000..e7ffaaf + +#endif diff --git a/include/linux/hash.h b/include/linux/hash.h -index bd1754c..8240892 100644 +index bd1754c..69b7715 100644 --- a/include/linux/hash.h +++ b/include/linux/hash.h -@@ -83,7 +83,7 @@ static inline u32 hash32_ptr(const void *ptr) +@@ -37,6 +37,9 @@ static __always_inline u64 hash_64(u64 val, unsigned int bits) + { + u64 hash = val; + ++#if defined(CONFIG_ARCH_HAS_FAST_MULTIPLIER) && BITS_PER_LONG == 64 ++ hash = hash * GOLDEN_RATIO_PRIME_64; ++#else + /* Sigh, gcc can't optimise this alone like it does for 32 bits. */ + u64 n = hash; + n <<= 18; +@@ -51,6 +54,7 @@ static __always_inline u64 hash_64(u64 val, unsigned int bits) + hash += n; + n <<= 2; + hash += n; ++#endif + + /* High bits are more random, so use them. */ + return hash >> (64 - bits); +@@ -83,7 +87,7 @@ static inline u32 hash32_ptr(const void *ptr) struct fast_hash_ops { u32 (*hash)(const void *data, u32 len, u32 seed); u32 (*hash2)(const u32 *data, u32 len, u32 seed); @@ -81256,6 +81806,47 @@ index ef95941..82db65a 100644 /** * list_move - delete from one list and add as another's head * @list: the entry to move +diff --git a/include/linux/lockref.h b/include/linux/lockref.h +index 4bfde0e..d6e2e09 100644 +--- a/include/linux/lockref.h ++++ b/include/linux/lockref.h +@@ -47,4 +47,36 @@ static inline int __lockref_is_dead(const struct lockref *l) + return ((int)l->count < 0); + } + ++static inline unsigned int __lockref_read(struct lockref *lockref) ++{ ++ return lockref->count; ++} ++ ++static inline void __lockref_set(struct lockref *lockref, unsigned int count) ++{ ++ lockref->count = count; ++} ++ ++static inline void __lockref_inc(struct lockref *lockref) ++{ ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ atomic_inc((atomic_t *)&lockref->count); ++#else ++ lockref->count++; ++#endif ++ ++} ++ ++static inline void __lockref_dec(struct lockref *lockref) ++{ ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ atomic_dec((atomic_t *)&lockref->count); ++#else ++ lockref->count--; ++#endif ++ ++} ++ + #endif /* __LINUX_LOCKREF_H */ diff --git a/include/linux/math64.h b/include/linux/math64.h index c45c089..298841c 100644 --- a/include/linux/math64.h @@ -82024,7 +82615,7 @@ index 0000000..33f4af8 + +#endif diff --git a/include/linux/nls.h b/include/linux/nls.h -index 520681b..1d67ed2 100644 +index 520681b..2b7fabb 100644 --- a/include/linux/nls.h +++ b/include/linux/nls.h @@ -31,7 +31,7 @@ struct nls_table { @@ -82036,6 +82627,15 @@ index 520681b..1d67ed2 100644 /* this value hold the maximum octet of charset */ #define NLS_MAX_CHARSET_SIZE 6 /* for UTF-8 */ +@@ -46,7 +46,7 @@ enum utf16_endian { + /* nls_base.c */ + extern int __register_nls(struct nls_table *, struct module *); + extern int unregister_nls(struct nls_table *); +-extern struct nls_table *load_nls(char *); ++extern struct nls_table *load_nls(const char *); + extern void unload_nls(struct nls_table *); + extern struct nls_table *load_nls_default(void); + #define register_nls(nls) __register_nls((nls), THIS_MODULE) diff --git a/include/linux/notifier.h b/include/linux/notifier.h index d14a4c3..a078786 100644 --- a/include/linux/notifier.h @@ -84291,52 +84891,20 @@ index c55aeed..b3393f4 100644 /** inet_connection_sock - INET connection oriented sock * diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h -index 058271b..1af4453 100644 +index 823ec7b..44c938c 100644 --- a/include/net/inetpeer.h +++ b/include/net/inetpeer.h -@@ -41,14 +41,13 @@ struct inet_peer { - struct rcu_head gc_rcu; - }; - /* -- * Once inet_peer is queued for deletion (refcnt == -1), following fields -- * are not available: rid, ip_id_count -+ * Once inet_peer is queued for deletion (refcnt == -1), following field -+ * is not available: rid - * We can share memory with rcu_head to help keep inet_peer small. +@@ -47,7 +47,7 @@ struct inet_peer { */ union { struct { - atomic_t rid; /* Frag reception counter */ -- atomic_t ip_id_count; /* IP ID for the next packet */ -+ atomic_unchecked_t rid; /* Frag reception counter */ ++ atomic_unchecked_t rid; /* Frag reception counter */ }; struct rcu_head rcu; struct inet_peer *gc_next; -@@ -165,7 +164,7 @@ bool inet_peer_xrlim_allow(struct inet_peer *peer, int timeout); - void inetpeer_invalidate_tree(struct inet_peer_base *); - - /* -- * temporary check to make sure we dont access rid, ip_id_count, tcp_ts, -+ * temporary check to make sure we dont access rid, tcp_ts, - * tcp_ts_stamp if no refcount is taken on inet_peer - */ - static inline void inet_peer_refcheck(const struct inet_peer *p) -@@ -173,13 +172,4 @@ static inline void inet_peer_refcheck(const struct inet_peer *p) - WARN_ON_ONCE(atomic_read(&p->refcnt) <= 0); - } - -- --/* can be called with or without local BH being disabled */ --static inline int inet_getid(struct inet_peer *p, int more) --{ -- more++; -- inet_peer_refcheck(p); -- return atomic_add_return(more, &p->ip_id_count) - more; --} -- - #endif /* _NET_INETPEER_H */ diff --git a/include/net/ip.h b/include/net/ip.h -index 23be0fd..7251808 100644 +index 937f196..7251808 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -214,7 +214,7 @@ static inline void snmp_mib_free(void __percpu *ptr[SNMP_ARRAY_SZ]) @@ -84348,55 +84916,15 @@ index 23be0fd..7251808 100644 static inline int inet_is_reserved_local_port(int port) { return test_bit(port, sysctl_local_reserved_ports); -@@ -297,9 +297,10 @@ static inline unsigned int ip_skb_dst_mtu(const struct sk_buff *skb) +@@ -297,7 +297,7 @@ static inline unsigned int ip_skb_dst_mtu(const struct sk_buff *skb) } } --void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more); +-u32 ip_idents_reserve(u32 hash, int segs); +u32 ip_idents_reserve(u32 hash, int segs) __intentional_overflow(-1); -+void __ip_select_ident(struct iphdr *iph, int segs); - --static inline void ip_select_ident(struct sk_buff *skb, struct dst_entry *dst, struct sock *sk) -+static inline void ip_select_ident_segs(struct sk_buff *skb, struct sock *sk, int segs) - { - struct iphdr *iph = ip_hdr(skb); + void __ip_select_ident(struct iphdr *iph, int segs); -@@ -309,24 +310,20 @@ static inline void ip_select_ident(struct sk_buff *skb, struct dst_entry *dst, s - * does not change, they drop every other packet in - * a TCP stream using header compression. - */ -- iph->id = (sk && inet_sk(sk)->inet_daddr) ? -- htons(inet_sk(sk)->inet_id++) : 0; -- } else -- __ip_select_ident(iph, dst, 0); --} -- --static inline void ip_select_ident_more(struct sk_buff *skb, struct dst_entry *dst, struct sock *sk, int more) --{ -- struct iphdr *iph = ip_hdr(skb); -- -- if ((iph->frag_off & htons(IP_DF)) && !skb->local_df) { - if (sk && inet_sk(sk)->inet_daddr) { - iph->id = htons(inet_sk(sk)->inet_id); -- inet_sk(sk)->inet_id += 1 + more; -- } else -+ inet_sk(sk)->inet_id += segs; -+ } else { - iph->id = 0; -- } else -- __ip_select_ident(iph, dst, more); -+ } -+ } else { -+ __ip_select_ident(iph, segs); -+ } -+} -+ -+static inline void ip_select_ident(struct sk_buff *skb, struct sock *sk) -+{ -+ ip_select_ident_segs(skb, sk, 1); - } - - /* + static inline void ip_select_ident_segs(struct sk_buff *skb, struct sock *sk, int segs) diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index 9922093..a1755d6 100644 --- a/include/net/ip_fib.h @@ -84446,19 +84974,6 @@ index 5679d92..2e7a690 100644 /* ip_vs_est */ struct list_head est_list; /* estimator list */ spinlock_t est_lock; -diff --git a/include/net/ipv6.h b/include/net/ipv6.h -index 4f541f1..9ac6578 100644 ---- a/include/net/ipv6.h -+++ b/include/net/ipv6.h -@@ -660,8 +660,6 @@ static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_add - return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr)); - } - --void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt); -- - int ip6_dst_hoplimit(struct dst_entry *dst); - - /* diff --git a/include/net/irda/ircomm_tty.h b/include/net/irda/ircomm_tty.h index 8d4f588..2e37ad2 100644 --- a/include/net/irda/ircomm_tty.h @@ -84859,19 +85374,6 @@ index 0dfcc92..7967849 100644 /* Structure to track chunk fragments that have been acked, but peer -diff --git a/include/net/secure_seq.h b/include/net/secure_seq.h -index f257486..3f36d45 100644 ---- a/include/net/secure_seq.h -+++ b/include/net/secure_seq.h -@@ -3,8 +3,6 @@ - - #include <linux/types.h> - --__u32 secure_ip_id(__be32 daddr); --__u32 secure_ipv6_id(const __be32 daddr[4]); - u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport); - u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, - __be16 dport); diff --git a/include/net/sock.h b/include/net/sock.h index 2f7bc43..530dadc 100644 --- a/include/net/sock.h @@ -86524,10 +87026,25 @@ index 1191a44..7c81292 100644 +} +EXPORT_SYMBOL(capable_wrt_inode_uidgid_nolog); diff --git a/kernel/cgroup.c b/kernel/cgroup.c -index 0c753dd..dd7d3d6 100644 +index 0c753dd..3ce8cca 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c -@@ -5372,7 +5372,7 @@ static int cgroup_css_links_read(struct seq_file *seq, void *v) +@@ -5190,6 +5190,14 @@ static void cgroup_release_agent(struct work_struct *work) + release_list); + list_del_init(&cgrp->release_list); + raw_spin_unlock(&release_list_lock); ++ ++ /* ++ * don't bother calling call_usermodehelper if we haven't ++ * configured a binary to execute ++ */ ++ if (cgrp->root->release_agent_path[0] == '\0') ++ goto continue_free; ++ + pathbuf = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!pathbuf) + goto continue_free; +@@ -5372,7 +5380,7 @@ static int cgroup_css_links_read(struct seq_file *seq, void *v) struct css_set *cset = link->cset; struct task_struct *task; int count = 0; @@ -87638,7 +88155,7 @@ index c44bff8..a3c5876 100644 else new_fs = fs; diff --git a/kernel/futex.c b/kernel/futex.c -index e3087af..8e3b90f 100644 +index e3087af..4730710 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -54,6 +54,7 @@ @@ -87688,7 +88205,15 @@ index e3087af..8e3b90f 100644 pagefault_disable(); ret = __copy_from_user_inatomic(dest, from, sizeof(u32)); -@@ -3019,6 +3025,7 @@ static void __init futex_detect_cmpxchg(void) +@@ -2614,6 +2620,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, + * shared futexes. We need to compare the keys: + */ + if (match_futex(&q.key, &key2)) { ++ queue_unlock(hb); + ret = -EINVAL; + goto out_put_keys; + } +@@ -3019,6 +3026,7 @@ static void __init futex_detect_cmpxchg(void) { #ifndef CONFIG_HAVE_FUTEX_CMPXCHG u32 curval; @@ -87696,7 +88221,7 @@ index e3087af..8e3b90f 100644 /* * This will fail and we want it. Some arch implementations do -@@ -3030,8 +3037,11 @@ static void __init futex_detect_cmpxchg(void) +@@ -3030,8 +3038,11 @@ static void __init futex_detect_cmpxchg(void) * implementation, the non-functional ones will return * -ENOSYS. */ @@ -87930,10 +88455,26 @@ index 3127ad5..159d880 100644 return -ENOMEM; reset_iter(iter, 0); diff --git a/kernel/kcmp.c b/kernel/kcmp.c -index e30ac0f..3528cac 100644 +index e30ac0f..a7fcafb 100644 --- a/kernel/kcmp.c +++ b/kernel/kcmp.c -@@ -99,6 +99,10 @@ SYSCALL_DEFINE5(kcmp, pid_t, pid1, pid_t, pid2, int, type, +@@ -44,11 +44,12 @@ static long kptr_obfuscate(long v, int type) + */ + static int kcmp_ptr(void *v1, void *v2, enum kcmp_type type) + { +- long ret; ++ long t1, t2; + +- ret = kptr_obfuscate((long)v1, type) - kptr_obfuscate((long)v2, type); ++ t1 = kptr_obfuscate((long)v1, type); ++ t2 = kptr_obfuscate((long)v2, type); + +- return (ret < 0) | ((ret > 0) << 1); ++ return (t1 < t2) | ((t1 > t2) << 1); + } + + /* The caller must have pinned the task */ +@@ -99,6 +100,10 @@ SYSCALL_DEFINE5(kcmp, pid_t, pid1, pid_t, pid2, int, type, struct task_struct *task1, *task2; int ret; @@ -90723,7 +91264,7 @@ index a63f4dc..349bbb0 100644 unsigned long timeout) { diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index 515e212..268a828 100644 +index 677ebad..e39b352 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -1775,7 +1775,7 @@ void set_numabalancing_state(bool enabled) @@ -90774,7 +91315,7 @@ index 515e212..268a828 100644 /* can't increase priority */ if (attr->sched_priority > p->rt_priority && attr->sched_priority > rlim_rtprio) -@@ -4726,8 +4732,10 @@ void idle_task_exit(void) +@@ -4727,8 +4733,10 @@ void idle_task_exit(void) BUG_ON(cpu_online(smp_processor_id())); @@ -90786,7 +91327,7 @@ index 515e212..268a828 100644 mmdrop(mm); } -@@ -4805,7 +4813,7 @@ static void migrate_tasks(unsigned int dead_cpu) +@@ -4806,7 +4814,7 @@ static void migrate_tasks(unsigned int dead_cpu) #if defined(CONFIG_SCHED_DEBUG) && defined(CONFIG_SYSCTL) @@ -90795,7 +91336,7 @@ index 515e212..268a828 100644 { .procname = "sched_domain", .mode = 0555, -@@ -4822,17 +4830,17 @@ static struct ctl_table sd_ctl_root[] = { +@@ -4823,17 +4831,17 @@ static struct ctl_table sd_ctl_root[] = { {} }; @@ -90817,7 +91358,7 @@ index 515e212..268a828 100644 /* * In the intermediate directories, both the child directory and -@@ -4840,22 +4848,25 @@ static void sd_free_ctl_entry(struct ctl_table **tablep) +@@ -4841,22 +4849,25 @@ static void sd_free_ctl_entry(struct ctl_table **tablep) * will always be set. In the lowest directory the names are * static strings and all have proc handlers. */ @@ -90849,7 +91390,7 @@ index 515e212..268a828 100644 const char *procname, void *data, int maxlen, umode_t mode, proc_handler *proc_handler, bool load_idx) -@@ -4875,7 +4886,7 @@ set_table_entry(struct ctl_table *entry, +@@ -4876,7 +4887,7 @@ set_table_entry(struct ctl_table *entry, static struct ctl_table * sd_alloc_ctl_domain_table(struct sched_domain *sd) { @@ -90858,7 +91399,7 @@ index 515e212..268a828 100644 if (table == NULL) return NULL; -@@ -4910,9 +4921,9 @@ sd_alloc_ctl_domain_table(struct sched_domain *sd) +@@ -4911,9 +4922,9 @@ sd_alloc_ctl_domain_table(struct sched_domain *sd) return table; } @@ -90870,7 +91411,7 @@ index 515e212..268a828 100644 struct sched_domain *sd; int domain_num = 0, i; char buf[32]; -@@ -4939,11 +4950,13 @@ static struct ctl_table_header *sd_sysctl_header; +@@ -4940,11 +4951,13 @@ static struct ctl_table_header *sd_sysctl_header; static void register_sched_domain_sysctl(void) { int i, cpu_num = num_possible_cpus(); @@ -90885,7 +91426,7 @@ index 515e212..268a828 100644 if (entry == NULL) return; -@@ -4966,8 +4979,12 @@ static void unregister_sched_domain_sysctl(void) +@@ -4967,8 +4980,12 @@ static void unregister_sched_domain_sysctl(void) if (sd_sysctl_header) unregister_sysctl_table(sd_sysctl_header); sd_sysctl_header = NULL; @@ -91154,7 +91695,7 @@ index 490fcbb..1e502c6 100644 .thread_should_run = ksoftirqd_should_run, .thread_fn = run_ksoftirqd, diff --git a/kernel/sys.c b/kernel/sys.c -index c0a58be..784c618 100644 +index c0a58be..95e292b 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -148,6 +148,12 @@ static int set_one_prio(struct task_struct *p, int niceval, int error) @@ -91170,17 +91711,28 @@ index c0a58be..784c618 100644 no_nice = security_task_setnice(p, niceval); if (no_nice) { error = no_nice; -@@ -351,6 +357,9 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid) +@@ -351,6 +357,20 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid) goto error; } + if (gr_check_group_change(new->gid, new->egid, INVALID_GID)) + goto error; + ++ if (!gid_eq(new->gid, old->gid)) { ++ /* make sure we generate a learn log for what will ++ end up being a role transition after a full-learning ++ policy is generated ++ CAP_SETGID is required to perform a transition ++ we may not log a CAP_SETGID check above, e.g. ++ in the case where new rgid = old egid ++ */ ++ gr_learn_cap(current, new, CAP_SETGID); ++ } ++ if (rgid != (gid_t) -1 || (egid != (gid_t) -1 && !gid_eq(kegid, old->gid))) new->sgid = new->egid; -@@ -386,6 +395,10 @@ SYSCALL_DEFINE1(setgid, gid_t, gid) +@@ -386,6 +406,10 @@ SYSCALL_DEFINE1(setgid, gid_t, gid) old = current_cred(); retval = -EPERM; @@ -91191,7 +91743,7 @@ index c0a58be..784c618 100644 if (ns_capable(old->user_ns, CAP_SETGID)) new->gid = new->egid = new->sgid = new->fsgid = kgid; else if (gid_eq(kgid, old->gid) || gid_eq(kgid, old->sgid)) -@@ -403,7 +416,7 @@ error: +@@ -403,7 +427,7 @@ error: /* * change the user struct in a credentials set to match the new UID */ @@ -91200,7 +91752,7 @@ index c0a58be..784c618 100644 { struct user_struct *new_user; -@@ -483,6 +496,9 @@ SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid) +@@ -483,7 +507,18 @@ SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid) goto error; } @@ -91208,9 +91760,18 @@ index c0a58be..784c618 100644 + goto error; + if (!uid_eq(new->uid, old->uid)) { ++ /* make sure we generate a learn log for what will ++ end up being a role transition after a full-learning ++ policy is generated ++ CAP_SETUID is required to perform a transition ++ we may not log a CAP_SETUID check above, e.g. ++ in the case where new ruid = old euid ++ */ ++ gr_learn_cap(current, new, CAP_SETUID); retval = set_user(new); if (retval < 0) -@@ -533,6 +549,12 @@ SYSCALL_DEFINE1(setuid, uid_t, uid) + goto error; +@@ -533,6 +568,12 @@ SYSCALL_DEFINE1(setuid, uid_t, uid) old = current_cred(); retval = -EPERM; @@ -91223,7 +91784,7 @@ index c0a58be..784c618 100644 if (ns_capable(old->user_ns, CAP_SETUID)) { new->suid = new->uid = kuid; if (!uid_eq(kuid, old->uid)) { -@@ -602,6 +624,9 @@ SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid) +@@ -602,6 +643,9 @@ SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid) goto error; } @@ -91233,7 +91794,7 @@ index c0a58be..784c618 100644 if (ruid != (uid_t) -1) { new->uid = kruid; if (!uid_eq(kruid, old->uid)) { -@@ -684,6 +709,9 @@ SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid) +@@ -684,6 +728,9 @@ SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid) goto error; } @@ -91243,7 +91804,7 @@ index c0a58be..784c618 100644 if (rgid != (gid_t) -1) new->gid = krgid; if (egid != (gid_t) -1) -@@ -745,12 +773,16 @@ SYSCALL_DEFINE1(setfsuid, uid_t, uid) +@@ -745,12 +792,16 @@ SYSCALL_DEFINE1(setfsuid, uid_t, uid) uid_eq(kuid, old->suid) || uid_eq(kuid, old->fsuid) || ns_capable(old->user_ns, CAP_SETUID)) { if (!uid_eq(kuid, old->fsuid)) { @@ -91260,7 +91821,7 @@ index c0a58be..784c618 100644 abort_creds(new); return old_fsuid; -@@ -783,12 +815,16 @@ SYSCALL_DEFINE1(setfsgid, gid_t, gid) +@@ -783,12 +834,16 @@ SYSCALL_DEFINE1(setfsgid, gid_t, gid) if (gid_eq(kgid, old->gid) || gid_eq(kgid, old->egid) || gid_eq(kgid, old->sgid) || gid_eq(kgid, old->fsgid) || ns_capable(old->user_ns, CAP_SETGID)) { @@ -91277,7 +91838,7 @@ index c0a58be..784c618 100644 abort_creds(new); return old_fsgid; -@@ -1167,19 +1203,19 @@ SYSCALL_DEFINE1(olduname, struct oldold_utsname __user *, name) +@@ -1167,19 +1222,19 @@ SYSCALL_DEFINE1(olduname, struct oldold_utsname __user *, name) return -EFAULT; down_read(&uts_sem); @@ -91302,7 +91863,7 @@ index c0a58be..784c618 100644 __OLD_UTS_LEN); error |= __put_user(0, name->machine + __OLD_UTS_LEN); up_read(&uts_sem); -@@ -1381,6 +1417,13 @@ int do_prlimit(struct task_struct *tsk, unsigned int resource, +@@ -1381,6 +1436,13 @@ int do_prlimit(struct task_struct *tsk, unsigned int resource, */ new_rlim->rlim_cur = 1; } @@ -91602,10 +92163,71 @@ index 7c7964c..2a0d412 100644 update_vsyscall_tz(); if (firsttime) { diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c -index fe75444..190c528 100644 +index fe75444..b8a1463 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c -@@ -811,7 +811,7 @@ static int __init alarmtimer_init(void) +@@ -464,18 +464,26 @@ static enum alarmtimer_type clock2alarm(clockid_t clockid) + static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm, + ktime_t now) + { ++ unsigned long flags; + struct k_itimer *ptr = container_of(alarm, struct k_itimer, + it.alarm.alarmtimer); +- if (posix_timer_event(ptr, 0) != 0) +- ptr->it_overrun++; ++ enum alarmtimer_restart result = ALARMTIMER_NORESTART; ++ ++ spin_lock_irqsave(&ptr->it_lock, flags); ++ if ((ptr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) { ++ if (posix_timer_event(ptr, 0) != 0) ++ ptr->it_overrun++; ++ } + + /* Re-add periodic timers */ + if (ptr->it.alarm.interval.tv64) { + ptr->it_overrun += alarm_forward(alarm, now, + ptr->it.alarm.interval); +- return ALARMTIMER_RESTART; ++ result = ALARMTIMER_RESTART; + } +- return ALARMTIMER_NORESTART; ++ spin_unlock_irqrestore(&ptr->it_lock, flags); ++ ++ return result; + } + + /** +@@ -541,18 +549,22 @@ static int alarm_timer_create(struct k_itimer *new_timer) + * @new_timer: k_itimer pointer + * @cur_setting: itimerspec data to fill + * +- * Copies the itimerspec data out from the k_itimer ++ * Copies out the current itimerspec data + */ + static void alarm_timer_get(struct k_itimer *timr, + struct itimerspec *cur_setting) + { +- memset(cur_setting, 0, sizeof(struct itimerspec)); ++ ktime_t relative_expiry_time = ++ alarm_expires_remaining(&(timr->it.alarm.alarmtimer)); + +- cur_setting->it_interval = +- ktime_to_timespec(timr->it.alarm.interval); +- cur_setting->it_value = +- ktime_to_timespec(timr->it.alarm.alarmtimer.node.expires); +- return; ++ if (ktime_to_ns(relative_expiry_time) > 0) { ++ cur_setting->it_value = ktime_to_timespec(relative_expiry_time); ++ } else { ++ cur_setting->it_value.tv_sec = 0; ++ cur_setting->it_value.tv_nsec = 0; ++ } ++ ++ cur_setting->it_interval = ktime_to_timespec(timr->it.alarm.interval); + } + + /** +@@ -811,7 +823,7 @@ static int __init alarmtimer_init(void) struct platform_device *pdev; int error = 0; int i; @@ -91869,7 +92491,7 @@ index e3be87e..7480b36 100644 ftrace_graph_active++; diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c -index 0954450..0ed035c 100644 +index 0954450..1e3e687 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -352,9 +352,9 @@ struct buffer_data_page { @@ -91895,7 +92517,31 @@ index 0954450..0ed035c 100644 local_t dropped_events; local_t committing; local_t commits; -@@ -991,8 +991,8 @@ static int rb_tail_page_update(struct ring_buffer_per_cpu *cpu_buffer, +@@ -626,8 +626,22 @@ int ring_buffer_poll_wait(struct ring_buffer *buffer, int cpu, + work = &cpu_buffer->irq_work; + } + +- work->waiters_pending = true; + poll_wait(filp, &work->waiters, poll_table); ++ work->waiters_pending = true; ++ /* ++ * There's a tight race between setting the waiters_pending and ++ * checking if the ring buffer is empty. Once the waiters_pending bit ++ * is set, the next event will wake the task up, but we can get stuck ++ * if there's only a single event in. ++ * ++ * FIXME: Ideally, we need a memory barrier on the writer side as well, ++ * but adding a memory barrier to all events will cause too much of a ++ * performance hit in the fast path. We only need a memory barrier when ++ * the buffer goes from empty to having content. But as this race is ++ * extremely small, and it's not a problem if another event comes in, we ++ * will fix it later. ++ */ ++ smp_mb(); + + if ((cpu == RING_BUFFER_ALL_CPUS && !ring_buffer_empty(buffer)) || + (cpu != RING_BUFFER_ALL_CPUS && !ring_buffer_empty_cpu(buffer, cpu))) +@@ -991,8 +1005,8 @@ static int rb_tail_page_update(struct ring_buffer_per_cpu *cpu_buffer, * * We add a counter to the write field to denote this. */ @@ -91906,7 +92552,7 @@ index 0954450..0ed035c 100644 /* * Just make sure we have seen our old_write and synchronize -@@ -1020,8 +1020,8 @@ static int rb_tail_page_update(struct ring_buffer_per_cpu *cpu_buffer, +@@ -1020,8 +1034,8 @@ static int rb_tail_page_update(struct ring_buffer_per_cpu *cpu_buffer, * cmpxchg to only update if an interrupt did not already * do it for us. If the cmpxchg fails, we don't care. */ @@ -91917,7 +92563,7 @@ index 0954450..0ed035c 100644 /* * No need to worry about races with clearing out the commit. -@@ -1385,12 +1385,12 @@ static void rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer); +@@ -1385,12 +1399,12 @@ static void rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer); static inline unsigned long rb_page_entries(struct buffer_page *bpage) { @@ -91932,7 +92578,7 @@ index 0954450..0ed035c 100644 } static int -@@ -1485,7 +1485,7 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned int nr_pages) +@@ -1485,7 +1499,7 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned int nr_pages) * bytes consumed in ring buffer from here. * Increment overrun to account for the lost events. */ @@ -91941,7 +92587,7 @@ index 0954450..0ed035c 100644 local_sub(BUF_PAGE_SIZE, &cpu_buffer->entries_bytes); } -@@ -2063,7 +2063,7 @@ rb_handle_head_page(struct ring_buffer_per_cpu *cpu_buffer, +@@ -2063,7 +2077,7 @@ rb_handle_head_page(struct ring_buffer_per_cpu *cpu_buffer, * it is our responsibility to update * the counters. */ @@ -91950,7 +92596,7 @@ index 0954450..0ed035c 100644 local_sub(BUF_PAGE_SIZE, &cpu_buffer->entries_bytes); /* -@@ -2213,7 +2213,7 @@ rb_reset_tail(struct ring_buffer_per_cpu *cpu_buffer, +@@ -2213,7 +2227,7 @@ rb_reset_tail(struct ring_buffer_per_cpu *cpu_buffer, if (tail == BUF_PAGE_SIZE) tail_page->real_end = 0; @@ -91959,7 +92605,7 @@ index 0954450..0ed035c 100644 return; } -@@ -2248,7 +2248,7 @@ rb_reset_tail(struct ring_buffer_per_cpu *cpu_buffer, +@@ -2248,7 +2262,7 @@ rb_reset_tail(struct ring_buffer_per_cpu *cpu_buffer, rb_event_set_padding(event); /* Set the write back to the previous setting */ @@ -91968,7 +92614,7 @@ index 0954450..0ed035c 100644 return; } -@@ -2260,7 +2260,7 @@ rb_reset_tail(struct ring_buffer_per_cpu *cpu_buffer, +@@ -2260,7 +2274,7 @@ rb_reset_tail(struct ring_buffer_per_cpu *cpu_buffer, /* Set write to end of buffer */ length = (tail + length) - BUF_PAGE_SIZE; @@ -91977,7 +92623,7 @@ index 0954450..0ed035c 100644 } /* -@@ -2286,7 +2286,7 @@ rb_move_tail(struct ring_buffer_per_cpu *cpu_buffer, +@@ -2286,7 +2300,7 @@ rb_move_tail(struct ring_buffer_per_cpu *cpu_buffer, * about it. */ if (unlikely(next_page == commit_page)) { @@ -91986,7 +92632,7 @@ index 0954450..0ed035c 100644 goto out_reset; } -@@ -2342,7 +2342,7 @@ rb_move_tail(struct ring_buffer_per_cpu *cpu_buffer, +@@ -2342,7 +2356,7 @@ rb_move_tail(struct ring_buffer_per_cpu *cpu_buffer, cpu_buffer->tail_page) && (cpu_buffer->commit_page == cpu_buffer->reader_page))) { @@ -91995,7 +92641,7 @@ index 0954450..0ed035c 100644 goto out_reset; } } -@@ -2390,7 +2390,7 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer, +@@ -2390,7 +2404,7 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer, length += RB_LEN_TIME_EXTEND; tail_page = cpu_buffer->tail_page; @@ -92004,7 +92650,7 @@ index 0954450..0ed035c 100644 /* set write to only the index of the write */ write &= RB_WRITE_MASK; -@@ -2414,7 +2414,7 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer, +@@ -2414,7 +2428,7 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer, kmemcheck_annotate_bitfield(event, bitfield); rb_update_event(cpu_buffer, event, length, add_timestamp, delta); @@ -92013,7 +92659,7 @@ index 0954450..0ed035c 100644 /* * If this is the first commit on the page, then update -@@ -2447,7 +2447,7 @@ rb_try_to_discard(struct ring_buffer_per_cpu *cpu_buffer, +@@ -2447,7 +2461,7 @@ rb_try_to_discard(struct ring_buffer_per_cpu *cpu_buffer, if (bpage->page == (void *)addr && rb_page_write(bpage) == old_index) { unsigned long write_mask = @@ -92022,7 +92668,7 @@ index 0954450..0ed035c 100644 unsigned long event_length = rb_event_length(event); /* * This is on the tail page. It is possible that -@@ -2457,7 +2457,7 @@ rb_try_to_discard(struct ring_buffer_per_cpu *cpu_buffer, +@@ -2457,7 +2471,7 @@ rb_try_to_discard(struct ring_buffer_per_cpu *cpu_buffer, */ old_index += write_mask; new_index += write_mask; @@ -92031,7 +92677,7 @@ index 0954450..0ed035c 100644 if (index == old_index) { /* update counters */ local_sub(event_length, &cpu_buffer->entries_bytes); -@@ -2849,7 +2849,7 @@ rb_decrement_entry(struct ring_buffer_per_cpu *cpu_buffer, +@@ -2849,7 +2863,7 @@ rb_decrement_entry(struct ring_buffer_per_cpu *cpu_buffer, /* Do the likely case first */ if (likely(bpage->page == (void *)addr)) { @@ -92040,7 +92686,7 @@ index 0954450..0ed035c 100644 return; } -@@ -2861,7 +2861,7 @@ rb_decrement_entry(struct ring_buffer_per_cpu *cpu_buffer, +@@ -2861,7 +2875,7 @@ rb_decrement_entry(struct ring_buffer_per_cpu *cpu_buffer, start = bpage; do { if (bpage->page == (void *)addr) { @@ -92049,7 +92695,7 @@ index 0954450..0ed035c 100644 return; } rb_inc_page(cpu_buffer, &bpage); -@@ -3145,7 +3145,7 @@ static inline unsigned long +@@ -3145,7 +3159,7 @@ static inline unsigned long rb_num_of_entries(struct ring_buffer_per_cpu *cpu_buffer) { return local_read(&cpu_buffer->entries) - @@ -92058,7 +92704,7 @@ index 0954450..0ed035c 100644 } /** -@@ -3234,7 +3234,7 @@ unsigned long ring_buffer_overrun_cpu(struct ring_buffer *buffer, int cpu) +@@ -3234,7 +3248,7 @@ unsigned long ring_buffer_overrun_cpu(struct ring_buffer *buffer, int cpu) return 0; cpu_buffer = buffer->buffers[cpu]; @@ -92067,7 +92713,7 @@ index 0954450..0ed035c 100644 return ret; } -@@ -3257,7 +3257,7 @@ ring_buffer_commit_overrun_cpu(struct ring_buffer *buffer, int cpu) +@@ -3257,7 +3271,7 @@ ring_buffer_commit_overrun_cpu(struct ring_buffer *buffer, int cpu) return 0; cpu_buffer = buffer->buffers[cpu]; @@ -92076,7 +92722,7 @@ index 0954450..0ed035c 100644 return ret; } -@@ -3342,7 +3342,7 @@ unsigned long ring_buffer_overruns(struct ring_buffer *buffer) +@@ -3342,7 +3356,7 @@ unsigned long ring_buffer_overruns(struct ring_buffer *buffer) /* if you care about this being correct, lock the buffer */ for_each_buffer_cpu(buffer, cpu) { cpu_buffer = buffer->buffers[cpu]; @@ -92085,7 +92731,7 @@ index 0954450..0ed035c 100644 } return overruns; -@@ -3518,8 +3518,8 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer) +@@ -3518,8 +3532,8 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer) /* * Reset the reader page to size zero. */ @@ -92096,7 +92742,7 @@ index 0954450..0ed035c 100644 local_set(&cpu_buffer->reader_page->page->commit, 0); cpu_buffer->reader_page->real_end = 0; -@@ -3553,7 +3553,7 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer) +@@ -3553,7 +3567,7 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer) * want to compare with the last_overrun. */ smp_mb(); @@ -92105,7 +92751,7 @@ index 0954450..0ed035c 100644 /* * Here's the tricky part. -@@ -4123,8 +4123,8 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer) +@@ -4123,8 +4137,8 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer) cpu_buffer->head_page = list_entry(cpu_buffer->pages, struct buffer_page, list); @@ -92116,7 +92762,7 @@ index 0954450..0ed035c 100644 local_set(&cpu_buffer->head_page->page->commit, 0); cpu_buffer->head_page->read = 0; -@@ -4134,14 +4134,14 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer) +@@ -4134,14 +4148,14 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer) INIT_LIST_HEAD(&cpu_buffer->reader_page->list); INIT_LIST_HEAD(&cpu_buffer->new_pages); @@ -92135,7 +92781,7 @@ index 0954450..0ed035c 100644 local_set(&cpu_buffer->dropped_events, 0); local_set(&cpu_buffer->entries, 0); local_set(&cpu_buffer->committing, 0); -@@ -4546,8 +4546,8 @@ int ring_buffer_read_page(struct ring_buffer *buffer, +@@ -4546,8 +4560,8 @@ int ring_buffer_read_page(struct ring_buffer *buffer, rb_init_page(bpage); bpage = reader->page; reader->page = *data_page; @@ -92365,6 +93011,20 @@ index b4defde..f092808 100644 } spin_unlock_irq(&pool->lock); +diff --git a/lib/Kconfig b/lib/Kconfig +index 991c98b..88061cf 100644 +--- a/lib/Kconfig ++++ b/lib/Kconfig +@@ -51,6 +51,9 @@ config PERCPU_RWSEM + config ARCH_USE_CMPXCHG_LOCKREF + bool + ++config ARCH_HAS_FAST_MULTIPLIER ++ bool ++ + config CRC_CCITT + tristate "CRC-CCITT functions" + help diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index a48abea..e108def 100644 --- a/lib/Kconfig.debug @@ -92444,6 +93104,34 @@ index 48140e3..de854e5 100644 obj-$(CONFIG_DEBUG_OBJECTS) += debugobjects.o ifneq ($(CONFIG_HAVE_DEC_LOCK),y) +diff --git a/lib/assoc_array.c b/lib/assoc_array.c +index c0b1007..2404d03 100644 +--- a/lib/assoc_array.c ++++ b/lib/assoc_array.c +@@ -1723,11 +1723,13 @@ ascend_old_tree: + shortcut = assoc_array_ptr_to_shortcut(ptr); + slot = shortcut->parent_slot; + cursor = shortcut->back_pointer; ++ if (!cursor) ++ goto gc_complete; + } else { + slot = node->parent_slot; + cursor = ptr; + } +- BUG_ON(!ptr); ++ BUG_ON(!cursor); + node = assoc_array_ptr_to_node(cursor); + slot++; + goto continue_node; +@@ -1735,7 +1737,7 @@ ascend_old_tree: + gc_complete: + edit->set[0].to = new_root; + assoc_array_apply_edit(edit); +- edit->array->nr_leaves_on_tree = nr_leaves_on_tree; ++ array->nr_leaves_on_tree = nr_leaves_on_tree; + return 0; + + enomem: diff --git a/lib/average.c b/lib/average.c index 114d1be..ab0350c 100644 --- a/lib/average.c @@ -92602,6 +93290,28 @@ index fea973f..386626f 100644 .hash = jhash, .hash2 = jhash2, }; +diff --git a/lib/hweight.c b/lib/hweight.c +index b7d81ba..9a5c1f2 100644 +--- a/lib/hweight.c ++++ b/lib/hweight.c +@@ -11,7 +11,7 @@ + + unsigned int __sw_hweight32(unsigned int w) + { +-#ifdef ARCH_HAS_FAST_MULTIPLIER ++#ifdef CONFIG_ARCH_HAS_FAST_MULTIPLIER + w -= (w >> 1) & 0x55555555; + w = (w & 0x33333333) + ((w >> 2) & 0x33333333); + w = (w + (w >> 4)) & 0x0f0f0f0f; +@@ -49,7 +49,7 @@ unsigned long __sw_hweight64(__u64 w) + return __sw_hweight32((unsigned int)(w >> 32)) + + __sw_hweight32((unsigned int)w); + #elif BITS_PER_LONG == 64 +-#ifdef ARCH_HAS_FAST_MULTIPLIER ++#ifdef CONFIG_ARCH_HAS_FAST_MULTIPLIER + w -= (w >> 1) & 0x5555555555555555ul; + w = (w & 0x3333333333333333ul) + ((w >> 2) & 0x3333333333333333ul); + w = (w + (w >> 4)) & 0x0f0f0f0f0f0f0f0ful; diff --git a/lib/inflate.c b/lib/inflate.c index 013a761..c28f3fc 100644 --- a/lib/inflate.c @@ -92888,6 +93598,98 @@ index c24c2f7..f0296f4 100644 + pax_close_kernel(); +} +EXPORT_SYMBOL(pax_list_del_rcu); +diff --git a/lib/lockref.c b/lib/lockref.c +index f07a40d..0a445a7 100644 +--- a/lib/lockref.c ++++ b/lib/lockref.c +@@ -49,13 +49,13 @@ + void lockref_get(struct lockref *lockref) + { + CMPXCHG_LOOP( +- new.count++; ++ __lockref_inc(&new); + , + return; + ); + + spin_lock(&lockref->lock); +- lockref->count++; ++ __lockref_inc(lockref); + spin_unlock(&lockref->lock); + } + EXPORT_SYMBOL(lockref_get); +@@ -70,7 +70,7 @@ int lockref_get_not_zero(struct lockref *lockref) + int retval; + + CMPXCHG_LOOP( +- new.count++; ++ __lockref_inc(&new); + if (!old.count) + return 0; + , +@@ -80,7 +80,7 @@ int lockref_get_not_zero(struct lockref *lockref) + spin_lock(&lockref->lock); + retval = 0; + if (lockref->count) { +- lockref->count++; ++ __lockref_inc(lockref); + retval = 1; + } + spin_unlock(&lockref->lock); +@@ -97,7 +97,7 @@ EXPORT_SYMBOL(lockref_get_not_zero); + int lockref_get_or_lock(struct lockref *lockref) + { + CMPXCHG_LOOP( +- new.count++; ++ __lockref_inc(&new); + if (!old.count) + break; + , +@@ -107,7 +107,7 @@ int lockref_get_or_lock(struct lockref *lockref) + spin_lock(&lockref->lock); + if (!lockref->count) + return 0; +- lockref->count++; ++ __lockref_inc(lockref); + spin_unlock(&lockref->lock); + return 1; + } +@@ -121,7 +121,7 @@ EXPORT_SYMBOL(lockref_get_or_lock); + int lockref_put_or_lock(struct lockref *lockref) + { + CMPXCHG_LOOP( +- new.count--; ++ __lockref_dec(&new); + if (old.count <= 1) + break; + , +@@ -131,7 +131,7 @@ int lockref_put_or_lock(struct lockref *lockref) + spin_lock(&lockref->lock); + if (lockref->count <= 1) + return 0; +- lockref->count--; ++ __lockref_dec(lockref); + spin_unlock(&lockref->lock); + return 1; + } +@@ -158,7 +158,7 @@ int lockref_get_not_dead(struct lockref *lockref) + int retval; + + CMPXCHG_LOOP( +- new.count++; ++ __lockref_inc(&new); + if ((int)old.count < 0) + return 0; + , +@@ -168,7 +168,7 @@ int lockref_get_not_dead(struct lockref *lockref) + spin_lock(&lockref->lock); + retval = 0; + if ((int) lockref->count >= 0) { +- lockref->count++; ++ __lockref_inc(lockref); + retval = 1; + } + spin_unlock(&lockref->lock); diff --git a/lib/percpu-refcount.c b/lib/percpu-refcount.c index 963b703..438bc51 100644 --- a/lib/percpu-refcount.c @@ -92954,6 +93756,22 @@ index 0922579..9d7adb9 100644 + printk("%lu pages hwpoisoned\n", atomic_long_read_unchecked(&num_poisoned_pages)); #endif } +diff --git a/lib/string.c b/lib/string.c +index e5878de..315fad2 100644 +--- a/lib/string.c ++++ b/lib/string.c +@@ -789,9 +789,9 @@ void *memchr_inv(const void *start, int c, size_t bytes) + return check_bytes8(start, value, bytes); + + value64 = value; +-#if defined(ARCH_HAS_FAST_MULTIPLIER) && BITS_PER_LONG == 64 ++#if defined(CONFIG_ARCH_HAS_FAST_MULTIPLIER) && BITS_PER_LONG == 64 + value64 *= 0x0101010101010101; +-#elif defined(ARCH_HAS_FAST_MULTIPLIER) ++#elif defined(CONFIG_ARCH_HAS_FAST_MULTIPLIER) + value64 *= 0x01010101; + value64 |= value64 << 32; + #else diff --git a/lib/strncpy_from_user.c b/lib/strncpy_from_user.c index bb2b201..46abaf9 100644 --- a/lib/strncpy_from_user.c @@ -94567,7 +95385,7 @@ index b1eb536..091d154 100644 capable(CAP_IPC_LOCK)) ret = do_mlockall(flags); diff --git a/mm/mmap.c b/mm/mmap.c -index 20ff0c3..a9eda98 100644 +index 20ff0c3..005dc47 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -36,6 +36,7 @@ @@ -94640,15 +95458,20 @@ index 20ff0c3..a9eda98 100644 if (vma->vm_ops && vma->vm_ops->close) vma->vm_ops->close(vma); if (vma->vm_file) -@@ -290,6 +312,7 @@ SYSCALL_DEFINE1(brk, unsigned long, brk) +@@ -290,6 +312,12 @@ SYSCALL_DEFINE1(brk, unsigned long, brk) * not page aligned -Ram Gupta */ rlim = rlimit(RLIMIT_DATA); ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP ++ /* force a minimum 16MB brk heap on setuid/setgid binaries */ ++ if (rlim < PAGE_SIZE && (get_dumpable(mm) != SUID_DUMP_USER) && gr_is_global_nonroot(current_uid())) ++ rlim = 4096 * PAGE_SIZE; ++#endif + gr_learn_resource(current, RLIMIT_DATA, (brk - mm->start_brk) + (mm->end_data - mm->start_data), 1); if (rlim < RLIM_INFINITY && (brk - mm->start_brk) + (mm->end_data - mm->start_data) > rlim) goto out; -@@ -940,6 +963,12 @@ static int +@@ -940,6 +968,12 @@ static int can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags, struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff) { @@ -94661,7 +95484,7 @@ index 20ff0c3..a9eda98 100644 if (is_mergeable_vma(vma, file, vm_flags) && is_mergeable_anon_vma(anon_vma, vma->anon_vma, vma)) { if (vma->vm_pgoff == vm_pgoff) -@@ -959,6 +988,12 @@ static int +@@ -959,6 +993,12 @@ static int can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags, struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff) { @@ -94674,7 +95497,7 @@ index 20ff0c3..a9eda98 100644 if (is_mergeable_vma(vma, file, vm_flags) && is_mergeable_anon_vma(anon_vma, vma->anon_vma, vma)) { pgoff_t vm_pglen; -@@ -1001,13 +1036,20 @@ can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags, +@@ -1001,13 +1041,20 @@ can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags, struct vm_area_struct *vma_merge(struct mm_struct *mm, struct vm_area_struct *prev, unsigned long addr, unsigned long end, unsigned long vm_flags, @@ -94696,7 +95519,7 @@ index 20ff0c3..a9eda98 100644 /* * We later require that vma->vm_flags == vm_flags, * so this tests vma->vm_flags & VM_SPECIAL, too. -@@ -1023,6 +1065,15 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm, +@@ -1023,6 +1070,15 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm, if (next && next->vm_end == end) /* cases 6, 7, 8 */ next = next->vm_next; @@ -94712,7 +95535,7 @@ index 20ff0c3..a9eda98 100644 /* * Can it merge with the predecessor? */ -@@ -1042,9 +1093,24 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm, +@@ -1042,9 +1098,24 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm, /* cases 1, 6 */ err = vma_adjust(prev, prev->vm_start, next->vm_end, prev->vm_pgoff, NULL); @@ -94738,7 +95561,7 @@ index 20ff0c3..a9eda98 100644 if (err) return NULL; khugepaged_enter_vma_merge(prev); -@@ -1058,12 +1124,27 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm, +@@ -1058,12 +1129,27 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm, mpol_equal(policy, vma_policy(next)) && can_vma_merge_before(next, vm_flags, anon_vma, file, pgoff+pglen)) { @@ -94768,7 +95591,7 @@ index 20ff0c3..a9eda98 100644 if (err) return NULL; khugepaged_enter_vma_merge(area); -@@ -1172,8 +1253,10 @@ none: +@@ -1172,8 +1258,10 @@ none: void vm_stat_account(struct mm_struct *mm, unsigned long flags, struct file *file, long pages) { @@ -94781,7 +95604,7 @@ index 20ff0c3..a9eda98 100644 mm->total_vm += pages; -@@ -1181,7 +1264,7 @@ void vm_stat_account(struct mm_struct *mm, unsigned long flags, +@@ -1181,7 +1269,7 @@ void vm_stat_account(struct mm_struct *mm, unsigned long flags, mm->shared_vm += pages; if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC) mm->exec_vm += pages; @@ -94790,7 +95613,7 @@ index 20ff0c3..a9eda98 100644 mm->stack_vm += pages; } #endif /* CONFIG_PROC_FS */ -@@ -1211,6 +1294,7 @@ static inline int mlock_future_check(struct mm_struct *mm, +@@ -1211,6 +1299,7 @@ static inline int mlock_future_check(struct mm_struct *mm, locked += mm->locked_vm; lock_limit = rlimit(RLIMIT_MEMLOCK); lock_limit >>= PAGE_SHIFT; @@ -94798,7 +95621,7 @@ index 20ff0c3..a9eda98 100644 if (locked > lock_limit && !capable(CAP_IPC_LOCK)) return -EAGAIN; } -@@ -1237,7 +1321,7 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, +@@ -1237,7 +1326,7 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, * (the exception is when the underlying filesystem is noexec * mounted, in which case we dont add PROT_EXEC.) */ @@ -94807,7 +95630,7 @@ index 20ff0c3..a9eda98 100644 if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC))) prot |= PROT_EXEC; -@@ -1263,7 +1347,7 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, +@@ -1263,7 +1352,7 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, /* Obtain the address to map to. we verify (or select) it and ensure * that it represents a valid section of the address space. */ @@ -94816,7 +95639,7 @@ index 20ff0c3..a9eda98 100644 if (addr & ~PAGE_MASK) return addr; -@@ -1274,6 +1358,43 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, +@@ -1274,6 +1363,43 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) | mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC; @@ -94860,7 +95683,7 @@ index 20ff0c3..a9eda98 100644 if (flags & MAP_LOCKED) if (!can_do_mlock()) return -EPERM; -@@ -1361,6 +1482,9 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, +@@ -1361,6 +1487,9 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, vm_flags |= VM_NORESERVE; } @@ -94870,7 +95693,7 @@ index 20ff0c3..a9eda98 100644 addr = mmap_region(file, addr, len, vm_flags, pgoff); if (!IS_ERR_VALUE(addr) && ((vm_flags & VM_LOCKED) || -@@ -1454,7 +1578,7 @@ int vma_wants_writenotify(struct vm_area_struct *vma) +@@ -1454,7 +1583,7 @@ int vma_wants_writenotify(struct vm_area_struct *vma) vm_flags_t vm_flags = vma->vm_flags; /* If it was private or non-writable, the write bit is already clear */ @@ -94879,7 +95702,7 @@ index 20ff0c3..a9eda98 100644 return 0; /* The backer wishes to know when pages are first written to? */ -@@ -1500,7 +1624,22 @@ unsigned long mmap_region(struct file *file, unsigned long addr, +@@ -1500,7 +1629,22 @@ unsigned long mmap_region(struct file *file, unsigned long addr, struct rb_node **rb_link, *rb_parent; unsigned long charged = 0; @@ -94902,7 +95725,7 @@ index 20ff0c3..a9eda98 100644 if (!may_expand_vm(mm, len >> PAGE_SHIFT)) { unsigned long nr_pages; -@@ -1519,11 +1658,10 @@ unsigned long mmap_region(struct file *file, unsigned long addr, +@@ -1519,11 +1663,10 @@ unsigned long mmap_region(struct file *file, unsigned long addr, /* Clear old maps */ error = -ENOMEM; @@ -94915,7 +95738,7 @@ index 20ff0c3..a9eda98 100644 } /* -@@ -1554,6 +1692,16 @@ munmap_back: +@@ -1554,6 +1697,16 @@ munmap_back: goto unacct_error; } @@ -94932,7 +95755,7 @@ index 20ff0c3..a9eda98 100644 vma->vm_mm = mm; vma->vm_start = addr; vma->vm_end = addr + len; -@@ -1573,6 +1721,13 @@ munmap_back: +@@ -1573,6 +1726,13 @@ munmap_back: if (error) goto unmap_and_free_vma; @@ -94946,7 +95769,7 @@ index 20ff0c3..a9eda98 100644 /* Can addr have changed?? * * Answer: Yes, several device drivers can do it in their -@@ -1606,6 +1761,12 @@ munmap_back: +@@ -1606,6 +1766,12 @@ munmap_back: } vma_link(mm, vma, prev, rb_link, rb_parent); @@ -94959,7 +95782,7 @@ index 20ff0c3..a9eda98 100644 /* Once vma denies write, undo our temporary denial count */ if (vm_flags & VM_DENYWRITE) allow_write_access(file); -@@ -1614,6 +1775,7 @@ out: +@@ -1614,6 +1780,7 @@ out: perf_event_mmap(vma); vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT); @@ -94967,7 +95790,7 @@ index 20ff0c3..a9eda98 100644 if (vm_flags & VM_LOCKED) { if (!((vm_flags & VM_SPECIAL) || is_vm_hugetlb_page(vma) || vma == get_gate_vma(current->mm))) -@@ -1646,6 +1808,12 @@ unmap_and_free_vma: +@@ -1646,6 +1813,12 @@ unmap_and_free_vma: unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end); charged = 0; free_vma: @@ -94980,7 +95803,7 @@ index 20ff0c3..a9eda98 100644 kmem_cache_free(vm_area_cachep, vma); unacct_error: if (charged) -@@ -1653,7 +1821,63 @@ unacct_error: +@@ -1653,7 +1826,63 @@ unacct_error: return error; } @@ -95045,7 +95868,7 @@ index 20ff0c3..a9eda98 100644 { /* * We implement the search by looking for an rbtree node that -@@ -1701,11 +1925,29 @@ unsigned long unmapped_area(struct vm_unmapped_area_info *info) +@@ -1701,11 +1930,29 @@ unsigned long unmapped_area(struct vm_unmapped_area_info *info) } } @@ -95076,7 +95899,7 @@ index 20ff0c3..a9eda98 100644 if (gap_end >= low_limit && gap_end - gap_start >= length) goto found; -@@ -1755,7 +1997,7 @@ found: +@@ -1755,7 +2002,7 @@ found: return gap_start; } @@ -95085,7 +95908,7 @@ index 20ff0c3..a9eda98 100644 { struct mm_struct *mm = current->mm; struct vm_area_struct *vma; -@@ -1809,6 +2051,24 @@ check_current: +@@ -1809,6 +2056,24 @@ check_current: gap_end = vma->vm_start; if (gap_end < low_limit) return -ENOMEM; @@ -95110,7 +95933,7 @@ index 20ff0c3..a9eda98 100644 if (gap_start <= high_limit && gap_end - gap_start >= length) goto found; -@@ -1872,6 +2132,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, +@@ -1872,6 +2137,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, struct mm_struct *mm = current->mm; struct vm_area_struct *vma; struct vm_unmapped_area_info info; @@ -95118,7 +95941,7 @@ index 20ff0c3..a9eda98 100644 if (len > TASK_SIZE - mmap_min_addr) return -ENOMEM; -@@ -1879,11 +2140,15 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, +@@ -1879,11 +2145,15 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, if (flags & MAP_FIXED) return addr; @@ -95135,7 +95958,7 @@ index 20ff0c3..a9eda98 100644 return addr; } -@@ -1892,6 +2157,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, +@@ -1892,6 +2162,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, info.low_limit = mm->mmap_base; info.high_limit = TASK_SIZE; info.align_mask = 0; @@ -95143,7 +95966,7 @@ index 20ff0c3..a9eda98 100644 return vm_unmapped_area(&info); } #endif -@@ -1910,6 +2176,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, +@@ -1910,6 +2181,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, struct mm_struct *mm = current->mm; unsigned long addr = addr0; struct vm_unmapped_area_info info; @@ -95151,7 +95974,7 @@ index 20ff0c3..a9eda98 100644 /* requested length too big for entire address space */ if (len > TASK_SIZE - mmap_min_addr) -@@ -1918,12 +2185,16 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, +@@ -1918,12 +2190,16 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, if (flags & MAP_FIXED) return addr; @@ -95169,7 +95992,7 @@ index 20ff0c3..a9eda98 100644 return addr; } -@@ -1932,6 +2203,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, +@@ -1932,6 +2208,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, info.low_limit = max(PAGE_SIZE, mmap_min_addr); info.high_limit = mm->mmap_base; info.align_mask = 0; @@ -95177,7 +96000,7 @@ index 20ff0c3..a9eda98 100644 addr = vm_unmapped_area(&info); /* -@@ -1944,6 +2216,12 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, +@@ -1944,6 +2221,12 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, VM_BUG_ON(addr != -ENOMEM); info.flags = 0; info.low_limit = TASK_UNMAPPED_BASE; @@ -95190,7 +96013,7 @@ index 20ff0c3..a9eda98 100644 info.high_limit = TASK_SIZE; addr = vm_unmapped_area(&info); } -@@ -2045,6 +2323,28 @@ find_vma_prev(struct mm_struct *mm, unsigned long addr, +@@ -2045,6 +2328,28 @@ find_vma_prev(struct mm_struct *mm, unsigned long addr, return vma; } @@ -95219,7 +96042,7 @@ index 20ff0c3..a9eda98 100644 /* * Verify that the stack growth is acceptable and * update accounting. This is shared with both the -@@ -2061,6 +2361,7 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns +@@ -2061,6 +2366,7 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns return -ENOMEM; /* Stack limit test */ @@ -95227,7 +96050,7 @@ index 20ff0c3..a9eda98 100644 if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur)) return -ENOMEM; -@@ -2071,6 +2372,7 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns +@@ -2071,6 +2377,7 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns locked = mm->locked_vm + grow; limit = ACCESS_ONCE(rlim[RLIMIT_MEMLOCK].rlim_cur); limit >>= PAGE_SHIFT; @@ -95235,7 +96058,7 @@ index 20ff0c3..a9eda98 100644 if (locked > limit && !capable(CAP_IPC_LOCK)) return -ENOMEM; } -@@ -2100,37 +2402,48 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns +@@ -2100,37 +2407,48 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns * PA-RISC uses this for its stack; IA64 for its Register Backing Store. * vma is the last one with address > vma->vm_end. Have to extend vma. */ @@ -95293,7 +96116,7 @@ index 20ff0c3..a9eda98 100644 unsigned long size, grow; size = address - vma->vm_start; -@@ -2165,6 +2478,8 @@ int expand_upwards(struct vm_area_struct *vma, unsigned long address) +@@ -2165,6 +2483,8 @@ int expand_upwards(struct vm_area_struct *vma, unsigned long address) } } } @@ -95302,7 +96125,7 @@ index 20ff0c3..a9eda98 100644 vma_unlock_anon_vma(vma); khugepaged_enter_vma_merge(vma); validate_mm(vma->vm_mm); -@@ -2179,6 +2494,8 @@ int expand_downwards(struct vm_area_struct *vma, +@@ -2179,6 +2499,8 @@ int expand_downwards(struct vm_area_struct *vma, unsigned long address) { int error; @@ -95311,7 +96134,7 @@ index 20ff0c3..a9eda98 100644 /* * We must make sure the anon_vma is allocated -@@ -2192,6 +2509,15 @@ int expand_downwards(struct vm_area_struct *vma, +@@ -2192,6 +2514,15 @@ int expand_downwards(struct vm_area_struct *vma, if (error) return error; @@ -95327,7 +96150,7 @@ index 20ff0c3..a9eda98 100644 vma_lock_anon_vma(vma); /* -@@ -2201,9 +2527,17 @@ int expand_downwards(struct vm_area_struct *vma, +@@ -2201,9 +2532,17 @@ int expand_downwards(struct vm_area_struct *vma, */ /* Somebody else might have raced and expanded it already */ @@ -95346,7 +96169,7 @@ index 20ff0c3..a9eda98 100644 size = vma->vm_end - address; grow = (vma->vm_start - address) >> PAGE_SHIFT; -@@ -2228,13 +2562,27 @@ int expand_downwards(struct vm_area_struct *vma, +@@ -2228,13 +2567,27 @@ int expand_downwards(struct vm_area_struct *vma, vma->vm_pgoff -= grow; anon_vma_interval_tree_post_update_vma(vma); vma_gap_update(vma); @@ -95374,7 +96197,7 @@ index 20ff0c3..a9eda98 100644 khugepaged_enter_vma_merge(vma); validate_mm(vma->vm_mm); return error; -@@ -2332,6 +2680,13 @@ static void remove_vma_list(struct mm_struct *mm, struct vm_area_struct *vma) +@@ -2332,6 +2685,13 @@ static void remove_vma_list(struct mm_struct *mm, struct vm_area_struct *vma) do { long nrpages = vma_pages(vma); @@ -95388,7 +96211,7 @@ index 20ff0c3..a9eda98 100644 if (vma->vm_flags & VM_ACCOUNT) nr_accounted += nrpages; vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages); -@@ -2376,6 +2731,16 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -2376,6 +2736,16 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma, insertion_point = (prev ? &prev->vm_next : &mm->mmap); vma->vm_prev = NULL; do { @@ -95405,7 +96228,7 @@ index 20ff0c3..a9eda98 100644 vma_rb_erase(vma, &mm->mm_rb); mm->map_count--; tail_vma = vma; -@@ -2401,14 +2766,33 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, +@@ -2401,14 +2771,33 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, struct vm_area_struct *new; int err = -ENOMEM; @@ -95439,7 +96262,7 @@ index 20ff0c3..a9eda98 100644 /* most fields are the same, copy all, and then fixup */ *new = *vma; -@@ -2421,6 +2805,22 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, +@@ -2421,6 +2810,22 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT); } @@ -95462,7 +96285,7 @@ index 20ff0c3..a9eda98 100644 err = vma_dup_policy(vma, new); if (err) goto out_free_vma; -@@ -2440,6 +2840,38 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, +@@ -2440,6 +2845,38 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, else err = vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new); @@ -95501,7 +96324,7 @@ index 20ff0c3..a9eda98 100644 /* Success. */ if (!err) return 0; -@@ -2449,10 +2881,18 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, +@@ -2449,10 +2886,18 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, new->vm_ops->close(new); if (new->vm_file) fput(new->vm_file); @@ -95521,7 +96344,7 @@ index 20ff0c3..a9eda98 100644 kmem_cache_free(vm_area_cachep, new); out_err: return err; -@@ -2465,6 +2905,15 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, +@@ -2465,6 +2910,15 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, int split_vma(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, int new_below) { @@ -95537,7 +96360,7 @@ index 20ff0c3..a9eda98 100644 if (mm->map_count >= sysctl_max_map_count) return -ENOMEM; -@@ -2476,11 +2925,30 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -2476,11 +2930,30 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma, * work. This now handles partial unmappings. * Jeremy Fitzhardinge <jeremy@goop.org> */ @@ -95568,7 +96391,7 @@ index 20ff0c3..a9eda98 100644 if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start) return -EINVAL; -@@ -2555,6 +3023,8 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len) +@@ -2555,6 +3028,8 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len) /* Fix up all other VM information */ remove_vma_list(mm, vma); @@ -95577,7 +96400,7 @@ index 20ff0c3..a9eda98 100644 return 0; } -@@ -2563,6 +3033,13 @@ int vm_munmap(unsigned long start, size_t len) +@@ -2563,6 +3038,13 @@ int vm_munmap(unsigned long start, size_t len) int ret; struct mm_struct *mm = current->mm; @@ -95591,7 +96414,7 @@ index 20ff0c3..a9eda98 100644 down_write(&mm->mmap_sem); ret = do_munmap(mm, start, len); up_write(&mm->mmap_sem); -@@ -2576,16 +3053,6 @@ SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) +@@ -2576,16 +3058,6 @@ SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) return vm_munmap(addr, len); } @@ -95608,7 +96431,7 @@ index 20ff0c3..a9eda98 100644 /* * this is really a simplified "do_mmap". it only handles * anonymous maps. eventually we may be able to do some -@@ -2599,6 +3066,7 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) +@@ -2599,6 +3071,7 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) struct rb_node ** rb_link, * rb_parent; pgoff_t pgoff = addr >> PAGE_SHIFT; int error; @@ -95616,7 +96439,7 @@ index 20ff0c3..a9eda98 100644 len = PAGE_ALIGN(len); if (!len) -@@ -2606,10 +3074,24 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) +@@ -2606,10 +3079,24 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags; @@ -95641,7 +96464,7 @@ index 20ff0c3..a9eda98 100644 error = mlock_future_check(mm, mm->def_flags, len); if (error) return error; -@@ -2623,21 +3105,20 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) +@@ -2623,21 +3110,20 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) /* * Clear old maps. this also does some error checking for us */ @@ -95666,7 +96489,7 @@ index 20ff0c3..a9eda98 100644 return -ENOMEM; /* Can we just expand an old private anonymous mapping? */ -@@ -2651,7 +3132,7 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) +@@ -2651,7 +3137,7 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) */ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); if (!vma) { @@ -95675,7 +96498,7 @@ index 20ff0c3..a9eda98 100644 return -ENOMEM; } -@@ -2665,10 +3146,11 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) +@@ -2665,10 +3151,11 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) vma_link(mm, vma, prev, rb_link, rb_parent); out: perf_event_mmap(vma); @@ -95689,7 +96512,7 @@ index 20ff0c3..a9eda98 100644 return addr; } -@@ -2730,6 +3212,7 @@ void exit_mmap(struct mm_struct *mm) +@@ -2730,6 +3217,7 @@ void exit_mmap(struct mm_struct *mm) while (vma) { if (vma->vm_flags & VM_ACCOUNT) nr_accounted += vma_pages(vma); @@ -95697,7 +96520,7 @@ index 20ff0c3..a9eda98 100644 vma = remove_vma(vma); } vm_unacct_memory(nr_accounted); -@@ -2747,6 +3230,13 @@ int insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vma) +@@ -2747,6 +3235,13 @@ int insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vma) struct vm_area_struct *prev; struct rb_node **rb_link, *rb_parent; @@ -95711,7 +96534,7 @@ index 20ff0c3..a9eda98 100644 /* * The vm_pgoff of a purely anonymous vma should be irrelevant * until its first write fault, when page's anon_vma and index -@@ -2770,7 +3260,21 @@ int insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vma) +@@ -2770,7 +3265,21 @@ int insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vma) security_vm_enough_memory_mm(mm, vma_pages(vma))) return -ENOMEM; @@ -95733,7 +96556,7 @@ index 20ff0c3..a9eda98 100644 return 0; } -@@ -2789,6 +3293,8 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, +@@ -2789,6 +3298,8 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, struct rb_node **rb_link, *rb_parent; bool faulted_in_anon_vma = true; @@ -95742,7 +96565,7 @@ index 20ff0c3..a9eda98 100644 /* * If anonymous vma has not yet been faulted, update new pgoff * to match new location, to increase its chance of merging. -@@ -2853,6 +3359,39 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, +@@ -2853,6 +3364,39 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, return NULL; } @@ -95782,7 +96605,7 @@ index 20ff0c3..a9eda98 100644 /* * Return true if the calling process may expand its vm space by the passed * number of pages -@@ -2864,6 +3403,7 @@ int may_expand_vm(struct mm_struct *mm, unsigned long npages) +@@ -2864,6 +3408,7 @@ int may_expand_vm(struct mm_struct *mm, unsigned long npages) lim = rlimit(RLIMIT_AS) >> PAGE_SHIFT; @@ -95790,7 +96613,7 @@ index 20ff0c3..a9eda98 100644 if (cur + npages > lim) return 0; return 1; -@@ -2934,6 +3474,22 @@ int install_special_mapping(struct mm_struct *mm, +@@ -2934,6 +3479,22 @@ int install_special_mapping(struct mm_struct *mm, vma->vm_start = addr; vma->vm_end = addr + len; @@ -96370,6 +97193,19 @@ index a2a54a8..43ecb68 100644 EXPORT_SYMBOL_GPL(pcpu_base_addr); static const int *pcpu_unit_map __read_mostly; /* cpu -> unit */ +diff --git a/mm/pgtable-generic.c b/mm/pgtable-generic.c +index a8b9199..dfb79e0 100644 +--- a/mm/pgtable-generic.c ++++ b/mm/pgtable-generic.c +@@ -195,7 +195,7 @@ void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, + pmd_t entry = *pmdp; + if (pmd_numa(entry)) + entry = pmd_mknonnuma(entry); +- set_pmd_at(vma->vm_mm, address, pmdp, pmd_mknotpresent(*pmdp)); ++ set_pmd_at(vma->vm_mm, address, pmdp, pmd_mknotpresent(entry)); + flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE); + } + #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ diff --git a/mm/process_vm_access.c b/mm/process_vm_access.c index fd26d04..0cea1b0 100644 --- a/mm/process_vm_access.c @@ -97695,10 +98531,10 @@ index 4a7f7e6..22cddf5 100644 if (S_ISREG(inode->i_mode)) diff --git a/mm/util.c b/mm/util.c -index a24aa22..a0d41ae 100644 +index c1010cb..91e1a36 100644 --- a/mm/util.c +++ b/mm/util.c -@@ -297,6 +297,12 @@ done: +@@ -294,6 +294,12 @@ done: void arch_pick_mmap_layout(struct mm_struct *mm) { mm->mmap_base = TASK_UNMAPPED_BASE; @@ -98413,10 +99249,10 @@ index d074d06..ad3cfcf 100644 if (ogm_packet->flags & BATADV_DIRECTLINK) has_directlink_flag = true; diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c -index cc1cfd6..7a68e022 100644 +index c46387a..6ad5ef9 100644 --- a/net/batman-adv/fragmentation.c +++ b/net/batman-adv/fragmentation.c -@@ -446,7 +446,7 @@ bool batadv_frag_send_packet(struct sk_buff *skb, +@@ -450,7 +450,7 @@ bool batadv_frag_send_packet(struct sk_buff *skb, frag_header.packet_type = BATADV_UNICAST_FRAG; frag_header.version = BATADV_COMPAT_VERSION; frag_header.ttl = BATADV_TTL; @@ -98756,6 +99592,340 @@ index b543470..d2ddae2 100644 if (!can_dir) { printk(KERN_INFO "can: failed to create /proc/net/can . " +diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c +index 96238ba..de6662b 100644 +--- a/net/ceph/auth_x.c ++++ b/net/ceph/auth_x.c +@@ -13,8 +13,6 @@ + #include "auth_x.h" + #include "auth_x_protocol.h" + +-#define TEMP_TICKET_BUF_LEN 256 +- + static void ceph_x_validate_tickets(struct ceph_auth_client *ac, int *pneed); + + static int ceph_x_is_authenticated(struct ceph_auth_client *ac) +@@ -64,7 +62,7 @@ static int ceph_x_encrypt(struct ceph_crypto_key *secret, + } + + static int ceph_x_decrypt(struct ceph_crypto_key *secret, +- void **p, void *end, void *obuf, size_t olen) ++ void **p, void *end, void **obuf, size_t olen) + { + struct ceph_x_encrypt_header head; + size_t head_len = sizeof(head); +@@ -75,8 +73,14 @@ static int ceph_x_decrypt(struct ceph_crypto_key *secret, + return -EINVAL; + + dout("ceph_x_decrypt len %d\n", len); +- ret = ceph_decrypt2(secret, &head, &head_len, obuf, &olen, +- *p, len); ++ if (*obuf == NULL) { ++ *obuf = kmalloc(len, GFP_NOFS); ++ if (!*obuf) ++ return -ENOMEM; ++ olen = len; ++ } ++ ++ ret = ceph_decrypt2(secret, &head, &head_len, *obuf, &olen, *p, len); + if (ret) + return ret; + if (head.struct_v != 1 || le64_to_cpu(head.magic) != CEPHX_ENC_MAGIC) +@@ -129,145 +133,154 @@ static void remove_ticket_handler(struct ceph_auth_client *ac, + kfree(th); + } + ++static int process_one_ticket(struct ceph_auth_client *ac, ++ struct ceph_crypto_key *secret, ++ void **p, void *end) ++{ ++ struct ceph_x_info *xi = ac->private; ++ int type; ++ u8 tkt_struct_v, blob_struct_v; ++ struct ceph_x_ticket_handler *th; ++ void *dbuf = NULL; ++ void *dp, *dend; ++ int dlen; ++ char is_enc; ++ struct timespec validity; ++ struct ceph_crypto_key old_key; ++ void *ticket_buf = NULL; ++ void *tp, *tpend; ++ struct ceph_timespec new_validity; ++ struct ceph_crypto_key new_session_key; ++ struct ceph_buffer *new_ticket_blob; ++ unsigned long new_expires, new_renew_after; ++ u64 new_secret_id; ++ int ret; ++ ++ ceph_decode_need(p, end, sizeof(u32) + 1, bad); ++ ++ type = ceph_decode_32(p); ++ dout(" ticket type %d %s\n", type, ceph_entity_type_name(type)); ++ ++ tkt_struct_v = ceph_decode_8(p); ++ if (tkt_struct_v != 1) ++ goto bad; ++ ++ th = get_ticket_handler(ac, type); ++ if (IS_ERR(th)) { ++ ret = PTR_ERR(th); ++ goto out; ++ } ++ ++ /* blob for me */ ++ dlen = ceph_x_decrypt(secret, p, end, &dbuf, 0); ++ if (dlen <= 0) { ++ ret = dlen; ++ goto out; ++ } ++ dout(" decrypted %d bytes\n", dlen); ++ dp = dbuf; ++ dend = dp + dlen; ++ ++ tkt_struct_v = ceph_decode_8(&dp); ++ if (tkt_struct_v != 1) ++ goto bad; ++ ++ memcpy(&old_key, &th->session_key, sizeof(old_key)); ++ ret = ceph_crypto_key_decode(&new_session_key, &dp, dend); ++ if (ret) ++ goto out; ++ ++ ceph_decode_copy(&dp, &new_validity, sizeof(new_validity)); ++ ceph_decode_timespec(&validity, &new_validity); ++ new_expires = get_seconds() + validity.tv_sec; ++ new_renew_after = new_expires - (validity.tv_sec / 4); ++ dout(" expires=%lu renew_after=%lu\n", new_expires, ++ new_renew_after); ++ ++ /* ticket blob for service */ ++ ceph_decode_8_safe(p, end, is_enc, bad); ++ if (is_enc) { ++ /* encrypted */ ++ dout(" encrypted ticket\n"); ++ dlen = ceph_x_decrypt(&old_key, p, end, &ticket_buf, 0); ++ if (dlen < 0) { ++ ret = dlen; ++ goto out; ++ } ++ tp = ticket_buf; ++ dlen = ceph_decode_32(&tp); ++ } else { ++ /* unencrypted */ ++ ceph_decode_32_safe(p, end, dlen, bad); ++ ticket_buf = kmalloc(dlen, GFP_NOFS); ++ if (!ticket_buf) { ++ ret = -ENOMEM; ++ goto out; ++ } ++ tp = ticket_buf; ++ ceph_decode_need(p, end, dlen, bad); ++ ceph_decode_copy(p, ticket_buf, dlen); ++ } ++ tpend = tp + dlen; ++ dout(" ticket blob is %d bytes\n", dlen); ++ ceph_decode_need(&tp, tpend, 1 + sizeof(u64), bad); ++ blob_struct_v = ceph_decode_8(&tp); ++ new_secret_id = ceph_decode_64(&tp); ++ ret = ceph_decode_buffer(&new_ticket_blob, &tp, tpend); ++ if (ret) ++ goto out; ++ ++ /* all is well, update our ticket */ ++ ceph_crypto_key_destroy(&th->session_key); ++ if (th->ticket_blob) ++ ceph_buffer_put(th->ticket_blob); ++ th->session_key = new_session_key; ++ th->ticket_blob = new_ticket_blob; ++ th->validity = new_validity; ++ th->secret_id = new_secret_id; ++ th->expires = new_expires; ++ th->renew_after = new_renew_after; ++ dout(" got ticket service %d (%s) secret_id %lld len %d\n", ++ type, ceph_entity_type_name(type), th->secret_id, ++ (int)th->ticket_blob->vec.iov_len); ++ xi->have_keys |= th->service; ++ ++out: ++ kfree(ticket_buf); ++ kfree(dbuf); ++ return ret; ++ ++bad: ++ ret = -EINVAL; ++ goto out; ++} ++ + static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac, + struct ceph_crypto_key *secret, + void *buf, void *end) + { +- struct ceph_x_info *xi = ac->private; +- int num; + void *p = buf; +- int ret; +- char *dbuf; +- char *ticket_buf; + u8 reply_struct_v; ++ u32 num; ++ int ret; + +- dbuf = kmalloc(TEMP_TICKET_BUF_LEN, GFP_NOFS); +- if (!dbuf) +- return -ENOMEM; +- +- ret = -ENOMEM; +- ticket_buf = kmalloc(TEMP_TICKET_BUF_LEN, GFP_NOFS); +- if (!ticket_buf) +- goto out_dbuf; +- +- ceph_decode_need(&p, end, 1 + sizeof(u32), bad); +- reply_struct_v = ceph_decode_8(&p); ++ ceph_decode_8_safe(&p, end, reply_struct_v, bad); + if (reply_struct_v != 1) +- goto bad; +- num = ceph_decode_32(&p); ++ return -EINVAL; ++ ++ ceph_decode_32_safe(&p, end, num, bad); + dout("%d tickets\n", num); ++ + while (num--) { +- int type; +- u8 tkt_struct_v, blob_struct_v; +- struct ceph_x_ticket_handler *th; +- void *dp, *dend; +- int dlen; +- char is_enc; +- struct timespec validity; +- struct ceph_crypto_key old_key; +- void *tp, *tpend; +- struct ceph_timespec new_validity; +- struct ceph_crypto_key new_session_key; +- struct ceph_buffer *new_ticket_blob; +- unsigned long new_expires, new_renew_after; +- u64 new_secret_id; +- +- ceph_decode_need(&p, end, sizeof(u32) + 1, bad); +- +- type = ceph_decode_32(&p); +- dout(" ticket type %d %s\n", type, ceph_entity_type_name(type)); +- +- tkt_struct_v = ceph_decode_8(&p); +- if (tkt_struct_v != 1) +- goto bad; +- +- th = get_ticket_handler(ac, type); +- if (IS_ERR(th)) { +- ret = PTR_ERR(th); +- goto out; +- } +- +- /* blob for me */ +- dlen = ceph_x_decrypt(secret, &p, end, dbuf, +- TEMP_TICKET_BUF_LEN); +- if (dlen <= 0) { +- ret = dlen; +- goto out; +- } +- dout(" decrypted %d bytes\n", dlen); +- dend = dbuf + dlen; +- dp = dbuf; +- +- tkt_struct_v = ceph_decode_8(&dp); +- if (tkt_struct_v != 1) +- goto bad; +- +- memcpy(&old_key, &th->session_key, sizeof(old_key)); +- ret = ceph_crypto_key_decode(&new_session_key, &dp, dend); ++ ret = process_one_ticket(ac, secret, &p, end); + if (ret) +- goto out; +- +- ceph_decode_copy(&dp, &new_validity, sizeof(new_validity)); +- ceph_decode_timespec(&validity, &new_validity); +- new_expires = get_seconds() + validity.tv_sec; +- new_renew_after = new_expires - (validity.tv_sec / 4); +- dout(" expires=%lu renew_after=%lu\n", new_expires, +- new_renew_after); +- +- /* ticket blob for service */ +- ceph_decode_8_safe(&p, end, is_enc, bad); +- tp = ticket_buf; +- if (is_enc) { +- /* encrypted */ +- dout(" encrypted ticket\n"); +- dlen = ceph_x_decrypt(&old_key, &p, end, ticket_buf, +- TEMP_TICKET_BUF_LEN); +- if (dlen < 0) { +- ret = dlen; +- goto out; +- } +- dlen = ceph_decode_32(&tp); +- } else { +- /* unencrypted */ +- ceph_decode_32_safe(&p, end, dlen, bad); +- ceph_decode_need(&p, end, dlen, bad); +- ceph_decode_copy(&p, ticket_buf, dlen); +- } +- tpend = tp + dlen; +- dout(" ticket blob is %d bytes\n", dlen); +- ceph_decode_need(&tp, tpend, 1 + sizeof(u64), bad); +- blob_struct_v = ceph_decode_8(&tp); +- new_secret_id = ceph_decode_64(&tp); +- ret = ceph_decode_buffer(&new_ticket_blob, &tp, tpend); +- if (ret) +- goto out; +- +- /* all is well, update our ticket */ +- ceph_crypto_key_destroy(&th->session_key); +- if (th->ticket_blob) +- ceph_buffer_put(th->ticket_blob); +- th->session_key = new_session_key; +- th->ticket_blob = new_ticket_blob; +- th->validity = new_validity; +- th->secret_id = new_secret_id; +- th->expires = new_expires; +- th->renew_after = new_renew_after; +- dout(" got ticket service %d (%s) secret_id %lld len %d\n", +- type, ceph_entity_type_name(type), th->secret_id, +- (int)th->ticket_blob->vec.iov_len); +- xi->have_keys |= th->service; ++ return ret; + } + +- ret = 0; +-out: +- kfree(ticket_buf); +-out_dbuf: +- kfree(dbuf); +- return ret; ++ return 0; + + bad: +- ret = -EINVAL; +- goto out; ++ return -EINVAL; + } + + static int ceph_x_build_authorizer(struct ceph_auth_client *ac, +@@ -583,13 +596,14 @@ static int ceph_x_verify_authorizer_reply(struct ceph_auth_client *ac, + struct ceph_x_ticket_handler *th; + int ret = 0; + struct ceph_x_authorize_reply reply; ++ void *preply = &reply; + void *p = au->reply_buf; + void *end = p + sizeof(au->reply_buf); + + th = get_ticket_handler(ac, au->service); + if (IS_ERR(th)) + return PTR_ERR(th); +- ret = ceph_x_decrypt(&th->session_key, &p, end, &reply, sizeof(reply)); ++ ret = ceph_x_decrypt(&th->session_key, &p, end, &preply, sizeof(reply)); + if (ret < 0) + return ret; + if (ret != sizeof(reply)) diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index 988721a..947846d 100644 --- a/net/ceph/messenger.c @@ -98778,8 +99948,28 @@ index 988721a..947846d 100644 s = addr_str[i]; switch (ss->ss_family) { +diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c +index 2ac9ef3..dbcbf5a 100644 +--- a/net/ceph/mon_client.c ++++ b/net/ceph/mon_client.c +@@ -1041,7 +1041,15 @@ static struct ceph_msg *mon_alloc_msg(struct ceph_connection *con, + if (!m) { + pr_info("alloc_msg unknown type %d\n", type); + *skip = 1; ++ } else if (front_len > m->front_alloc_len) { ++ pr_warning("mon_alloc_msg front %d > prealloc %d (%u#%llu)\n", ++ front_len, m->front_alloc_len, ++ (unsigned int)con->peer_name.type, ++ le64_to_cpu(con->peer_name.num)); ++ ceph_msg_put(m); ++ m = ceph_msg_new(type, front_len, GFP_NOFS, false); + } ++ + return m; + } + diff --git a/net/compat.c b/net/compat.c -index f50161f..ab7644e 100644 +index cbc1a2a..ab7644e 100644 --- a/net/compat.c +++ b/net/compat.c @@ -73,9 +73,9 @@ int get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr __user *umsg) @@ -98795,28 +99985,17 @@ index f50161f..ab7644e 100644 return 0; } -@@ -85,21 +85,22 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov, - { - int tot_len; +@@ -87,7 +87,7 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov, -- if (kern_msg->msg_namelen) { -+ if (kern_msg->msg_name && kern_msg->msg_namelen) { + if (kern_msg->msg_name && kern_msg->msg_namelen) { if (mode == VERIFY_READ) { - int err = move_addr_to_kernel(kern_msg->msg_name, + int err = move_addr_to_kernel((void __force_user *)kern_msg->msg_name, kern_msg->msg_namelen, kern_address); if (err < 0) - return err; - } -- if (kern_msg->msg_name) -- kern_msg->msg_name = kern_address; -- } else -+ kern_msg->msg_name = kern_address; -+ } else { - kern_msg->msg_name = NULL; -+ kern_msg->msg_namelen = 0; -+ } +@@ -100,7 +100,7 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov, + } tot_len = iov_from_user_compat_to_kern(kern_iov, - (struct compat_iovec __user *)kern_msg->msg_iov, @@ -98824,7 +100003,7 @@ index f50161f..ab7644e 100644 kern_msg->msg_iovlen); if (tot_len >= 0) kern_msg->msg_iov = kern_iov; -@@ -119,20 +120,20 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov, +@@ -120,20 +120,20 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov, #define CMSG_COMPAT_FIRSTHDR(msg) \ (((msg)->msg_controllen) >= sizeof(struct compat_cmsghdr) ? \ @@ -98848,7 +100027,7 @@ index f50161f..ab7644e 100644 msg->msg_controllen) return NULL; return (struct compat_cmsghdr __user *)ptr; -@@ -222,7 +223,7 @@ Efault: +@@ -223,7 +223,7 @@ Efault: int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *data) { @@ -98857,7 +100036,7 @@ index f50161f..ab7644e 100644 struct compat_cmsghdr cmhdr; struct compat_timeval ctv; struct compat_timespec cts[3]; -@@ -278,7 +279,7 @@ int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *dat +@@ -279,7 +279,7 @@ int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *dat void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm) { @@ -98866,7 +100045,7 @@ index f50161f..ab7644e 100644 int fdmax = (kmsg->msg_controllen - sizeof(struct compat_cmsghdr)) / sizeof(int); int fdnum = scm->fp->count; struct file **fp = scm->fp->fp; -@@ -366,7 +367,7 @@ static int do_set_sock_timeout(struct socket *sock, int level, +@@ -367,7 +367,7 @@ static int do_set_sock_timeout(struct socket *sock, int level, return -EFAULT; old_fs = get_fs(); set_fs(KERNEL_DS); @@ -98875,7 +100054,7 @@ index f50161f..ab7644e 100644 set_fs(old_fs); return err; -@@ -427,7 +428,7 @@ static int do_get_sock_timeout(struct socket *sock, int level, int optname, +@@ -428,7 +428,7 @@ static int do_get_sock_timeout(struct socket *sock, int level, int optname, len = sizeof(ktime); old_fs = get_fs(); set_fs(KERNEL_DS); @@ -98884,7 +100063,7 @@ index f50161f..ab7644e 100644 set_fs(old_fs); if (!err) { -@@ -570,7 +571,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname, +@@ -571,7 +571,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname, case MCAST_JOIN_GROUP: case MCAST_LEAVE_GROUP: { @@ -98893,7 +100072,7 @@ index f50161f..ab7644e 100644 struct group_req __user *kgr = compat_alloc_user_space(sizeof(struct group_req)); u32 interface; -@@ -591,7 +592,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname, +@@ -592,7 +592,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname, case MCAST_BLOCK_SOURCE: case MCAST_UNBLOCK_SOURCE: { @@ -98902,7 +100081,7 @@ index f50161f..ab7644e 100644 struct group_source_req __user *kgsr = compat_alloc_user_space( sizeof(struct group_source_req)); u32 interface; -@@ -612,7 +613,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname, +@@ -613,7 +613,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname, } case MCAST_MSFILTER: { @@ -98911,7 +100090,7 @@ index f50161f..ab7644e 100644 struct group_filter __user *kgf; u32 interface, fmode, numsrc; -@@ -650,7 +651,7 @@ int compat_mc_getsockopt(struct sock *sock, int level, int optname, +@@ -651,7 +651,7 @@ int compat_mc_getsockopt(struct sock *sock, int level, int optname, char __user *optval, int __user *optlen, int (*getsockopt)(struct sock *, int, int, char __user *, int __user *)) { @@ -98920,7 +100099,7 @@ index f50161f..ab7644e 100644 struct group_filter __user *kgf; int __user *koptlen; u32 interface, fmode, numsrc; -@@ -803,7 +804,7 @@ asmlinkage long compat_sys_socketcall(int call, u32 __user *args) +@@ -804,7 +804,7 @@ asmlinkage long compat_sys_socketcall(int call, u32 __user *args) if (call < SYS_SOCKET || call > SYS_SENDMMSG) return -EINVAL; @@ -99145,15 +100324,11 @@ index dfa602c..3103d88 100644 fle->object = flo; else diff --git a/net/core/iovec.c b/net/core/iovec.c -index b618694..cd5f0af 100644 +index 26dc006..89e838e 100644 --- a/net/core/iovec.c +++ b/net/core/iovec.c -@@ -39,23 +39,23 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr_storage *a - { - int size, ct, err; - -- if (m->msg_namelen) { -+ if (m->msg_name && m->msg_namelen) { +@@ -42,7 +42,7 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr_storage *a + if (m->msg_name && m->msg_namelen) { if (mode == VERIFY_READ) { void __user *namep; - namep = (void __user __force *) m->msg_name; @@ -99161,14 +100336,7 @@ index b618694..cd5f0af 100644 err = move_addr_to_kernel(namep, m->msg_namelen, address); if (err < 0) - return err; - } -- if (m->msg_name) -- m->msg_name = address; -+ m->msg_name = address; - } else { - m->msg_name = NULL; -+ m->msg_namelen = 0; +@@ -55,7 +55,7 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr_storage *a } size = m->msg_iovlen * sizeof(struct iovec); @@ -99421,44 +100589,8 @@ index b442e7e..6f5b5a2 100644 i++, cmfptr++) { struct socket *sock; -diff --git a/net/core/secure_seq.c b/net/core/secure_seq.c -index 897da56..ba71212 100644 ---- a/net/core/secure_seq.c -+++ b/net/core/secure_seq.c -@@ -85,31 +85,6 @@ EXPORT_SYMBOL(secure_ipv6_port_ephemeral); - #endif - - #ifdef CONFIG_INET --__u32 secure_ip_id(__be32 daddr) --{ -- u32 hash[MD5_DIGEST_WORDS]; -- -- net_secret_init(); -- hash[0] = (__force __u32) daddr; -- hash[1] = net_secret[13]; -- hash[2] = net_secret[14]; -- hash[3] = net_secret[15]; -- -- md5_transform(hash, net_secret); -- -- return hash[0]; --} -- --__u32 secure_ipv6_id(const __be32 daddr[4]) --{ -- __u32 hash[4]; -- -- net_secret_init(); -- memcpy(hash, daddr, 16); -- md5_transform(hash, net_secret); -- -- return hash[0]; --} - - __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr, - __be16 sport, __be16 dport) diff --git a/net/core/skbuff.c b/net/core/skbuff.c -index 7f2e1fc..6206b10 100644 +index 8f6391b..40bc442 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -2003,7 +2003,7 @@ EXPORT_SYMBOL(__skb_checksum); @@ -99921,28 +101053,6 @@ index 9d43468..ffa28cc 100644 return nh->nh_saddr; } -diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c -index 9db3b87..0ffcd4d 100644 ---- a/net/ipv4/igmp.c -+++ b/net/ipv4/igmp.c -@@ -369,7 +369,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) - pip->saddr = fl4.saddr; - pip->protocol = IPPROTO_IGMP; - pip->tot_len = 0; /* filled in later */ -- ip_select_ident(skb, &rt->dst, NULL); -+ ip_select_ident(skb, NULL); - ((u8 *)&pip[1])[0] = IPOPT_RA; - ((u8 *)&pip[1])[1] = 4; - ((u8 *)&pip[1])[2] = 0; -@@ -714,7 +714,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc, - iph->daddr = dst; - iph->saddr = fl4.saddr; - iph->protocol = IPPROTO_IGMP; -- ip_select_ident(skb, &rt->dst, NULL); -+ ip_select_ident(skb, NULL); - ((u8 *)&iph[1])[0] = IPOPT_RA; - ((u8 *)&iph[1])[1] = 4; - ((u8 *)&iph[1])[2] = 0; diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 0d1e2cb..4501a2c 100644 --- a/net/ipv4/inet_connection_sock.c @@ -99987,47 +101097,14 @@ index 8b9cf27..0d8d592 100644 inet_twsk_deschedule(tw, death_row); while (twrefcnt) { diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c -index 48f4244..d83ba8a 100644 +index bf2cb4a..d83ba8a 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c -@@ -26,20 +26,7 @@ - * Theory of operations. - * We keep one entry for each peer IP address. The nodes contains long-living - * information about the peer which doesn't depend on routes. -- * At this moment this information consists only of ID field for the next -- * outgoing IP packet. This field is incremented with each packet as encoded -- * in inet_getid() function (include/net/inetpeer.h). -- * At the moment of writing this notes identifier of IP packets is generated -- * to be unpredictable using this code only for packets subjected -- * (actually or potentially) to defragmentation. I.e. DF packets less than -- * PMTU in size when local fragmentation is disabled use a constant ID and do -- * not use this code (see ip_select_ident() in include/net/ip.h). - * -- * Route cache entries hold references to our nodes. -- * New cache entries get references via lookup by destination IP address in -- * the avl tree. The reference is grabbed only when it's needed i.e. only -- * when we try to output IP packet which needs an unpredictable ID (see -- * __ip_select_ident() in net/ipv4/route.c). - * Nodes are removed only when reference counter goes to 0. - * When it's happened the node may be removed when a sufficient amount of - * time has been passed since its last use. The less-recently-used entry can -@@ -62,7 +49,6 @@ - * refcnt: atomically against modifications on other CPU; - * usually under some other lock to prevent node disappearing - * daddr: unchangeable -- * ip_id_count: atomic value (no lock needed) - */ - - static struct kmem_cache *peer_cachep __read_mostly; -@@ -496,11 +482,7 @@ relookup: +@@ -482,7 +482,7 @@ relookup: if (p) { p->daddr = *daddr; atomic_set(&p->refcnt, 1); - atomic_set(&p->rid, 0); -- atomic_set(&p->ip_id_count, -- (daddr->family == AF_INET) ? -- secure_ip_id(daddr->addr.a4) : -- secure_ipv6_id(daddr->addr.a6)); + atomic_set_unchecked(&p->rid, 0); p->metrics[RTAX_LOCK-1] = INETPEER_METRICS_NEW; p->rate_tokens = 0; @@ -100114,38 +101191,6 @@ index 94213c8..8bdb342 100644 .kind = "gretap", .maxtype = IFLA_GRE_MAX, .policy = ipgre_policy, -diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c -index 73c6b63..ed88d78 100644 ---- a/net/ipv4/ip_output.c -+++ b/net/ipv4/ip_output.c -@@ -148,7 +148,7 @@ int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk, - iph->daddr = (opt && opt->opt.srr ? opt->opt.faddr : daddr); - iph->saddr = saddr; - iph->protocol = sk->sk_protocol; -- ip_select_ident(skb, &rt->dst, sk); -+ ip_select_ident(skb, sk); - - if (opt && opt->opt.optlen) { - iph->ihl += opt->opt.optlen>>2; -@@ -386,8 +386,7 @@ packet_routed: - ip_options_build(skb, &inet_opt->opt, inet->inet_daddr, rt, 0); - } - -- ip_select_ident_more(skb, &rt->dst, sk, -- (skb_shinfo(skb)->gso_segs ?: 1) - 1); -+ ip_select_ident_segs(skb, sk, skb_shinfo(skb)->gso_segs ?: 1); - - skb->priority = sk->sk_priority; - skb->mark = sk->sk_mark; -@@ -1338,7 +1337,7 @@ struct sk_buff *__ip_make_skb(struct sock *sk, - iph->ttl = ttl; - iph->protocol = sk->sk_protocol; - ip_copy_addrs(iph, fl4); -- ip_select_ident(skb, &rt->dst, sk); -+ ip_select_ident(skb, sk); - - if (opt) { - iph->ihl += opt->optlen>>2; diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 580dd96..9fcef7e 100644 --- a/net/ipv4/ip_sockglue.c @@ -100169,19 +101214,6 @@ index 580dd96..9fcef7e 100644 msg.msg_controllen = len; msg.msg_flags = flags; -diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c -index 8d69626..65b664d 100644 ---- a/net/ipv4/ip_tunnel_core.c -+++ b/net/ipv4/ip_tunnel_core.c -@@ -74,7 +74,7 @@ int iptunnel_xmit(struct rtable *rt, struct sk_buff *skb, - iph->daddr = dst; - iph->saddr = src; - iph->ttl = ttl; -- __ip_select_ident(iph, &rt->dst, (skb_shinfo(skb)->gso_segs ?: 1) - 1); -+ __ip_select_ident(iph, skb_shinfo(skb)->gso_segs ?: 1); - - err = ip_local_out(skb); - if (unlikely(net_xmit_eval(err))) diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index e4a8f76..dd8ad72 100644 --- a/net/ipv4/ip_vti.c @@ -100257,19 +101289,6 @@ index 62eaa00..29b2dc2 100644 .kind = "ipip", .maxtype = IFLA_IPTUN_MAX, .policy = ipip_policy, -diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c -index 2886357..1149fc2 100644 ---- a/net/ipv4/ipmr.c -+++ b/net/ipv4/ipmr.c -@@ -1663,7 +1663,7 @@ static void ip_encap(struct sk_buff *skb, __be32 saddr, __be32 daddr) - iph->protocol = IPPROTO_IPIP; - iph->ihl = 5; - iph->tot_len = htons(skb->len); -- ip_select_ident(skb, skb_dst(skb), NULL); -+ ip_select_ident(skb, NULL); - ip_send_check(iph); - - memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index f95b6f9..2ee2097 100644 --- a/net/ipv4/netfilter/arp_tables.c @@ -100453,7 +101472,7 @@ index e21934b..4e7cb58 100644 static int ping_v4_seq_show(struct seq_file *seq, void *v) diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c -index c04518f..d67116b 100644 +index 11c8d81..d67116b 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -311,7 +311,7 @@ static int raw_rcv_skb(struct sock *sk, struct sk_buff *skb) @@ -100465,15 +101484,6 @@ index c04518f..d67116b 100644 kfree_skb(skb); return NET_RX_DROP; } -@@ -389,7 +389,7 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4, - iph->check = 0; - iph->tot_len = htons(length); - if (!iph->id) -- ip_select_ident(skb, &rt->dst, NULL); -+ ip_select_ident(skb, NULL); - - iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); - } @@ -748,16 +748,20 @@ static int raw_init(struct sock *sk) static int raw_seticmpfilter(struct sock *sk, char __user *optval, int optlen) @@ -100517,18 +101527,10 @@ index c04518f..d67116b 100644 static int raw_seq_show(struct seq_file *seq, void *v) diff --git a/net/ipv4/route.c b/net/ipv4/route.c -index 031553f..1f6f4e2 100644 +index ca5a01e..8c5cdb4 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c -@@ -89,6 +89,7 @@ - #include <linux/rcupdate.h> - #include <linux/times.h> - #include <linux/slab.h> -+#include <linux/jhash.h> - #include <net/dst.h> - #include <net/net_namespace.h> - #include <net/protocol.h> -@@ -233,7 +234,7 @@ static const struct seq_operations rt_cache_seq_ops = { +@@ -234,7 +234,7 @@ static const struct seq_operations rt_cache_seq_ops = { static int rt_cache_seq_open(struct inode *inode, struct file *file) { @@ -100537,7 +101539,7 @@ index 031553f..1f6f4e2 100644 } static const struct file_operations rt_cache_seq_fops = { -@@ -324,7 +325,7 @@ static const struct seq_operations rt_cpu_seq_ops = { +@@ -325,7 +325,7 @@ static const struct seq_operations rt_cpu_seq_ops = { static int rt_cpu_seq_open(struct inode *inode, struct file *file) { @@ -100546,7 +101548,7 @@ index 031553f..1f6f4e2 100644 } static const struct file_operations rt_cpu_seq_fops = { -@@ -362,7 +363,7 @@ static int rt_acct_proc_show(struct seq_file *m, void *v) +@@ -363,7 +363,7 @@ static int rt_acct_proc_show(struct seq_file *m, void *v) static int rt_acct_proc_open(struct inode *inode, struct file *file) { @@ -100555,78 +101557,30 @@ index 031553f..1f6f4e2 100644 } static const struct file_operations rt_acct_proc_fops = { -@@ -462,39 +463,45 @@ static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst, - return neigh_create(&arp_tbl, pkey, dev); - } +@@ -465,11 +465,11 @@ static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst, --/* -- * Peer allocation may fail only in serious out-of-memory conditions. However -- * we still can generate some output. -- * Random ID selection looks a bit dangerous because we have no chances to -- * select ID being unique in a reasonable period of time. -- * But broken packet identifier may be better than no packet at all. -+#define IP_IDENTS_SZ 2048u -+struct ip_ident_bucket { + #define IP_IDENTS_SZ 2048u + struct ip_ident_bucket { +- atomic_t id; + atomic_unchecked_t id; -+ u32 stamp32; -+}; -+ -+static struct ip_ident_bucket *ip_idents __read_mostly; -+ -+/* In order to protect privacy, we add a perturbation to identifiers -+ * if one generator is seldom used. This makes hard for an attacker -+ * to infer how many packets were sent between two points in time. - */ --static void ip_select_fb_ident(struct iphdr *iph) -+u32 ip_idents_reserve(u32 hash, int segs) - { -- static DEFINE_SPINLOCK(ip_fb_id_lock); -- static u32 ip_fallback_id; -- u32 salt; -+ struct ip_ident_bucket *bucket = ip_idents + hash % IP_IDENTS_SZ; -+ u32 old = ACCESS_ONCE(bucket->stamp32); -+ u32 now = (u32)jiffies; -+ u32 delta = 0; - -- spin_lock_bh(&ip_fb_id_lock); -- salt = secure_ip_id((__force __be32)ip_fallback_id ^ iph->daddr); -- iph->id = htons(salt & 0xFFFF); -- ip_fallback_id = salt; -- spin_unlock_bh(&ip_fb_id_lock); -+ if (old != now && cmpxchg(&bucket->stamp32, old, now) == old) -+ delta = prandom_u32_max(now - old); -+ -+ return atomic_add_return_unchecked(segs + delta, &bucket->id) - segs; - } -+EXPORT_SYMBOL(ip_idents_reserve); + u32 stamp32; + }; --void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more) -+void __ip_select_ident(struct iphdr *iph, int segs) - { -- struct net *net = dev_net(dst->dev); -- struct inet_peer *peer; -+ static u32 ip_idents_hashrnd __read_mostly; -+ u32 hash, id; +-static struct ip_ident_bucket *ip_idents __read_mostly; ++static struct ip_ident_bucket ip_idents[IP_IDENTS_SZ] __read_mostly; -- peer = inet_getpeer_v4(net->ipv4.peers, iph->daddr, 1); -- if (peer) { -- iph->id = htons(inet_getid(peer, more)); -- inet_putpeer(peer); -- return; -- } -+ net_get_random_once(&ip_idents_hashrnd, sizeof(ip_idents_hashrnd)); + /* In order to protect privacy, we add a perturbation to identifiers + * if one generator is seldom used. This makes hard for an attacker +@@ -485,7 +485,7 @@ u32 ip_idents_reserve(u32 hash, int segs) + if (old != now && cmpxchg(&bucket->stamp32, old, now) == old) + delta = prandom_u32_max(now - old); -- ip_select_fb_ident(iph); -+ hash = jhash_3words((__force u32)iph->daddr, -+ (__force u32)iph->saddr, -+ iph->protocol, -+ ip_idents_hashrnd); -+ id = ip_idents_reserve(hash, segs); -+ iph->id = htons(id); +- return atomic_add_return(segs + delta, &bucket->id) - segs; ++ return atomic_add_return_unchecked(segs + delta, &bucket->id) - segs; } - EXPORT_SYMBOL(__ip_select_ident); + EXPORT_SYMBOL(ip_idents_reserve); -@@ -2624,34 +2631,34 @@ static struct ctl_table ipv4_route_flush_table[] = { +@@ -2631,34 +2631,34 @@ static struct ctl_table ipv4_route_flush_table[] = { .maxlen = sizeof(int), .mode = 0200, .proc_handler = ipv4_sysctl_rtcache_flush, @@ -100669,7 +101623,7 @@ index 031553f..1f6f4e2 100644 err_dup: return -ENOMEM; } -@@ -2674,8 +2681,8 @@ static __net_initdata struct pernet_operations sysctl_route_ops = { +@@ -2681,8 +2681,8 @@ static __net_initdata struct pernet_operations sysctl_route_ops = { static __net_init int rt_genid_init(struct net *net) { @@ -100680,19 +101634,19 @@ index 031553f..1f6f4e2 100644 get_random_bytes(&net->ipv4.dev_addr_genid, sizeof(net->ipv4.dev_addr_genid)); return 0; -@@ -2718,6 +2725,12 @@ int __init ip_rt_init(void) +@@ -2725,11 +2725,7 @@ int __init ip_rt_init(void) { int rc = 0; -+ ip_idents = kmalloc(IP_IDENTS_SZ * sizeof(*ip_idents), GFP_KERNEL); -+ if (!ip_idents) -+ panic("IP: failed to allocate ip_idents\n"); -+ -+ prandom_bytes(ip_idents, IP_IDENTS_SZ * sizeof(*ip_idents)); -+ +- ip_idents = kmalloc(IP_IDENTS_SZ * sizeof(*ip_idents), GFP_KERNEL); +- if (!ip_idents) +- panic("IP: failed to allocate ip_idents\n"); +- +- prandom_bytes(ip_idents, IP_IDENTS_SZ * sizeof(*ip_idents)); ++ prandom_bytes(ip_idents, sizeof(ip_idents)); + #ifdef CONFIG_IP_ROUTE_CLASSID ip_rt_acct = __alloc_percpu(256 * sizeof(struct ip_rt_acct), __alignof__(struct ip_rt_acct)); - if (!ip_rt_acct) diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 44eba05..b36864b 100644 --- a/net/ipv4/sysctl_net_ipv4.c @@ -100989,33 +101943,6 @@ index 64f0354..a81b39d 100644 if (retransmits_timed_out(sk, retry_until, syn_set ? 0 : icsk->icsk_user_timeout, syn_set)) { /* Has it gone just too far? */ -diff --git a/net/ipv4/tcp_vegas.c b/net/ipv4/tcp_vegas.c -index 06cae62..6b1a5fd 100644 ---- a/net/ipv4/tcp_vegas.c -+++ b/net/ipv4/tcp_vegas.c -@@ -219,7 +219,8 @@ static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack, u32 acked, - * This is: - * (actual rate in segments) * baseRTT - */ -- target_cwnd = tp->snd_cwnd * vegas->baseRTT / rtt; -+ target_cwnd = (u64)tp->snd_cwnd * vegas->baseRTT; -+ do_div(target_cwnd, rtt); - - /* Calculate the difference between the window we had, - * and the window we would like to have. This quantity -diff --git a/net/ipv4/tcp_veno.c b/net/ipv4/tcp_veno.c -index 326475a..603ad49 100644 ---- a/net/ipv4/tcp_veno.c -+++ b/net/ipv4/tcp_veno.c -@@ -145,7 +145,7 @@ static void tcp_veno_cong_avoid(struct sock *sk, u32 ack, u32 acked, - - rtt = veno->minrtt; - -- target_cwnd = (tp->snd_cwnd * veno->basertt); -+ target_cwnd = (u64)tp->snd_cwnd * veno->basertt; - target_cwnd <<= V_PARAM_SHIFT; - do_div(target_cwnd, rtt); - diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index b25e852..cdc3258 100644 --- a/net/ipv4/udp.c @@ -101134,24 +102061,6 @@ index b25e852..cdc3258 100644 } int udp4_seq_show(struct seq_file *seq, void *v) -diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c -index 31b1815..1f564a1 100644 ---- a/net/ipv4/xfrm4_mode_tunnel.c -+++ b/net/ipv4/xfrm4_mode_tunnel.c -@@ -117,12 +117,12 @@ static int xfrm4_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) - - top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ? - 0 : (XFRM_MODE_SKB_CB(skb)->frag_off & htons(IP_DF)); -- ip_select_ident(skb, dst->child, NULL); - - top_iph->ttl = ip4_dst_hoplimit(dst->child); - - top_iph->saddr = x->props.saddr.a4; - top_iph->daddr = x->id.daddr.a4; -+ ip_select_ident(skb, NULL); - - return 0; - } diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index e1a6393..f634ce5 100644 --- a/net/ipv4/xfrm4_policy.c @@ -101206,7 +102115,7 @@ index e1a6393..f634ce5 100644 return -ENOMEM; } diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c -index 6c7fa08..8a31430 100644 +index 6c7fa08..7c5abd70 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -598,7 +598,7 @@ static int inet6_netconf_dump_devconf(struct sk_buff *skb, @@ -101261,7 +102170,21 @@ index 6c7fa08..8a31430 100644 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { idx = 0; head = &net->dev_index_head[h]; -@@ -4758,7 +4765,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) +@@ -4746,11 +4753,8 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) + + rt = rt6_lookup(dev_net(dev), &ifp->peer_addr, NULL, + dev->ifindex, 1); +- if (rt) { +- dst_hold(&rt->dst); +- if (ip6_del_rt(rt)) +- dst_free(&rt->dst); +- } ++ if (rt && ip6_del_rt(rt)) ++ dst_free(&rt->dst); + } + dst_hold(&ifp->rt->dst); + +@@ -4758,7 +4762,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) dst_free(&ifp->rt->dst); break; } @@ -101270,7 +102193,7 @@ index 6c7fa08..8a31430 100644 rt_genid_bump_ipv6(net); } -@@ -4779,7 +4786,7 @@ int addrconf_sysctl_forward(struct ctl_table *ctl, int write, +@@ -4779,7 +4783,7 @@ int addrconf_sysctl_forward(struct ctl_table *ctl, int write, int *valp = ctl->data; int val = *valp; loff_t pos = *ppos; @@ -101279,7 +102202,7 @@ index 6c7fa08..8a31430 100644 int ret; /* -@@ -4864,7 +4871,7 @@ int addrconf_sysctl_disable(struct ctl_table *ctl, int write, +@@ -4864,7 +4868,7 @@ int addrconf_sysctl_disable(struct ctl_table *ctl, int write, int *valp = ctl->data; int val = *valp; loff_t pos = *ppos; @@ -101365,31 +102288,6 @@ index 2465d18..bc5bf7f 100644 .kind = "ip6gretap", .maxtype = IFLA_GRE_MAX, .policy = ip6gre_policy, -diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c -index a62b610..073e5a6 100644 ---- a/net/ipv6/ip6_output.c -+++ b/net/ipv6/ip6_output.c -@@ -537,6 +537,20 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from) - skb_copy_secmark(to, from); - } - -+static void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt) -+{ -+ static u32 ip6_idents_hashrnd __read_mostly; -+ u32 hash, id; -+ -+ net_get_random_once(&ip6_idents_hashrnd, sizeof(ip6_idents_hashrnd)); -+ -+ hash = __ipv6_addr_jhash(&rt->rt6i_dst.addr, ip6_idents_hashrnd); -+ hash = __ipv6_addr_jhash(&rt->rt6i_src.addr, hash); -+ -+ id = ip_idents_reserve(hash, 1); -+ fhdr->identification = htonl(id); -+} -+ - int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) - { - struct sk_buff *frag; diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 9120339..cfdd84f 100644 --- a/net/ipv6/ip6_tunnel.c @@ -101538,41 +102436,6 @@ index 767ab8d..c5ec70a 100644 err_alloc: return -ENOMEM; } -diff --git a/net/ipv6/output_core.c b/net/ipv6/output_core.c -index b31a012..ab2f47d 100644 ---- a/net/ipv6/output_core.c -+++ b/net/ipv6/output_core.c -@@ -7,30 +7,6 @@ - #include <net/ip6_fib.h> - #include <net/addrconf.h> - --void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt) --{ -- static atomic_t ipv6_fragmentation_id; -- int ident; -- --#if IS_ENABLED(CONFIG_IPV6) -- if (rt && !(rt->dst.flags & DST_NOPEER)) { -- struct inet_peer *peer; -- struct net *net; -- -- net = dev_net(rt->dst.dev); -- peer = inet_getpeer_v6(net->ipv6.peers, &rt->rt6i_dst.addr, 1); -- if (peer) { -- fhdr->identification = htonl(inet_getid(peer, 0)); -- inet_putpeer(peer); -- return; -- } -- } --#endif -- ident = atomic_inc_return(&ipv6_fragmentation_id); -- fhdr->identification = htonl(ident); --} --EXPORT_SYMBOL(ipv6_select_ident); -- - int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) - { - u16 offset = sizeof(struct ipv6hdr); diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c index bda7429..469b26b 100644 --- a/net/ipv6/ping.c @@ -102591,18 +103454,9 @@ index db80126..ef7110e 100644 cp->old_state = cp->state; /* diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c -index c47444e..e9a86e6 100644 +index 7f0e1cf..e9a86e6 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c -@@ -883,7 +883,7 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, - iph->daddr = cp->daddr.ip; - iph->saddr = saddr; - iph->ttl = old_iph->ttl; -- ip_select_ident(skb, &rt->dst, NULL); -+ ip_select_ident(skb, NULL); - - /* Another hack: avoid icmp_send in ip_fragment */ - skb->local_df = 1; @@ -1102,7 +1102,7 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, else rc = NF_ACCEPT; @@ -102997,10 +103851,18 @@ index b74aa07..d41926e 100644 *uaddr_len = sizeof(struct sockaddr_ax25); } diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c -index 48a6a93..0b0496e 100644 +index 48a6a93..d2c096b 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c -@@ -1845,7 +1845,7 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, +@@ -635,6 +635,7 @@ static void init_prb_bdqc(struct packet_sock *po, + p1->tov_in_jiffies = msecs_to_jiffies(p1->retire_blk_tov); + p1->blk_sizeof_priv = req_u->req3.tp_sizeof_priv; + ++ p1->max_frame_len = p1->kblk_size - BLK_PLUS_PRIV(p1->blk_sizeof_priv); + prb_init_ft_ops(p1, req_u); + prb_setup_retire_blk_timer(po, tx_ring); + prb_open_block(p1, pbd); +@@ -1845,7 +1846,7 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, spin_lock(&sk->sk_receive_queue.lock); po->stats.stats1.tp_packets++; @@ -103009,7 +103871,7 @@ index 48a6a93..0b0496e 100644 __skb_queue_tail(&sk->sk_receive_queue, skb); spin_unlock(&sk->sk_receive_queue.lock); sk->sk_data_ready(sk, skb->len); -@@ -1854,7 +1854,7 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, +@@ -1854,7 +1855,7 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, drop_n_acct: spin_lock(&sk->sk_receive_queue.lock); po->stats.stats1.tp_drops++; @@ -103018,7 +103880,26 @@ index 48a6a93..0b0496e 100644 spin_unlock(&sk->sk_receive_queue.lock); drop_n_restore: -@@ -3449,7 +3449,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, +@@ -1946,6 +1947,18 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, + if ((int)snaplen < 0) + snaplen = 0; + } ++ } else if (unlikely(macoff + snaplen > ++ GET_PBDQC_FROM_RB(&po->rx_ring)->max_frame_len)) { ++ u32 nval; ++ ++ nval = GET_PBDQC_FROM_RB(&po->rx_ring)->max_frame_len - macoff; ++ pr_err_once("tpacket_rcv: packet too big, clamped from %u to %u. macoff=%u\n", ++ snaplen, nval, macoff); ++ snaplen = nval; ++ if (unlikely((int)snaplen < 0)) { ++ snaplen = 0; ++ macoff = GET_PBDQC_FROM_RB(&po->rx_ring)->max_frame_len; ++ } + } + spin_lock(&sk->sk_receive_queue.lock); + h.raw = packet_current_rx_frame(po, skb, +@@ -3449,7 +3462,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, case PACKET_HDRLEN: if (len > sizeof(int)) len = sizeof(int); @@ -103027,7 +103908,7 @@ index 48a6a93..0b0496e 100644 return -EFAULT; switch (val) { case TPACKET_V1: -@@ -3495,7 +3495,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, +@@ -3495,7 +3508,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, len = lv; if (put_user(len, optlen)) return -EFAULT; @@ -103036,6 +103917,29 @@ index 48a6a93..0b0496e 100644 return -EFAULT; return 0; } +@@ -3779,6 +3792,10 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, + goto out; + if (unlikely(req->tp_block_size & (PAGE_SIZE - 1))) + goto out; ++ if (po->tp_version >= TPACKET_V3 && ++ (int)(req->tp_block_size - ++ BLK_PLUS_PRIV(req_u->req3.tp_sizeof_priv)) <= 0) ++ goto out; + if (unlikely(req->tp_frame_size < po->tp_hdrlen + + po->tp_reserve)) + goto out; +diff --git a/net/packet/internal.h b/net/packet/internal.h +index eb9580a..cdddf6a 100644 +--- a/net/packet/internal.h ++++ b/net/packet/internal.h +@@ -29,6 +29,7 @@ struct tpacket_kbdq_core { + char *pkblk_start; + char *pkblk_end; + int kblk_size; ++ unsigned int max_frame_len; + unsigned int knum_blocks; + uint64_t knxt_seq_num; + char *prev; diff --git a/net/phonet/pep.c b/net/phonet/pep.c index e774117..900b8b7 100644 --- a/net/phonet/pep.c @@ -103519,18 +104423,6 @@ index f226709..0e735a8 100644 _proto("Tx RESPONSE %%%u", ntohl(hdr->serial)); ret = kernel_sendmsg(conn->trans->local->socket, &msg, iov, 3, len); -diff --git a/net/sctp/associola.c b/net/sctp/associola.c -index a4d5701..5d97d8f 100644 ---- a/net/sctp/associola.c -+++ b/net/sctp/associola.c -@@ -1151,6 +1151,7 @@ void sctp_assoc_update(struct sctp_association *asoc, - asoc->c = new->c; - asoc->peer.rwnd = new->peer.rwnd; - asoc->peer.sack_needed = new->peer.sack_needed; -+ asoc->peer.auth_capable = new->peer.auth_capable; - asoc->peer.i = new->peer.i; - sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_INITIAL, - asoc->peer.i.initial_tsn, GFP_ATOMIC); diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 2b1738e..a9d0fc9 100644 --- a/net/sctp/ipv6.c @@ -103762,7 +104654,7 @@ index dfa532f..1dcfb44 100644 } diff --git a/net/socket.c b/net/socket.c -index a19ae19..89554dc 100644 +index a19ae19..edb5c03 100644 --- a/net/socket.c +++ b/net/socket.c @@ -88,6 +88,7 @@ @@ -103946,7 +104838,17 @@ index a19ae19..89554dc 100644 int err, err2; int fput_needed; -@@ -2065,7 +2131,7 @@ static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg, +@@ -1987,6 +2053,9 @@ static int copy_msghdr_from_user(struct msghdr *kmsg, + if (copy_from_user(kmsg, umsg, sizeof(struct msghdr))) + return -EFAULT; + ++ if (kmsg->msg_name == NULL) ++ kmsg->msg_namelen = 0; ++ + if (kmsg->msg_namelen < 0) + return -EINVAL; + +@@ -2065,7 +2134,7 @@ static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg, * checking falls down on this. */ if (copy_from_user(ctl_buf, @@ -103955,7 +104857,7 @@ index a19ae19..89554dc 100644 ctl_len)) goto out_freectl; msg_sys->msg_control = ctl_buf; -@@ -2216,7 +2282,7 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg, +@@ -2216,7 +2285,7 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg, int err, total_len, len; /* kernel mode address */ @@ -103964,7 +104866,7 @@ index a19ae19..89554dc 100644 /* user mode address pointers */ struct sockaddr __user *uaddr; -@@ -2245,7 +2311,7 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg, +@@ -2245,7 +2314,7 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg, /* Save the user-mode address (verify_iovec will change the * kernel msghdr to use the kernel address space) */ @@ -103973,7 +104875,7 @@ index a19ae19..89554dc 100644 uaddr_len = COMPAT_NAMELEN(msg); if (MSG_CMSG_COMPAT & flags) err = verify_compat_iovec(msg_sys, iov, &addr, VERIFY_WRITE); -@@ -2889,7 +2955,7 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32) +@@ -2889,7 +2958,7 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32) ifr = compat_alloc_user_space(buf_size); rxnfc = (void __user *)ifr + ALIGN(sizeof(struct ifreq), 8); @@ -103982,7 +104884,7 @@ index a19ae19..89554dc 100644 return -EFAULT; if (put_user(convert_in ? rxnfc : compat_ptr(data), -@@ -3000,7 +3066,7 @@ static int bond_ioctl(struct net *net, unsigned int cmd, +@@ -3000,7 +3069,7 @@ static int bond_ioctl(struct net *net, unsigned int cmd, old_fs = get_fs(); set_fs(KERNEL_DS); err = dev_ioctl(net, cmd, @@ -103991,7 +104893,7 @@ index a19ae19..89554dc 100644 set_fs(old_fs); return err; -@@ -3093,7 +3159,7 @@ static int compat_sioc_ifmap(struct net *net, unsigned int cmd, +@@ -3093,7 +3162,7 @@ static int compat_sioc_ifmap(struct net *net, unsigned int cmd, old_fs = get_fs(); set_fs(KERNEL_DS); @@ -104000,7 +104902,7 @@ index a19ae19..89554dc 100644 set_fs(old_fs); if (cmd == SIOCGIFMAP && !err) { -@@ -3177,7 +3243,7 @@ static int routing_ioctl(struct net *net, struct socket *sock, +@@ -3177,7 +3246,7 @@ static int routing_ioctl(struct net *net, struct socket *sock, ret |= get_user(rtdev, &(ur4->rt_dev)); if (rtdev) { ret |= copy_from_user(devname, compat_ptr(rtdev), 15); @@ -104009,7 +104911,7 @@ index a19ae19..89554dc 100644 devname[15] = 0; } else r4.rt_dev = NULL; -@@ -3404,8 +3470,8 @@ int kernel_getsockopt(struct socket *sock, int level, int optname, +@@ -3404,8 +3473,8 @@ int kernel_getsockopt(struct socket *sock, int level, int optname, int __user *uoptlen; int err; @@ -104020,7 +104922,7 @@ index a19ae19..89554dc 100644 set_fs(KERNEL_DS); if (level == SOL_SOCKET) -@@ -3425,7 +3491,7 @@ int kernel_setsockopt(struct socket *sock, int level, int optname, +@@ -3425,7 +3494,7 @@ int kernel_setsockopt(struct socket *sock, int level, int optname, char __user *uoptval; int err; @@ -104301,10 +105203,10 @@ index c1d124d..acfc59e 100644 goto err; return 0; diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c -index 62e4f9b..dd3f2d7 100644 +index ed36cb5..c55d17f 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_transport.c +++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c -@@ -292,7 +292,7 @@ static void rq_cq_reap(struct svcxprt_rdma *xprt) +@@ -293,7 +293,7 @@ static void rq_cq_reap(struct svcxprt_rdma *xprt) return; ib_req_notify_cq(xprt->sc_rq_cq, IB_CQ_NEXT_COMP); @@ -104313,7 +105215,7 @@ index 62e4f9b..dd3f2d7 100644 while ((ret = ib_poll_cq(xprt->sc_rq_cq, 1, &wc)) > 0) { ctxt = (struct svc_rdma_op_ctxt *)(unsigned long)wc.wr_id; -@@ -314,7 +314,7 @@ static void rq_cq_reap(struct svcxprt_rdma *xprt) +@@ -315,7 +315,7 @@ static void rq_cq_reap(struct svcxprt_rdma *xprt) } if (ctxt) @@ -104322,7 +105224,7 @@ index 62e4f9b..dd3f2d7 100644 set_bit(XPT_DATA, &xprt->sc_xprt.xpt_flags); /* -@@ -386,7 +386,7 @@ static void sq_cq_reap(struct svcxprt_rdma *xprt) +@@ -387,7 +387,7 @@ static void sq_cq_reap(struct svcxprt_rdma *xprt) return; ib_req_notify_cq(xprt->sc_sq_cq, IB_CQ_NEXT_COMP); @@ -104331,7 +105233,7 @@ index 62e4f9b..dd3f2d7 100644 while ((ret = ib_poll_cq(cq, 1, &wc)) > 0) { if (wc.status != IB_WC_SUCCESS) /* Close the transport */ -@@ -404,7 +404,7 @@ static void sq_cq_reap(struct svcxprt_rdma *xprt) +@@ -405,7 +405,7 @@ static void sq_cq_reap(struct svcxprt_rdma *xprt) } if (ctxt) @@ -104340,7 +105242,7 @@ index 62e4f9b..dd3f2d7 100644 } static void sq_comp_handler(struct ib_cq *cq, void *cq_context) -@@ -1262,7 +1262,7 @@ int svc_rdma_send(struct svcxprt_rdma *xprt, struct ib_send_wr *wr) +@@ -1263,7 +1263,7 @@ int svc_rdma_send(struct svcxprt_rdma *xprt, struct ib_send_wr *wr) spin_lock_bh(&xprt->sc_lock); if (xprt->sc_sq_depth < atomic_read(&xprt->sc_sq_count) + wr_count) { spin_unlock_bh(&xprt->sc_lock); @@ -109670,10 +110572,10 @@ index 0000000..89f256d +} diff --git a/tools/gcc/latent_entropy_plugin.c b/tools/gcc/latent_entropy_plugin.c new file mode 100644 -index 0000000..39d7cc7 +index 0000000..e48b323 --- /dev/null +++ b/tools/gcc/latent_entropy_plugin.c -@@ -0,0 +1,462 @@ +@@ -0,0 +1,466 @@ +/* + * Copyright 2012-2014 by the PaX Team <pageexec@freemail.hu> + * Licensed under the GPL v2 @@ -109702,7 +110604,7 @@ index 0000000..39d7cc7 +static tree latent_entropy_decl; + +static struct plugin_info latent_entropy_plugin_info = { -+ .version = "201403280150", ++ .version = "201409101820", + .help = NULL +}; + @@ -109878,6 +110780,10 @@ index 0000000..39d7cc7 + if (TREE_THIS_VOLATILE(current_function_decl)) + return false; + ++ // gcc-4.5 doesn't discover some trivial noreturn functions ++ if (EDGE_COUNT(EXIT_BLOCK_PTR_FOR_FN(cfun)->preds) == 0) ++ return false; ++ + return lookup_attribute("latent_entropy", DECL_ATTRIBUTES(current_function_decl)) != NULL_TREE; +} + |