diff options
author | Anthony G. Basile <blueness@gentoo.org> | 2016-04-03 05:35:02 -0400 |
---|---|---|
committer | Anthony G. Basile <blueness@gentoo.org> | 2016-04-03 05:35:02 -0400 |
commit | cdf70bd2fcd9e90bb82e2d1ecc7701d8efba0808 (patch) | |
tree | f3026138d22bc936a2e74d8988391b6dcc9e3460 | |
parent | grsecurity-3.1-4.4.6-201603221748 (diff) | |
download | hardened-patchset-cdf70bd2fcd9e90bb82e2d1ecc7701d8efba0808.tar.gz hardened-patchset-cdf70bd2fcd9e90bb82e2d1ecc7701d8efba0808.tar.bz2 hardened-patchset-cdf70bd2fcd9e90bb82e2d1ecc7701d8efba0808.zip |
grsecurity-3.1-4.4.6-20160402173420160402
-rw-r--r-- | 4.4.6/0000_README | 2 | ||||
-rw-r--r-- | 4.4.6/4420_grsecurity-3.1-4.4.6-201604021734.patch (renamed from 4.4.6/4420_grsecurity-3.1-4.4.6-201603221748.patch) | 2557 |
2 files changed, 2333 insertions, 226 deletions
diff --git a/4.4.6/0000_README b/4.4.6/0000_README index 3c1a08c..5a53479 100644 --- a/4.4.6/0000_README +++ b/4.4.6/0000_README @@ -2,7 +2,7 @@ README ----------------------------------------------------------------------------- Individual Patch Descriptions: ----------------------------------------------------------------------------- -Patch: 4420_grsecurity-3.1-4.4.6-201603221748.patch +Patch: 4420_grsecurity-3.1-4.4.6-201604021734.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/4.4.6/4420_grsecurity-3.1-4.4.6-201603221748.patch b/4.4.6/4420_grsecurity-3.1-4.4.6-201604021734.patch index a0d7af9..33aecb1 100644 --- a/4.4.6/4420_grsecurity-3.1-4.4.6-201603221748.patch +++ b/4.4.6/4420_grsecurity-3.1-4.4.6-201604021734.patch @@ -4519,6 +4519,20 @@ index 4867f5d..dbfed1e 100644 } } +diff --git a/arch/arm/mm/pageattr.c b/arch/arm/mm/pageattr.c +index cf30daf..d19b1ad 100644 +--- a/arch/arm/mm/pageattr.c ++++ b/arch/arm/mm/pageattr.c +@@ -49,6 +49,9 @@ static int change_memory_common(unsigned long addr, int numpages, + WARN_ON_ONCE(1); + } + ++ if (!numpages) ++ return 0; ++ + if (start < MODULES_VADDR || start >= MODULES_END) + return -EINVAL; + diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c index 93d0b6d..2db6d99 100644 --- a/arch/arm/net/bpf_jit_32.c @@ -5605,7 +5619,7 @@ index 2cd45f5..d0f4900 100644 static dma_addr_t octeon_unity_phys_to_dma(struct device *dev, phys_addr_t paddr) diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h -index 835b402..afbd327 100644 +index 835b402..347a797 100644 --- a/arch/mips/include/asm/atomic.h +++ b/arch/mips/include/asm/atomic.h @@ -22,15 +22,39 @@ @@ -5766,7 +5780,7 @@ index 835b402..afbd327 100644 " .set mips0 \n" \ : "=&r" (result), "=&r" (temp), \ "+" GCC_OFF_SMALL_ASM() (v->counter) \ -@@ -102,26 +159,33 @@ static __inline__ int atomic_##op##_return(int i, atomic_t * v) \ +@@ -102,26 +159,31 @@ static __inline__ int atomic_##op##_return(int i, atomic_t * v) \ } else if (kernel_uses_llsc) { \ int temp; \ \ @@ -5781,6 +5795,8 @@ index 835b402..afbd327 100644 - "+" GCC_OFF_SMALL_ASM() (v->counter) \ - : "Ir" (i)); \ - } while (unlikely(!result)); \ +- \ +- result = temp; result c_op i; \ + __asm__ __volatile__( \ + " .set "MIPS_ISA_LEVEL" \n" \ + "1: ll %1, %2 # atomic_" #op "_return" #suffix "\n" \ @@ -5794,8 +5810,6 @@ index 835b402..afbd327 100644 + : "=&r" (result), "=&r" (temp), \ + "+" GCC_OFF_SMALL_ASM() (v->counter) \ + : "Ir" (i)); \ - \ - result = temp; result c_op i; \ } else { \ unsigned long flags; \ \ @@ -5814,7 +5828,7 @@ index 835b402..afbd327 100644 raw_local_irq_restore(flags); \ } \ \ -@@ -130,20 +194,25 @@ static __inline__ int atomic_##op##_return(int i, atomic_t * v) \ +@@ -130,20 +192,25 @@ static __inline__ int atomic_##op##_return(int i, atomic_t * v) \ return result; \ } @@ -5848,7 +5862,7 @@ index 835b402..afbd327 100644 /* * atomic_sub_if_positive - conditionally subtract integer from atomic variable -@@ -153,7 +222,7 @@ ATOMIC_OP(xor, ^=, xor) +@@ -153,7 +220,7 @@ ATOMIC_OP(xor, ^=, xor) * Atomically test @v and subtract @i if @v is greater or equal than @i. * The function returns the old value of @v minus @i. */ @@ -5857,7 +5871,7 @@ index 835b402..afbd327 100644 { int result; -@@ -163,7 +232,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) +@@ -163,7 +230,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) int temp; __asm__ __volatile__( @@ -5866,7 +5880,7 @@ index 835b402..afbd327 100644 "1: ll %1, %2 # atomic_sub_if_positive\n" " subu %0, %1, %3 \n" " bltz %0, 1f \n" -@@ -212,8 +281,26 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) +@@ -212,8 +279,26 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) return result; } @@ -5895,7 +5909,7 @@ index 835b402..afbd327 100644 /** * __atomic_add_unless - add unless the number is a given value -@@ -241,6 +328,10 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) +@@ -241,6 +326,10 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) #define atomic_dec_return(v) atomic_sub_return(1, (v)) #define atomic_inc_return(v) atomic_add_return(1, (v)) @@ -5906,7 +5920,7 @@ index 835b402..afbd327 100644 /* * atomic_sub_and_test - subtract value from variable and test result -@@ -262,6 +353,10 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) +@@ -262,6 +351,10 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) * other cases. */ #define atomic_inc_and_test(v) (atomic_inc_return(v) == 0) @@ -5917,7 +5931,7 @@ index 835b402..afbd327 100644 /* * atomic_dec_and_test - decrement by 1 and test -@@ -286,6 +381,10 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) +@@ -286,6 +379,10 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) * Atomically increments @v by 1. */ #define atomic_inc(v) atomic_add(1, (v)) @@ -5928,7 +5942,7 @@ index 835b402..afbd327 100644 /* * atomic_dec - decrement and test -@@ -294,6 +393,10 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) +@@ -294,6 +391,10 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) * Atomically decrements @v by 1. */ #define atomic_dec(v) atomic_sub(1, (v)) @@ -5939,7 +5953,7 @@ index 835b402..afbd327 100644 /* * atomic_add_negative - add and test if negative -@@ -315,54 +418,77 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) +@@ -315,54 +416,77 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) * @v: pointer of type atomic64_t * */ @@ -6037,7 +6051,7 @@ index 835b402..afbd327 100644 { \ long result; \ \ -@@ -372,12 +498,15 @@ static __inline__ long atomic64_##op##_return(long i, atomic64_t * v) \ +@@ -372,12 +496,15 @@ static __inline__ long atomic64_##op##_return(long i, atomic64_t * v) \ long temp; \ \ __asm__ __volatile__( \ @@ -6056,7 +6070,7 @@ index 835b402..afbd327 100644 " .set mips0 \n" \ : "=&r" (result), "=&r" (temp), \ "+" GCC_OFF_SMALL_ASM() (v->counter) \ -@@ -385,27 +514,35 @@ static __inline__ long atomic64_##op##_return(long i, atomic64_t * v) \ +@@ -385,27 +512,33 @@ static __inline__ long atomic64_##op##_return(long i, atomic64_t * v) \ } else if (kernel_uses_llsc) { \ long temp; \ \ @@ -6072,6 +6086,8 @@ index 835b402..afbd327 100644 - : "Ir" (i), GCC_OFF_SMALL_ASM() (v->counter) \ - : "memory"); \ - } while (unlikely(!result)); \ +- \ +- result = temp; result c_op i; \ + __asm__ __volatile__( \ + " .set "MIPS_ISA_LEVEL" \n" \ + "1: lld %1, %2 # atomic64_" #op "_return" #suffix "\n"\ @@ -6087,8 +6103,6 @@ index 835b402..afbd327 100644 + "=" GCC_OFF_SMALL_ASM() (v->counter) \ + : "Ir" (i), GCC_OFF_SMALL_ASM() (v->counter) \ + : "memory"); \ - \ - result = temp; result c_op i; \ } else { \ unsigned long flags; \ \ @@ -6107,7 +6121,7 @@ index 835b402..afbd327 100644 raw_local_irq_restore(flags); \ } \ \ -@@ -414,19 +551,27 @@ static __inline__ long atomic64_##op##_return(long i, atomic64_t * v) \ +@@ -414,19 +547,27 @@ static __inline__ long atomic64_##op##_return(long i, atomic64_t * v) \ return result; \ } @@ -6143,7 +6157,7 @@ index 835b402..afbd327 100644 /* * atomic64_sub_if_positive - conditionally subtract integer from atomic -@@ -437,7 +582,7 @@ ATOMIC64_OP(xor, ^=, xor) +@@ -437,7 +578,7 @@ ATOMIC64_OP(xor, ^=, xor) * Atomically test @v and subtract @i if @v is greater or equal than @i. * The function returns the old value of @v minus @i. */ @@ -6152,7 +6166,7 @@ index 835b402..afbd327 100644 { long result; -@@ -447,7 +592,7 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v) +@@ -447,7 +588,7 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v) long temp; __asm__ __volatile__( @@ -6161,7 +6175,7 @@ index 835b402..afbd327 100644 "1: lld %1, %2 # atomic64_sub_if_positive\n" " dsubu %0, %1, %3 \n" " bltz %0, 1f \n" -@@ -496,9 +641,26 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v) +@@ -496,9 +637,26 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v) return result; } @@ -6191,7 +6205,7 @@ index 835b402..afbd327 100644 /** * atomic64_add_unless - add unless the number is a given value -@@ -528,6 +690,7 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) +@@ -528,6 +686,7 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) #define atomic64_dec_return(v) atomic64_sub_return(1, (v)) #define atomic64_inc_return(v) atomic64_add_return(1, (v)) @@ -6199,7 +6213,7 @@ index 835b402..afbd327 100644 /* * atomic64_sub_and_test - subtract value from variable and test result -@@ -549,6 +712,7 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) +@@ -549,6 +708,7 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) * other cases. */ #define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0) @@ -6207,7 +6221,7 @@ index 835b402..afbd327 100644 /* * atomic64_dec_and_test - decrement by 1 and test -@@ -573,6 +737,7 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) +@@ -573,6 +733,7 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) * Atomically increments @v by 1. */ #define atomic64_inc(v) atomic64_add(1, (v)) @@ -6215,7 +6229,7 @@ index 835b402..afbd327 100644 /* * atomic64_dec - decrement and test -@@ -581,6 +746,7 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) +@@ -581,6 +742,7 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) * Atomically decrements @v by 1. */ #define atomic64_dec(v) atomic64_sub(1, (v)) @@ -12101,6 +12115,19 @@ index e3abe6f..ae224ef 100644 #This will adjust *FLAGS accordingly to the platform. include $(ARCH_DIR)/Makefile-os-$(OS) +diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c +index 29880c9..e22e572 100644 +--- a/arch/um/drivers/mconsole_kern.c ++++ b/arch/um/drivers/mconsole_kern.c +@@ -133,7 +133,7 @@ void mconsole_proc(struct mc_request *req) + ptr += strlen("proc"); + ptr = skip_spaces(ptr); + +- file = file_open_root(mnt->mnt_root, mnt, ptr, O_RDONLY); ++ file = file_open_root(mnt->mnt_root, mnt, ptr, O_RDONLY, 0); + if (IS_ERR(file)) { + mconsole_reply(req, "Failed to open file", 1, 0); + printk(KERN_ERR "open /proc/%s: %ld\n", ptr, PTR_ERR(file)); diff --git a/arch/um/include/asm/cache.h b/arch/um/include/asm/cache.h index 19e1bdd..3665b77 100644 --- a/arch/um/include/asm/cache.h @@ -16502,7 +16529,7 @@ index efb2b93..8a9cb8e 100644 _ASM_NOKPROBE(restore) #endif diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile -index 265c0ed..a9ca19a 100644 +index 265c0ed..a706eb9 100644 --- a/arch/x86/entry/vdso/Makefile +++ b/arch/x86/entry/vdso/Makefile @@ -69,7 +69,7 @@ CFL := $(PROFILING) -mcmodel=small -fPIC -O2 -fasynchronous-unwind-tables -m64 \ @@ -16514,7 +16541,15 @@ index 265c0ed..a9ca19a 100644 # # vDSO code runs in userspace and -pg doesn't help with profiling anyway. -@@ -162,7 +162,7 @@ quiet_cmd_vdso = VDSO $@ +@@ -139,6 +139,7 @@ KBUILD_CFLAGS_32 := $(filter-out -m64,$(KBUILD_CFLAGS)) + KBUILD_CFLAGS_32 := $(filter-out -mcmodel=kernel,$(KBUILD_CFLAGS_32)) + KBUILD_CFLAGS_32 := $(filter-out -fno-pic,$(KBUILD_CFLAGS_32)) + KBUILD_CFLAGS_32 := $(filter-out -mfentry,$(KBUILD_CFLAGS_32)) ++KBUILD_CFLAGS_32 := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS_32)) + KBUILD_CFLAGS_32 += -m32 -msoft-float -mregparm=0 -fpic + KBUILD_CFLAGS_32 += $(call cc-option, -fno-stack-protector) + KBUILD_CFLAGS_32 += $(call cc-option, -foptimize-sibling-calls) +@@ -162,7 +163,7 @@ quiet_cmd_vdso = VDSO $@ -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^) && \ sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@' @@ -18081,7 +18116,7 @@ index acdee09..e5c31cd 100644 struct compat_timespec { compat_time_t tv_sec; diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h -index f7ba9fb..f658131 100644 +index f7ba9fb..d3945be 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h @@ -217,7 +217,8 @@ @@ -18103,15 +18138,7 @@ index f7ba9fb..f658131 100644 #define X86_FEATURE_BMI2 ( 9*32+ 8) /* 2nd group bit manipulation extensions */ #define X86_FEATURE_ERMS ( 9*32+ 9) /* Enhanced REP MOVSB/STOSB */ #define X86_FEATURE_INVPCID ( 9*32+10) /* Invalidate Processor Context ID */ -@@ -408,6 +409,7 @@ extern const char * const x86_bug_flags[NBUGINTS*32]; - #define cpu_has_eager_fpu boot_cpu_has(X86_FEATURE_EAGER_FPU) - #define cpu_has_topoext boot_cpu_has(X86_FEATURE_TOPOEXT) - #define cpu_has_bpext boot_cpu_has(X86_FEATURE_BPEXT) -+#define cpu_has_pcid boot_cpu_has(X86_FEATURE_PCID) - - #if __GNUC__ >= 4 - extern void warn_pre_alternatives(void); -@@ -461,7 +463,8 @@ static __always_inline __pure bool __static_cpu_has(u16 bit) +@@ -461,7 +462,8 @@ static __always_inline __pure bool __static_cpu_has(u16 bit) #ifdef CONFIG_X86_DEBUG_STATIC_CPU_HAS t_warn: @@ -18121,7 +18148,7 @@ index f7ba9fb..f658131 100644 return false; #endif -@@ -482,7 +485,7 @@ static __always_inline __pure bool __static_cpu_has(u16 bit) +@@ -482,7 +484,7 @@ static __always_inline __pure bool __static_cpu_has(u16 bit) ".section .discard,\"aw\",@progbits\n" " .byte 0xff + (4f-3f) - (2b-1b)\n" /* size check */ ".previous\n" @@ -18130,7 +18157,7 @@ index f7ba9fb..f658131 100644 "3: movb $1,%0\n" "4:\n" ".previous\n" -@@ -517,7 +520,7 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit) +@@ -517,7 +519,7 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit) " .byte 5f - 4f\n" /* repl len */ " .byte 3b - 2b\n" /* pad len */ ".previous\n" @@ -18139,7 +18166,7 @@ index f7ba9fb..f658131 100644 "4: jmp %l[t_no]\n" "5:\n" ".previous\n" -@@ -552,7 +555,7 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit) +@@ -552,7 +554,7 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit) ".section .discard,\"aw\",@progbits\n" " .byte 0xff + (4f-3f) - (2b-1b)\n" /* size check */ ".previous\n" @@ -18148,7 +18175,7 @@ index f7ba9fb..f658131 100644 "3: movb $0,%0\n" "4:\n" ".previous\n" -@@ -567,7 +570,7 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit) +@@ -567,7 +569,7 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit) ".section .discard,\"aw\",@progbits\n" " .byte 0xff + (6f-5f) - (4b-3b)\n" /* size check */ ".previous\n" @@ -24468,7 +24495,7 @@ index 464ffd6..01f2cda 100644 +EXPORT_SYMBOL(pax_check_alloca); +#endif diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c -index 5f1c626..1cba97e 100644 +index 5f1c626..14b4999 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c @@ -153,12 +153,12 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, @@ -24493,7 +24520,22 @@ index 5f1c626..1cba97e 100644 while (!done) { unsigned long *stack_end; enum stack_type stype; -@@ -202,7 +201,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, +@@ -192,17 +191,19 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, + done = 1; + + switch (stype) { +- +- /* Break out early if we are on the thread stack */ + case STACK_IS_NORMAL: ++ /* ++ * This handles the process stack: ++ */ ++ stack_start = (void *)((unsigned long)stack & ~(THREAD_SIZE-1)); ++ bp = ops->walk_stack(task, stack_start, stack, bp, ops, data, NULL, &graph); + break; + + case STACK_IS_EXCEPTION: +- if (ops->stack(data, id) < 0) break; @@ -24502,17 +24544,18 @@ index 5f1c626..1cba97e 100644 data, stack_end, &graph); ops->stack(data, "<EOE>"); /* -@@ -210,6 +209,8 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, +@@ -210,15 +211,16 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, * second-to-last pointer (index -2 to end) in the * exception stack: */ + if ((u16)stack_end[-1] != __KERNEL_DS) -+ goto out; ++ break; stack = (unsigned long *) stack_end[-2]; done = 0; break; -@@ -218,7 +219,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, + case STACK_IS_IRQ: +- if (ops->stack(data, "IRQ") < 0) break; - bp = ops->walk_stack(tinfo, stack, bp, @@ -24520,18 +24563,18 @@ index 5f1c626..1cba97e 100644 ops, data, stack_end, &graph); /* * We link to the next stack (which would be -@@ -240,7 +241,9 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, - /* - * This handles the process stack: - */ +@@ -237,10 +239,6 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, + } + } + +- /* +- * This handles the process stack: +- */ - bp = ops->walk_stack(tinfo, stack, bp, ops, data, NULL, &graph); -+ stack_start = (void *)((unsigned long)stack & ~(THREAD_SIZE-1)); -+ bp = ops->walk_stack(task, stack_start, stack, bp, ops, data, NULL, &graph); -+out: put_cpu(); } EXPORT_SYMBOL(dump_trace); -@@ -347,8 +350,55 @@ int is_valid_bugaddr(unsigned long ip) +@@ -347,8 +345,55 @@ int is_valid_bugaddr(unsigned long ip) { unsigned short ud2; @@ -25258,7 +25301,7 @@ index f129a9a..af8f6da 100644 for (i = 0; i < NUM_EXCEPTION_VECTORS; i++) diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S -index 6bc9ae2..d184220 100644 +index 6bc9ae2..33997fe 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S @@ -27,6 +27,12 @@ @@ -25553,10 +25596,11 @@ index 6bc9ae2..d184220 100644 .fill 4096,1,0 +.section .swapper_pg_dir,"a",@progbits ENTRY(swapper_pg_dir) +- .fill 1024,4,0 +#ifdef CONFIG_X86_PAE -+ .fill 4,8,0 ++ .fill PTRS_PER_PGD,8,0 +#else - .fill 1024,4,0 ++ .fill PTRS_PER_PGD,4,0 +#endif /* @@ -25578,7 +25622,7 @@ index 6bc9ae2..d184220 100644 +#ifdef CONFIG_PAX_PER_CPU_PGD +ENTRY(cpu_pgd) + .rept 2*NR_CPUS -+ .fill 4,8,0 ++ .fill PTRS_PER_PGD,8,0 + .endr +#endif + @@ -29665,7 +29709,7 @@ index 899c40f..a114588 100644 .disabled_by_bios = is_disabled, .hardware_setup = svm_hardware_setup, diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c -index 0958fa2..9fe3f1d 100644 +index 0958fa2..4d1af52 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -1514,12 +1514,12 @@ static void vmcs_write64(unsigned long field, u64 value) @@ -29784,7 +29828,23 @@ index 0958fa2..9fe3f1d 100644 } kvm_set_posted_intr_wakeup_handler(wakeup_handler); -@@ -8601,6 +8622,12 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) +@@ -7340,6 +7361,7 @@ static int handle_invept(struct kvm_vcpu *vcpu) + if (!(types & (1UL << type))) { + nested_vmx_failValid(vcpu, + VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID); ++ skip_emulated_instruction(vcpu); + return 1; + } + +@@ -7398,6 +7420,7 @@ static int handle_invvpid(struct kvm_vcpu *vcpu) + if (!(types & (1UL << type))) { + nested_vmx_failValid(vcpu, + VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID); ++ skip_emulated_instruction(vcpu); + return 1; + } + +@@ -8601,6 +8624,12 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) "jmp 2f \n\t" "1: " __ex(ASM_VMX_VMRESUME) "\n\t" "2: " @@ -29797,7 +29857,7 @@ index 0958fa2..9fe3f1d 100644 /* Save guest registers, load host registers, keep flags */ "mov %0, %c[wordsize](%%" _ASM_SP ") \n\t" "pop %0 \n\t" -@@ -8653,6 +8680,11 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) +@@ -8653,6 +8682,11 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) #endif [cr2]"i"(offsetof(struct vcpu_vmx, vcpu.arch.cr2)), [wordsize]"i"(sizeof(ulong)) @@ -29809,7 +29869,7 @@ index 0958fa2..9fe3f1d 100644 : "cc", "memory" #ifdef CONFIG_X86_64 , "rax", "rbx", "rdi", "rsi" -@@ -8666,7 +8698,7 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) +@@ -8666,7 +8700,7 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) if (debugctlmsr) update_debugctlmsr(debugctlmsr); @@ -29818,7 +29878,7 @@ index 0958fa2..9fe3f1d 100644 /* * The sysexit path does not restore ds/es, so we must set them to * a reasonable value ourselves. -@@ -8675,8 +8707,18 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) +@@ -8675,8 +8709,18 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) * may be executed in interrupt context, which saves and restore segments * around it, nullifying its effect. */ @@ -29839,7 +29899,7 @@ index 0958fa2..9fe3f1d 100644 #endif vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP) -@@ -10758,7 +10800,7 @@ out: +@@ -10758,7 +10802,7 @@ out: return ret; } @@ -32674,7 +32734,7 @@ index 903ec1e..41b4708 100644 } diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c -index e830c71..96cfc3d 100644 +index e830c71..f7e9e6c 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -14,6 +14,8 @@ @@ -32808,7 +32868,7 @@ index e830c71..96cfc3d 100644 + +#ifdef CONFIG_PAX_PER_CPU_PGD + BUG_ON(__pa(get_cpu_pgd(smp_processor_id(), kernel)) != (pgd_paddr & __PHYSICAL_MASK)); -+ vmalloc_sync_one(__va(pgd_paddr + PAGE_SIZE), address); ++ vmalloc_sync_one(__va(pgd_paddr + PTRS_PER_PGD * sizeof(pgd_t)), address); +#endif + pmd_k = vmalloc_sync_one(__va(pgd_paddr), address); @@ -37229,6 +37289,19 @@ index 0774799..7afc734 100644 if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len)) goto error; +diff --git a/crypto/asymmetric_keys/pkcs7_trust.c b/crypto/asymmetric_keys/pkcs7_trust.c +index 90d6d47..ecdb5a2 100644 +--- a/crypto/asymmetric_keys/pkcs7_trust.c ++++ b/crypto/asymmetric_keys/pkcs7_trust.c +@@ -178,6 +178,8 @@ int pkcs7_validate_trust(struct pkcs7_message *pkcs7, + int cached_ret = -ENOKEY; + int ret; + ++ *_trusted = false; ++ + for (p = pkcs7->certs; p; p = p->next) + p->seen = false; + diff --git a/crypto/cryptd.c b/crypto/cryptd.c index c81861b..dbf894f 100644 --- a/crypto/cryptd.c @@ -41187,6 +41260,222 @@ index ca5c71a..df88d0c 100644 err = pci_request_regions(pdev, name); if (err) +diff --git a/drivers/crypto/marvell/cesa.h b/drivers/crypto/marvell/cesa.h +index bd985e7..74071e4 100644 +--- a/drivers/crypto/marvell/cesa.h ++++ b/drivers/crypto/marvell/cesa.h +@@ -588,6 +588,7 @@ struct mv_cesa_ahash_dma_req { + struct mv_cesa_tdma_req base; + u8 *padding; + dma_addr_t padding_dma; ++ u8 *cache; + dma_addr_t cache_dma; + }; + +@@ -609,7 +610,7 @@ struct mv_cesa_ahash_req { + struct mv_cesa_ahash_std_req std; + } req; + struct mv_cesa_op_ctx op_tmpl; +- u8 *cache; ++ u8 cache[CESA_MAX_HASH_BLOCK_SIZE]; + unsigned int cache_ptr; + u64 len; + int src_nents; +diff --git a/drivers/crypto/marvell/hash.c b/drivers/crypto/marvell/hash.c +index 6ec55b4..27b314e 100644 +--- a/drivers/crypto/marvell/hash.c ++++ b/drivers/crypto/marvell/hash.c +@@ -45,69 +45,25 @@ mv_cesa_ahash_req_iter_next_op(struct mv_cesa_ahash_dma_iter *iter) + return mv_cesa_req_dma_iter_next_op(&iter->base); + } + +-static inline int mv_cesa_ahash_dma_alloc_cache(struct mv_cesa_ahash_req *creq, +- gfp_t flags) ++static inline int ++mv_cesa_ahash_dma_alloc_cache(struct mv_cesa_ahash_dma_req *req, gfp_t flags) + { +- struct mv_cesa_ahash_dma_req *dreq = &creq->req.dma; +- +- creq->cache = dma_pool_alloc(cesa_dev->dma->cache_pool, flags, +- &dreq->cache_dma); +- if (!creq->cache) +- return -ENOMEM; +- +- return 0; +-} +- +-static inline int mv_cesa_ahash_std_alloc_cache(struct mv_cesa_ahash_req *creq, +- gfp_t flags) +-{ +- creq->cache = kzalloc(CESA_MAX_HASH_BLOCK_SIZE, flags); +- if (!creq->cache) ++ req->cache = dma_pool_alloc(cesa_dev->dma->cache_pool, flags, ++ &req->cache_dma); ++ if (!req->cache) + return -ENOMEM; + + return 0; + } + +-static int mv_cesa_ahash_alloc_cache(struct ahash_request *req) +-{ +- struct mv_cesa_ahash_req *creq = ahash_request_ctx(req); +- gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? +- GFP_KERNEL : GFP_ATOMIC; +- int ret; +- +- if (creq->cache) +- return 0; +- +- if (creq->req.base.type == CESA_DMA_REQ) +- ret = mv_cesa_ahash_dma_alloc_cache(creq, flags); +- else +- ret = mv_cesa_ahash_std_alloc_cache(creq, flags); +- +- return ret; +-} +- +-static inline void mv_cesa_ahash_dma_free_cache(struct mv_cesa_ahash_req *creq) +-{ +- dma_pool_free(cesa_dev->dma->cache_pool, creq->cache, +- creq->req.dma.cache_dma); +-} +- +-static inline void mv_cesa_ahash_std_free_cache(struct mv_cesa_ahash_req *creq) +-{ +- kfree(creq->cache); +-} +- +-static void mv_cesa_ahash_free_cache(struct mv_cesa_ahash_req *creq) ++static inline void ++mv_cesa_ahash_dma_free_cache(struct mv_cesa_ahash_dma_req *req) + { +- if (!creq->cache) ++ if (!req->cache) + return; + +- if (creq->req.base.type == CESA_DMA_REQ) +- mv_cesa_ahash_dma_free_cache(creq); +- else +- mv_cesa_ahash_std_free_cache(creq); +- +- creq->cache = NULL; ++ dma_pool_free(cesa_dev->dma->cache_pool, req->cache, ++ req->cache_dma); + } + + static int mv_cesa_ahash_dma_alloc_padding(struct mv_cesa_ahash_dma_req *req, +@@ -146,6 +102,7 @@ static inline void mv_cesa_ahash_dma_cleanup(struct ahash_request *req) + struct mv_cesa_ahash_req *creq = ahash_request_ctx(req); + + dma_unmap_sg(cesa_dev->dev, req->src, creq->src_nents, DMA_TO_DEVICE); ++ mv_cesa_ahash_dma_free_cache(&creq->req.dma); + mv_cesa_dma_cleanup(&creq->req.dma.base); + } + +@@ -161,8 +118,6 @@ static void mv_cesa_ahash_last_cleanup(struct ahash_request *req) + { + struct mv_cesa_ahash_req *creq = ahash_request_ctx(req); + +- mv_cesa_ahash_free_cache(creq); +- + if (creq->req.base.type == CESA_DMA_REQ) + mv_cesa_ahash_dma_last_cleanup(req); + } +@@ -445,14 +400,6 @@ static inline int mv_cesa_ahash_cra_init(struct crypto_tfm *tfm) + static int mv_cesa_ahash_cache_req(struct ahash_request *req, bool *cached) + { + struct mv_cesa_ahash_req *creq = ahash_request_ctx(req); +- int ret; +- +- if (((creq->cache_ptr + req->nbytes) & CESA_HASH_BLOCK_SIZE_MSK) && +- !creq->last_req) { +- ret = mv_cesa_ahash_alloc_cache(req); +- if (ret) +- return ret; +- } + + if (creq->cache_ptr + req->nbytes < 64 && !creq->last_req) { + *cached = true; +@@ -505,10 +452,17 @@ mv_cesa_ahash_dma_add_cache(struct mv_cesa_tdma_chain *chain, + gfp_t flags) + { + struct mv_cesa_ahash_dma_req *ahashdreq = &creq->req.dma; ++ int ret; + + if (!creq->cache_ptr) + return 0; + ++ ret = mv_cesa_ahash_dma_alloc_cache(ahashdreq, flags); ++ if (ret) ++ return ret; ++ ++ memcpy(ahashdreq->cache, creq->cache, creq->cache_ptr); ++ + return mv_cesa_dma_add_data_transfer(chain, + CESA_SA_DATA_SRAM_OFFSET, + ahashdreq->cache_dma, +@@ -844,10 +798,6 @@ static int mv_cesa_ahash_import(struct ahash_request *req, const void *hash, + if (!cache_ptr) + return 0; + +- ret = mv_cesa_ahash_alloc_cache(req); +- if (ret) +- return ret; +- + memcpy(creq->cache, cache, cache_ptr); + creq->cache_ptr = cache_ptr; + +@@ -856,9 +806,14 @@ static int mv_cesa_ahash_import(struct ahash_request *req, const void *hash, + + static int mv_cesa_md5_init(struct ahash_request *req) + { ++ struct mv_cesa_ahash_req *creq = ahash_request_ctx(req); + struct mv_cesa_op_ctx tmpl = { }; + + mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_MACM_MD5); ++ creq->state[0] = MD5_H0; ++ creq->state[1] = MD5_H1; ++ creq->state[2] = MD5_H2; ++ creq->state[3] = MD5_H3; + + mv_cesa_ahash_init(req, &tmpl, true); + +@@ -919,9 +874,15 @@ struct ahash_alg mv_md5_alg = { + + static int mv_cesa_sha1_init(struct ahash_request *req) + { ++ struct mv_cesa_ahash_req *creq = ahash_request_ctx(req); + struct mv_cesa_op_ctx tmpl = { }; + + mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_MACM_SHA1); ++ creq->state[0] = SHA1_H0; ++ creq->state[1] = SHA1_H1; ++ creq->state[2] = SHA1_H2; ++ creq->state[3] = SHA1_H3; ++ creq->state[4] = SHA1_H4; + + mv_cesa_ahash_init(req, &tmpl, false); + +@@ -982,9 +943,18 @@ struct ahash_alg mv_sha1_alg = { + + static int mv_cesa_sha256_init(struct ahash_request *req) + { ++ struct mv_cesa_ahash_req *creq = ahash_request_ctx(req); + struct mv_cesa_op_ctx tmpl = { }; + + mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_MACM_SHA256); ++ creq->state[0] = SHA256_H0; ++ creq->state[1] = SHA256_H1; ++ creq->state[2] = SHA256_H2; ++ creq->state[3] = SHA256_H3; ++ creq->state[4] = SHA256_H4; ++ creq->state[5] = SHA256_H5; ++ creq->state[6] = SHA256_H6; ++ creq->state[7] = SHA256_H7; + + mv_cesa_ahash_init(req, &tmpl, false); + diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index ca848cc..9049c89 100644 --- a/drivers/devfreq/devfreq.c @@ -41549,7 +41838,7 @@ index d425374..1da1716 100644 EXPORT_SYMBOL_GPL(cper_next_record_id); diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c -index 027ca212..65689be 100644 +index 027ca21..65689be 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -174,14 +174,16 @@ static struct attribute_group efi_subsys_attr_group = { @@ -44512,7 +44801,7 @@ index 624d941..106fa1f 100644 nr_free, shrink_pages); } diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c -index 62c7b1d..2018818 100644 +index 62c7b1d..46d7a6a 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c @@ -367,7 +367,6 @@ static int udl_fb_release(struct fb_info *info, int user) @@ -44523,6 +44812,28 @@ index 62c7b1d..2018818 100644 } pr_warn("released /dev/fb%d user=%d count=%d\n", +@@ -539,7 +538,7 @@ static int udlfb_create(struct drm_fb_helper *helper, + out_destroy_fbi: + drm_fb_helper_release_fbi(helper); + out_gfree: +- drm_gem_object_unreference(&ufbdev->ufb.obj->base); ++ drm_gem_object_unreference_unlocked(&ufbdev->ufb.obj->base); + out: + return ret; + } +diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c +index 2a0a784..d7528e0 100644 +--- a/drivers/gpu/drm/udl/udl_gem.c ++++ b/drivers/gpu/drm/udl/udl_gem.c +@@ -52,7 +52,7 @@ udl_gem_create(struct drm_file *file, + return ret; + } + +- drm_gem_object_unreference(&obj->base); ++ drm_gem_object_unreference_unlocked(&obj->base); + *handle_p = handle; + return 0; + } diff --git a/drivers/gpu/drm/via/via_dma.c b/drivers/gpu/drm/via/via_dma.c index d17d8f2..67e8e48b 100644 --- a/drivers/gpu/drm/via/via_dma.c @@ -45120,6 +45431,30 @@ index 17ae2eb..21b71dd 100644 int ret, i; int in_i = 1, temp_i = 1, curr_i = 1, humidity_i = 1; enum iio_chan_type type; +diff --git a/drivers/hwmon/max1111.c b/drivers/hwmon/max1111.c +index 36544c4..303d0c9 100644 +--- a/drivers/hwmon/max1111.c ++++ b/drivers/hwmon/max1111.c +@@ -85,6 +85,9 @@ static struct max1111_data *the_max1111; + + int max1111_read_channel(int channel) + { ++ if (!the_max1111 || !the_max1111->spi) ++ return -ENODEV; ++ + return max1111_read(&the_max1111->spi->dev, channel); + } + EXPORT_SYMBOL(max1111_read_channel); +@@ -258,6 +261,9 @@ static int max1111_remove(struct spi_device *spi) + { + struct max1111_data *data = spi_get_drvdata(spi); + ++#ifdef CONFIG_SHARPSL_PM ++ the_max1111 = NULL; ++#endif + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&spi->dev.kobj, &max1110_attr_group); + sysfs_remove_group(&spi->dev.kobj, &max1111_attr_group); diff --git a/drivers/hwmon/nct6683.c b/drivers/hwmon/nct6683.c index 37f0170..414ec2c 100644 --- a/drivers/hwmon/nct6683.c @@ -46355,11 +46690,113 @@ index 4a95b22..874c182 100644 #include <linux/input.h> #include <linux/gameport.h> #include <linux/jiffies.h> +diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c +index cfd58e8..1c5914c 100644 +--- a/drivers/input/misc/ati_remote2.c ++++ b/drivers/input/misc/ati_remote2.c +@@ -817,26 +817,49 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d + + ar2->udev = udev; + ++ /* Sanity check, first interface must have an endpoint */ ++ if (alt->desc.bNumEndpoints < 1 || !alt->endpoint) { ++ dev_err(&interface->dev, ++ "%s(): interface 0 must have an endpoint\n", __func__); ++ r = -ENODEV; ++ goto fail1; ++ } + ar2->intf[0] = interface; + ar2->ep[0] = &alt->endpoint[0].desc; + ++ /* Sanity check, the device must have two interfaces */ + ar2->intf[1] = usb_ifnum_to_if(udev, 1); ++ if ((udev->actconfig->desc.bNumInterfaces < 2) || !ar2->intf[1]) { ++ dev_err(&interface->dev, "%s(): need 2 interfaces, found %d\n", ++ __func__, udev->actconfig->desc.bNumInterfaces); ++ r = -ENODEV; ++ goto fail1; ++ } ++ + r = usb_driver_claim_interface(&ati_remote2_driver, ar2->intf[1], ar2); + if (r) + goto fail1; ++ ++ /* Sanity check, second interface must have an endpoint */ + alt = ar2->intf[1]->cur_altsetting; ++ if (alt->desc.bNumEndpoints < 1 || !alt->endpoint) { ++ dev_err(&interface->dev, ++ "%s(): interface 1 must have an endpoint\n", __func__); ++ r = -ENODEV; ++ goto fail2; ++ } + ar2->ep[1] = &alt->endpoint[0].desc; + + r = ati_remote2_urb_init(ar2); + if (r) +- goto fail2; ++ goto fail3; + + ar2->channel_mask = channel_mask; + ar2->mode_mask = mode_mask; + + r = ati_remote2_setup(ar2, ar2->channel_mask); + if (r) +- goto fail2; ++ goto fail3; + + usb_make_path(udev, ar2->phys, sizeof(ar2->phys)); + strlcat(ar2->phys, "/input0", sizeof(ar2->phys)); +@@ -845,11 +868,11 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d + + r = sysfs_create_group(&udev->dev.kobj, &ati_remote2_attr_group); + if (r) +- goto fail2; ++ goto fail3; + + r = ati_remote2_input_init(ar2); + if (r) +- goto fail3; ++ goto fail4; + + usb_set_intfdata(interface, ar2); + +@@ -857,10 +880,11 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d + + return 0; + +- fail3: ++ fail4: + sysfs_remove_group(&udev->dev.kobj, &ati_remote2_attr_group); +- fail2: ++ fail3: + ati_remote2_urb_cleanup(ar2); ++ fail2: + usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]); + fail1: + kfree(ar2); diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c -index ac1fa5f..5f7502c 100644 +index ac1fa5f..1e1a411 100644 --- a/drivers/input/misc/ims-pcu.c +++ b/drivers/input/misc/ims-pcu.c -@@ -1851,7 +1851,7 @@ static int ims_pcu_identify_type(struct ims_pcu *pcu, u8 *device_id) +@@ -1663,6 +1663,8 @@ static int ims_pcu_parse_cdc_data(struct usb_interface *intf, struct ims_pcu *pc + + pcu->ctrl_intf = usb_ifnum_to_if(pcu->udev, + union_desc->bMasterInterface0); ++ if (!pcu->ctrl_intf) ++ return -EINVAL; + + alt = pcu->ctrl_intf->cur_altsetting; + pcu->ep_ctrl = &alt->endpoint[0].desc; +@@ -1670,6 +1672,8 @@ static int ims_pcu_parse_cdc_data(struct usb_interface *intf, struct ims_pcu *pc + + pcu->data_intf = usb_ifnum_to_if(pcu->udev, + union_desc->bSlaveInterface0); ++ if (!pcu->data_intf) ++ return -EINVAL; + + alt = pcu->data_intf->cur_altsetting; + if (alt->desc.bNumEndpoints != 2) { +@@ -1851,7 +1855,7 @@ static int ims_pcu_identify_type(struct ims_pcu *pcu, u8 *device_id) static int ims_pcu_init_application_mode(struct ims_pcu *pcu) { @@ -46368,7 +46805,7 @@ index ac1fa5f..5f7502c 100644 const struct ims_pcu_device_info *info; int error; -@@ -1882,7 +1882,7 @@ static int ims_pcu_init_application_mode(struct ims_pcu *pcu) +@@ -1882,7 +1886,7 @@ static int ims_pcu_init_application_mode(struct ims_pcu *pcu) } /* Device appears to be operable, complete initialization */ @@ -46460,6 +46897,61 @@ index 92e2243..8fd9092 100644 { .ident = "Shift", .matches = { +diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c +index d214f22..b3afa9f 100644 +--- a/drivers/input/touchscreen/sur40.c ++++ b/drivers/input/touchscreen/sur40.c +@@ -197,28 +197,34 @@ static int sur40_command(struct sur40_state *dev, + static int sur40_init(struct sur40_state *dev) + { + int result; +- u8 buffer[24]; ++ u8 *buffer; ++ ++ buffer = kmalloc(24, GFP_KERNEL); ++ if (!buffer) { ++ result = -ENOMEM; ++ goto error; ++ } + + /* stupidly replay the original MS driver init sequence */ + result = sur40_command(dev, SUR40_GET_VERSION, 0x00, buffer, 12); + if (result < 0) +- return result; ++ goto error; + + result = sur40_command(dev, SUR40_GET_VERSION, 0x01, buffer, 12); + if (result < 0) +- return result; ++ goto error; + + result = sur40_command(dev, SUR40_GET_VERSION, 0x02, buffer, 12); + if (result < 0) +- return result; ++ goto error; + + result = sur40_command(dev, SUR40_UNKNOWN2, 0x00, buffer, 24); + if (result < 0) +- return result; ++ goto error; + + result = sur40_command(dev, SUR40_UNKNOWN1, 0x00, buffer, 5); + if (result < 0) +- return result; ++ goto error; + + result = sur40_command(dev, SUR40_GET_VERSION, 0x03, buffer, 12); + +@@ -226,7 +232,8 @@ static int sur40_init(struct sur40_state *dev) + * Discard the result buffer - no known data inside except + * some version strings, maybe extract these sometime... + */ +- ++error: ++ kfree(buffer); + return result; + } + diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index b9094e9..a4885c6 100644 --- a/drivers/iommu/Kconfig @@ -46514,7 +47006,7 @@ index 4e5118a..6b1675e 100644 return -ENOMEM; diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c -index 47dc7a7..2bfe405 100644 +index 47dc7a7..aa39188 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -341,7 +341,7 @@ enum arm_smmu_domain_stage { @@ -46622,7 +47114,7 @@ index 47dc7a7..2bfe405 100644 "iova to phys timed out on %pad. Falling back to software table walk.\n", &iova); - return ops->iova_to_phys(ops, iova); -+ return iop->ops->iova_to_phys(ops, iova); ++ return iop->ops->iova_to_phys(iop, iova); } phys = readl_relaxed(cb_base + ARM_SMMU_CB_PAR_LO); @@ -52544,7 +53036,7 @@ index 58efdec..4184f70 100644 .maxtype = IFLA_GENEVE_MAX, .policy = geneve_policy, diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h -index 5fa98f5..322f0f8 100644 +index 5fa98f5..74440cc 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h @@ -178,7 +178,7 @@ struct rndis_device { @@ -52556,8 +53048,71 @@ index 5fa98f5..322f0f8 100644 spinlock_t request_lock; struct list_head req_list; +@@ -628,6 +628,7 @@ struct nvsp_message { + #define NETVSC_PACKET_SIZE 4096 + + #define VRSS_SEND_TAB_SIZE 16 ++#define VRSS_CHANNEL_MAX 64 + + #define RNDIS_MAX_PKT_DEFAULT 8 + #define RNDIS_PKT_ALIGN_DEFAULT 8 +@@ -692,13 +693,13 @@ struct netvsc_device { + + struct net_device *ndev; + +- struct vmbus_channel *chn_table[NR_CPUS]; ++ struct vmbus_channel *chn_table[VRSS_CHANNEL_MAX]; + u32 send_table[VRSS_SEND_TAB_SIZE]; + u32 max_chn; + u32 num_chn; + spinlock_t sc_lock; /* Protects num_sc_offered variable */ + u32 num_sc_offered; +- atomic_t queue_sends[NR_CPUS]; ++ atomic_t queue_sends[VRSS_CHANNEL_MAX]; + + /* Holds rndis device info */ + void *extension; +@@ -710,7 +711,7 @@ struct netvsc_device { + /* The sub channel callback buffer */ + unsigned char *sub_cb_buf; + +- struct multi_send_data msd[NR_CPUS]; ++ struct multi_send_data msd[VRSS_CHANNEL_MAX]; + u32 max_pkt; /* max number of pkt in one send, e.g. 8 */ + u32 pkt_align; /* alignment bytes, e.g. 8 */ + +diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c +index 409b48e..710a23f 100644 +--- a/drivers/net/hyperv/netvsc_drv.c ++++ b/drivers/net/hyperv/netvsc_drv.c +@@ -875,6 +875,7 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu) + struct netvsc_device *nvdev = hv_get_drvdata(hdev); + struct netvsc_device_info device_info; + int limit = ETH_DATA_LEN; ++ u32 num_chn; + int ret = 0; + + if (nvdev == NULL || nvdev->destroy) +@@ -890,6 +891,8 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu) + if (ret) + goto out; + ++ num_chn = nvdev->num_chn; ++ + nvdev->start_remove = true; + rndis_filter_device_remove(hdev); + +@@ -900,7 +903,7 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu) + + memset(&device_info, 0, sizeof(device_info)); + device_info.ring_size = ring_size; +- device_info.num_chn = nvdev->num_chn; ++ device_info.num_chn = num_chn; + device_info.max_num_vrss_chns = max_num_vrss_chns; + rndis_filter_device_add(hdev, &device_info); + diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c -index 5931a79..134ce31 100644 +index 5931a79..b0645bb 100644 --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c @@ -101,7 +101,7 @@ static struct rndis_request *get_rndis_request(struct rndis_device *dev, @@ -52578,6 +53133,18 @@ index 5931a79..134ce31 100644 /* Ignore return since this msg is optional. */ rndis_filter_send_request(dev, request); +@@ -1115,9 +1115,9 @@ int rndis_filter_device_add(struct hv_device *dev, + if (ret || rsscap.num_recv_que < 2) + goto out; + +- num_rss_qs = min(device_info->max_num_vrss_chns, rsscap.num_recv_que); ++ net_device->max_chn = min_t(u32, VRSS_CHANNEL_MAX, rsscap.num_recv_que); + +- net_device->max_chn = rsscap.num_recv_que; ++ num_rss_qs = min(device_info->max_num_vrss_chns, net_device->max_chn); + + /* + * We will limit the VRSS channels to the number CPUs in the NUMA node @@ -1138,8 +1138,7 @@ int rndis_filter_device_add(struct hv_device *dev, if (net_device->num_chn == 1) goto out; @@ -52866,7 +53433,7 @@ index 0bfbaba..c81a3588 100644 r = get_phy_id(bus, addr, &phy_id, is_c45, &c45_ids); diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c -index 9a863c6..8e2d8c9 100644 +index 9a863c6..accd789 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c @@ -1045,7 +1045,6 @@ ppp_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) @@ -52887,6 +53454,36 @@ index 9a863c6..8e2d8c9 100644 break; err = 0; break; +@@ -2290,7 +2288,7 @@ int ppp_register_net_channel(struct net *net, struct ppp_channel *chan) + + pch->ppp = NULL; + pch->chan = chan; +- pch->chan_net = net; ++ pch->chan_net = get_net(net); + chan->ppp = pch; + init_ppp_file(&pch->file, CHANNEL); + pch->file.hdrlen = chan->hdrlen; +@@ -2387,6 +2385,8 @@ ppp_unregister_channel(struct ppp_channel *chan) + spin_lock_bh(&pn->all_channels_lock); + list_del(&pch->list); + spin_unlock_bh(&pn->all_channels_lock); ++ put_net(pch->chan_net); ++ pch->chan_net = NULL; + + pch->file.dead = 1; + wake_up_interruptible(&pch->file.rwait); +diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c +index f7e8c79..d5531cd 100644 +--- a/drivers/net/ppp/pptp.c ++++ b/drivers/net/ppp/pptp.c +@@ -369,6 +369,7 @@ allow_packet: + + skb->ip_summed = CHECKSUM_NONE; + skb_set_network_header(skb, skb->head-skb->data); ++ skb->network_header = 0; + ppp_input(&po->chan, skb); + + return NET_RX_SUCCESS; diff --git a/drivers/net/slip/slhc.c b/drivers/net/slip/slhc.c index 27ed252..80cffde 100644 --- a/drivers/net/slip/slhc.c @@ -57367,6 +57964,19 @@ index f69fb5c..be5da97 100644 #endif } +diff --git a/drivers/staging/rdma/ehca/ehca_irq.c b/drivers/staging/rdma/ehca/ehca_irq.c +index 8615d7c..1396623 100644 +--- a/drivers/staging/rdma/ehca/ehca_irq.c ++++ b/drivers/staging/rdma/ehca/ehca_irq.c +@@ -802,7 +802,7 @@ static void comp_task(unsigned int cpu) + spin_unlock_irq(&cct->task_lock); + } + +-static struct smp_hotplug_thread comp_pool_threads = { ++static struct smp_hotplug_thread comp_pool_threads __read_only = { + .thread_should_run = comp_task_should_run, + .thread_fn = comp_task, + .thread_comm = "ehca_comp/%u", diff --git a/drivers/staging/rdma/ipath/ipath_rc.c b/drivers/staging/rdma/ipath/ipath_rc.c index d4aa535..022fa57 100644 --- a/drivers/staging/rdma/ipath/ipath_rc.c @@ -59621,6 +60231,20 @@ index db322d9..f0f4bc1 100644 if (!left--) { if (instance->disconnected) +diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c +index fa4e239..d37fdcc 100644 +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -1114,6 +1114,9 @@ static int acm_probe(struct usb_interface *intf, + if (quirks == NO_UNION_NORMAL) { + data_interface = usb_ifnum_to_if(usb_dev, 1); + control_interface = usb_ifnum_to_if(usb_dev, 0); ++ /* we would crash */ ++ if (!data_interface || !control_interface) ++ return -ENODEV; + goto skip_normal_probe; + } + diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h index ccfaba9..523f476 100644 --- a/drivers/usb/class/cdc-acm.h @@ -59714,6 +60338,27 @@ index 38ae877c..9bf9e7d 100644 __create_pipe(ps->dev, uurb->endpoint & 0xf) | (uurb->endpoint & USB_DIR_IN); +diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c +index 56593a9..2057d91 100644 +--- a/drivers/usb/core/driver.c ++++ b/drivers/usb/core/driver.c +@@ -502,11 +502,15 @@ static int usb_unbind_interface(struct device *dev) + int usb_driver_claim_interface(struct usb_driver *driver, + struct usb_interface *iface, void *priv) + { +- struct device *dev = &iface->dev; ++ struct device *dev; + struct usb_device *udev; + int retval = 0; + int lpm_disable_error; + ++ if (!iface) ++ return -ENODEV; ++ ++ dev = &iface->dev; + if (dev->driver) + return -EBUSY; + diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 1c102d6..d15688e 100644 --- a/drivers/usb/core/hcd.c @@ -60138,6 +60783,23 @@ index a0a3827..d7ec10b 100644 memset(&props, 0, sizeof(struct backlight_properties)); props.type = BACKLIGHT_RAW; props.max_brightness = 0xff; +diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c +index c6bfd13..1950e87 100644 +--- a/drivers/usb/misc/iowarrior.c ++++ b/drivers/usb/misc/iowarrior.c +@@ -787,6 +787,12 @@ static int iowarrior_probe(struct usb_interface *interface, + iface_desc = interface->cur_altsetting; + dev->product_id = le16_to_cpu(udev->descriptor.idProduct); + ++ if (iface_desc->desc.bNumEndpoints < 1) { ++ dev_err(&interface->dev, "Invalid number of endpoints\n"); ++ retval = -EINVAL; ++ goto error; ++ } ++ + /* set up the endpoint information */ + for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { + endpoint = &iface_desc->endpoint[i].desc; diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index 3806e70..55c508b 100644 --- a/drivers/usb/serial/console.c @@ -79518,10 +80180,21 @@ index a7a1b21..023d87a 100644 /* * We'll have a dentry and an inode for diff --git a/fs/coredump.c b/fs/coredump.c -index 1777331..d6154a2 100644 +index 1777331..400d71c 100644 --- a/fs/coredump.c +++ b/fs/coredump.c -@@ -456,8 +456,8 @@ static void wait_for_dump_helpers(struct file *file) +@@ -32,6 +32,10 @@ + #include <linux/pipe_fs_i.h> + #include <linux/oom.h> + #include <linux/compat.h> ++#include <linux/sched.h> ++#include <linux/fs.h> ++#include <linux/path.h> ++#include <linux/timekeeping.h> + + #include <asm/uaccess.h> + #include <asm/mmu_context.h> +@@ -456,8 +460,8 @@ static void wait_for_dump_helpers(struct file *file) struct pipe_inode_info *pipe = file->private_data; pipe_lock(pipe); @@ -79532,7 +80205,7 @@ index 1777331..d6154a2 100644 wake_up_interruptible_sync(&pipe->wait); kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); pipe_unlock(pipe); -@@ -466,11 +466,11 @@ static void wait_for_dump_helpers(struct file *file) +@@ -466,11 +470,11 @@ static void wait_for_dump_helpers(struct file *file) * We actually want wait_event_freezable() but then we need * to clear TIF_SIGPENDING and improve dump_interrupted(). */ @@ -79547,7 +80220,7 @@ index 1777331..d6154a2 100644 pipe_unlock(pipe); } -@@ -517,7 +517,9 @@ void do_coredump(const siginfo_t *siginfo) +@@ -517,7 +521,9 @@ void do_coredump(const siginfo_t *siginfo) /* require nonrelative corefile path and be extra careful */ bool need_suid_safe = false; bool core_dumped = false; @@ -79558,7 +80231,7 @@ index 1777331..d6154a2 100644 struct coredump_params cprm = { .siginfo = siginfo, .regs = signal_pt_regs(), -@@ -530,12 +532,17 @@ void do_coredump(const siginfo_t *siginfo) +@@ -530,12 +536,17 @@ void do_coredump(const siginfo_t *siginfo) .mm_flags = mm->flags, }; @@ -79578,7 +80251,7 @@ index 1777331..d6154a2 100644 goto fail; cred = prepare_creds(); -@@ -553,7 +560,7 @@ void do_coredump(const siginfo_t *siginfo) +@@ -553,7 +564,7 @@ void do_coredump(const siginfo_t *siginfo) need_suid_safe = true; } @@ -79587,7 +80260,7 @@ index 1777331..d6154a2 100644 if (retval < 0) goto fail_creds; -@@ -596,7 +603,7 @@ void do_coredump(const siginfo_t *siginfo) +@@ -596,7 +607,7 @@ void do_coredump(const siginfo_t *siginfo) } cprm.limit = RLIM_INFINITY; @@ -79596,16 +80269,18 @@ index 1777331..d6154a2 100644 if (core_pipe_limit && (core_pipe_limit < dump_count)) { printk(KERN_WARNING "Pid %d(%s) over core_pipe_limit\n", task_tgid_vnr(current), current->comm); -@@ -628,6 +635,8 @@ void do_coredump(const siginfo_t *siginfo) +@@ -627,6 +638,10 @@ void do_coredump(const siginfo_t *siginfo) + } } else { struct inode *inode; - -+ gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1); ++ int open_flags = O_CREAT | O_RDWR | O_NOFOLLOW | ++ O_LARGEFILE | O_EXCL; + ++ gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1); + if (cprm.limit < binfmt->min_coredump) goto fail_unlock; - -@@ -653,7 +662,7 @@ void do_coredump(const siginfo_t *siginfo) +@@ -653,7 +668,7 @@ void do_coredump(const siginfo_t *siginfo) * If it doesn't exist, that's fine. If there's some * other problem, we'll catch it at the filp_open(). */ @@ -79614,7 +80289,39 @@ index 1777331..d6154a2 100644 set_fs(old_fs); } -@@ -717,7 +726,7 @@ close_fail: +@@ -665,10 +680,27 @@ void do_coredump(const siginfo_t *siginfo) + * what matters is that at least one of the two processes + * writes its coredump successfully, not which one. + */ +- cprm.file = filp_open(cn.corename, +- O_CREAT | 2 | O_NOFOLLOW | +- O_LARGEFILE | O_EXCL, +- 0600); ++ if (need_suid_safe) { ++ /* ++ * Using user namespaces, normal user tasks can change ++ * their current->fs->root to point to arbitrary ++ * directories. Since the intention of the "only dump ++ * with a fully qualified path" rule is to control where ++ * coredumps may be placed using root privileges, ++ * current->fs->root must not be used. Instead, use the ++ * root directory of init_task. ++ */ ++ struct path root; ++ ++ task_lock(&init_task); ++ get_fs_root(init_task.fs, &root); ++ task_unlock(&init_task); ++ cprm.file = file_open_root(root.dentry, root.mnt, ++ cn.corename, open_flags, 0600); ++ path_put(&root); ++ } else { ++ cprm.file = filp_open(cn.corename, open_flags, 0600); ++ } + if (IS_ERR(cprm.file)) + goto fail_unlock; + +@@ -717,7 +749,7 @@ close_fail: filp_close(cprm.file, NULL); fail_dropcount: if (ispipe) @@ -79623,7 +80330,7 @@ index 1777331..d6154a2 100644 fail_unlock: kfree(cn.corename); coredump_finish(mm, core_dumped); -@@ -738,6 +747,8 @@ int dump_emit(struct coredump_params *cprm, const void *addr, int nr) +@@ -738,6 +770,8 @@ int dump_emit(struct coredump_params *cprm, const void *addr, int nr) struct file *file = cprm->file; loff_t pos = file->f_pos; ssize_t n; @@ -79921,6 +80628,30 @@ index e2e47ba..221b0a3 100644 PATH_MAX); set_fs(old_fs); if (rc < 0) +diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c +index 6bd67e2..1d71a4b 100644 +--- a/fs/ecryptfs/keystore.c ++++ b/fs/ecryptfs/keystore.c +@@ -633,8 +633,7 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, + if (!s) { + printk(KERN_ERR "%s: Out of memory whilst trying to kmalloc " + "[%zd] bytes of kernel memory\n", __func__, sizeof(*s)); +- rc = -ENOMEM; +- goto out; ++ return -ENOMEM; + } + s->desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; + (*packet_size) = 0; +@@ -926,8 +925,7 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, + if (!s) { + printk(KERN_ERR "%s: Out of memory whilst trying to kmalloc " + "[%zd] bytes of kernel memory\n", __func__, sizeof(*s)); +- rc = -ENOMEM; +- goto out; ++ return -ENOMEM; + } + s->desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; + if (max_packet_size < ECRYPTFS_TAG_70_MIN_METADATA_SIZE) { diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c index e4141f2..d8263e8 100644 --- a/fs/ecryptfs/miscdev.c @@ -80850,10 +81581,26 @@ index fe1f50f..3f4c870 100644 if (free_clusters >= (nclusters + dirty_clusters + resv_clusters)) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h -index cc7ca4e..1973ef2 100644 +index cc7ca4e..8c14386 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h -@@ -1351,19 +1351,19 @@ struct ext4_sb_info { +@@ -910,6 +910,15 @@ struct ext4_inode_info { + * by other means, so we have i_data_sem. + */ + struct rw_semaphore i_data_sem; ++ /* ++ * i_mmap_sem is for serializing page faults with truncate / punch hole ++ * operations. We have to make sure that new page cannot be faulted in ++ * a section of the inode that is being punched. We cannot easily use ++ * i_data_sem for this since we need protection for the whole punch ++ * operation and i_data_sem ranks below transaction start so we have ++ * to occasionally drop it. ++ */ ++ struct rw_semaphore i_mmap_sem; + struct inode vfs_inode; + struct jbd2_inode *jinode; + +@@ -1351,19 +1360,19 @@ struct ext4_sb_info { unsigned long s_mb_last_start; /* stats for buddy allocator */ @@ -80883,8 +81630,26 @@ index cc7ca4e..1973ef2 100644 atomic_t s_lock_busy; /* locality groups */ +@@ -2484,6 +2493,7 @@ extern int ext4_chunk_trans_blocks(struct inode *, int nrblocks); + extern int ext4_zero_partial_blocks(handle_t *handle, struct inode *inode, + loff_t lstart, loff_t lend); + extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf); ++extern int ext4_filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf); + extern qsize_t *ext4_get_reserved_space(struct inode *inode); + extern void ext4_da_update_reserve_space(struct inode *inode, + int used, int quota_claim); +@@ -2848,6 +2858,9 @@ static inline int ext4_update_inode_size(struct inode *inode, loff_t newsize) + return changed; + } + ++int ext4_update_disksize_before_punch(struct inode *inode, loff_t offset, ++ loff_t len); ++ + struct ext4_group_info { + unsigned long bb_state; + struct rb_root bb_free_root; diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c -index 551353b..a069cff 100644 +index 551353b..1c45aae 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -863,7 +863,7 @@ ext4_find_extent(struct inode *inode, ext4_lblk_t block, @@ -80896,6 +81661,525 @@ index 551353b..a069cff 100644 int ret; eh = ext_inode_hdr(inode); +@@ -4685,10 +4685,6 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset, + if (len <= EXT_UNWRITTEN_MAX_LEN) + flags |= EXT4_GET_BLOCKS_NO_NORMALIZE; + +- /* Wait all existing dio workers, newcomers will block on i_mutex */ +- ext4_inode_block_unlocked_dio(inode); +- inode_dio_wait(inode); +- + /* + * credits to insert 1 extent into extent tree + */ +@@ -4752,8 +4748,6 @@ retry: + goto retry; + } + +- ext4_inode_resume_unlocked_dio(inode); +- + return ret > 0 ? ret2 : ret; + } + +@@ -4770,7 +4764,6 @@ static long ext4_zero_range(struct file *file, loff_t offset, + int partial_begin, partial_end; + loff_t start, end; + ext4_lblk_t lblk; +- struct address_space *mapping = inode->i_mapping; + unsigned int blkbits = inode->i_blkbits; + + trace_ext4_zero_range(inode, offset, len, mode); +@@ -4786,17 +4779,6 @@ static long ext4_zero_range(struct file *file, loff_t offset, + } + + /* +- * Write out all dirty pages to avoid race conditions +- * Then release them. +- */ +- if (mapping->nrpages && mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) { +- ret = filemap_write_and_wait_range(mapping, offset, +- offset + len - 1); +- if (ret) +- return ret; +- } +- +- /* + * Round up offset. This is not fallocate, we neet to zero out + * blocks, so convert interior block aligned part of the range to + * unwritten and possibly manually zero out unaligned parts of the +@@ -4839,6 +4821,10 @@ static long ext4_zero_range(struct file *file, loff_t offset, + if (mode & FALLOC_FL_KEEP_SIZE) + flags |= EXT4_GET_BLOCKS_KEEP_SIZE; + ++ /* Wait all existing dio workers, newcomers will block on i_mutex */ ++ ext4_inode_block_unlocked_dio(inode); ++ inode_dio_wait(inode); ++ + /* Preallocate the range including the unaligned edges */ + if (partial_begin || partial_end) { + ret = ext4_alloc_file_blocks(file, +@@ -4847,7 +4833,7 @@ static long ext4_zero_range(struct file *file, loff_t offset, + round_down(offset, 1 << blkbits)) >> blkbits, + new_size, flags, mode); + if (ret) +- goto out_mutex; ++ goto out_dio; + + } + +@@ -4856,16 +4842,23 @@ static long ext4_zero_range(struct file *file, loff_t offset, + flags |= (EXT4_GET_BLOCKS_CONVERT_UNWRITTEN | + EXT4_EX_NOCACHE); + +- /* Now release the pages and zero block aligned part of pages*/ ++ /* ++ * Prevent page faults from reinstantiating pages we have ++ * released from page cache. ++ */ ++ down_write(&EXT4_I(inode)->i_mmap_sem); ++ ret = ext4_update_disksize_before_punch(inode, offset, len); ++ if (ret) { ++ up_write(&EXT4_I(inode)->i_mmap_sem); ++ goto out_dio; ++ } ++ /* Now release the pages and zero block aligned part of pages */ + truncate_pagecache_range(inode, start, end - 1); + inode->i_mtime = inode->i_ctime = ext4_current_time(inode); + +- /* Wait all existing dio workers, newcomers will block on i_mutex */ +- ext4_inode_block_unlocked_dio(inode); +- inode_dio_wait(inode); +- + ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size, + flags, mode); ++ up_write(&EXT4_I(inode)->i_mmap_sem); + if (ret) + goto out_dio; + } +@@ -4998,8 +4991,13 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len) + goto out; + } + ++ /* Wait all existing dio workers, newcomers will block on i_mutex */ ++ ext4_inode_block_unlocked_dio(inode); ++ inode_dio_wait(inode); ++ + ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size, + flags, mode); ++ ext4_inode_resume_unlocked_dio(inode); + if (ret) + goto out; + +@@ -5494,21 +5492,7 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) + return ret; + } + +- /* +- * Need to round down offset to be aligned with page size boundary +- * for page size > block size. +- */ +- ioffset = round_down(offset, PAGE_SIZE); +- +- /* Write out all dirty pages */ +- ret = filemap_write_and_wait_range(inode->i_mapping, ioffset, +- LLONG_MAX); +- if (ret) +- return ret; +- +- /* Take mutex lock */ + mutex_lock(&inode->i_mutex); +- + /* + * There is no need to overlap collapse range with EOF, in which case + * it is effectively a truncate operation +@@ -5524,17 +5508,43 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) + goto out_mutex; + } + +- truncate_pagecache(inode, ioffset); +- + /* Wait for existing dio to complete */ + ext4_inode_block_unlocked_dio(inode); + inode_dio_wait(inode); + ++ /* ++ * Prevent page faults from reinstantiating pages we have released from ++ * page cache. ++ */ ++ down_write(&EXT4_I(inode)->i_mmap_sem); ++ /* ++ * Need to round down offset to be aligned with page size boundary ++ * for page size > block size. ++ */ ++ ioffset = round_down(offset, PAGE_SIZE); ++ /* ++ * Write tail of the last page before removed range since it will get ++ * removed from the page cache below. ++ */ ++ ret = filemap_write_and_wait_range(inode->i_mapping, ioffset, offset); ++ if (ret) ++ goto out_mmap; ++ /* ++ * Write data that will be shifted to preserve them when discarding ++ * page cache below. We are also protected from pages becoming dirty ++ * by i_mmap_sem. ++ */ ++ ret = filemap_write_and_wait_range(inode->i_mapping, offset + len, ++ LLONG_MAX); ++ if (ret) ++ goto out_mmap; ++ truncate_pagecache(inode, ioffset); ++ + credits = ext4_writepage_trans_blocks(inode); + handle = ext4_journal_start(inode, EXT4_HT_TRUNCATE, credits); + if (IS_ERR(handle)) { + ret = PTR_ERR(handle); +- goto out_dio; ++ goto out_mmap; + } + + down_write(&EXT4_I(inode)->i_data_sem); +@@ -5573,7 +5583,8 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) + + out_stop: + ext4_journal_stop(handle); +-out_dio: ++out_mmap: ++ up_write(&EXT4_I(inode)->i_mmap_sem); + ext4_inode_resume_unlocked_dio(inode); + out_mutex: + mutex_unlock(&inode->i_mutex); +@@ -5627,21 +5638,7 @@ int ext4_insert_range(struct inode *inode, loff_t offset, loff_t len) + return ret; + } + +- /* +- * Need to round down to align start offset to page size boundary +- * for page size > block size. +- */ +- ioffset = round_down(offset, PAGE_SIZE); +- +- /* Write out all dirty pages */ +- ret = filemap_write_and_wait_range(inode->i_mapping, ioffset, +- LLONG_MAX); +- if (ret) +- return ret; +- +- /* Take mutex lock */ + mutex_lock(&inode->i_mutex); +- + /* Currently just for extent based files */ + if (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) { + ret = -EOPNOTSUPP; +@@ -5660,17 +5657,32 @@ int ext4_insert_range(struct inode *inode, loff_t offset, loff_t len) + goto out_mutex; + } + +- truncate_pagecache(inode, ioffset); +- + /* Wait for existing dio to complete */ + ext4_inode_block_unlocked_dio(inode); + inode_dio_wait(inode); + ++ /* ++ * Prevent page faults from reinstantiating pages we have released from ++ * page cache. ++ */ ++ down_write(&EXT4_I(inode)->i_mmap_sem); ++ /* ++ * Need to round down to align start offset to page size boundary ++ * for page size > block size. ++ */ ++ ioffset = round_down(offset, PAGE_SIZE); ++ /* Write out all dirty pages */ ++ ret = filemap_write_and_wait_range(inode->i_mapping, ioffset, ++ LLONG_MAX); ++ if (ret) ++ goto out_mmap; ++ truncate_pagecache(inode, ioffset); ++ + credits = ext4_writepage_trans_blocks(inode); + handle = ext4_journal_start(inode, EXT4_HT_TRUNCATE, credits); + if (IS_ERR(handle)) { + ret = PTR_ERR(handle); +- goto out_dio; ++ goto out_mmap; + } + + /* Expand file to avoid data loss if there is error while shifting */ +@@ -5741,7 +5753,8 @@ int ext4_insert_range(struct inode *inode, loff_t offset, loff_t len) + + out_stop: + ext4_journal_stop(handle); +-out_dio: ++out_mmap: ++ up_write(&EXT4_I(inode)->i_mmap_sem); + ext4_inode_resume_unlocked_dio(inode); + out_mutex: + mutex_unlock(&inode->i_mutex); +diff --git a/fs/ext4/file.c b/fs/ext4/file.c +index 113837e..0d24ebc 100644 +--- a/fs/ext4/file.c ++++ b/fs/ext4/file.c +@@ -209,15 +209,18 @@ static int ext4_dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf) + { + int result; + handle_t *handle = NULL; +- struct super_block *sb = file_inode(vma->vm_file)->i_sb; ++ struct inode *inode = file_inode(vma->vm_file); ++ struct super_block *sb = inode->i_sb; + bool write = vmf->flags & FAULT_FLAG_WRITE; + + if (write) { + sb_start_pagefault(sb); + file_update_time(vma->vm_file); ++ down_read(&EXT4_I(inode)->i_mmap_sem); + handle = ext4_journal_start_sb(sb, EXT4_HT_WRITE_PAGE, + EXT4_DATA_TRANS_BLOCKS(sb)); +- } ++ } else ++ down_read(&EXT4_I(inode)->i_mmap_sem); + + if (IS_ERR(handle)) + result = VM_FAULT_SIGBUS; +@@ -228,8 +231,10 @@ static int ext4_dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf) + if (write) { + if (!IS_ERR(handle)) + ext4_journal_stop(handle); ++ up_read(&EXT4_I(inode)->i_mmap_sem); + sb_end_pagefault(sb); +- } ++ } else ++ up_read(&EXT4_I(inode)->i_mmap_sem); + + return result; + } +@@ -246,10 +251,12 @@ static int ext4_dax_pmd_fault(struct vm_area_struct *vma, unsigned long addr, + if (write) { + sb_start_pagefault(sb); + file_update_time(vma->vm_file); ++ down_read(&EXT4_I(inode)->i_mmap_sem); + handle = ext4_journal_start_sb(sb, EXT4_HT_WRITE_PAGE, + ext4_chunk_trans_blocks(inode, + PMD_SIZE / PAGE_SIZE)); +- } ++ } else ++ down_read(&EXT4_I(inode)->i_mmap_sem); + + if (IS_ERR(handle)) + result = VM_FAULT_SIGBUS; +@@ -260,30 +267,71 @@ static int ext4_dax_pmd_fault(struct vm_area_struct *vma, unsigned long addr, + if (write) { + if (!IS_ERR(handle)) + ext4_journal_stop(handle); ++ up_read(&EXT4_I(inode)->i_mmap_sem); + sb_end_pagefault(sb); +- } ++ } else ++ up_read(&EXT4_I(inode)->i_mmap_sem); + + return result; + } + + static int ext4_dax_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) + { +- return dax_mkwrite(vma, vmf, ext4_get_block_dax, +- ext4_end_io_unwritten); ++ int err; ++ struct inode *inode = file_inode(vma->vm_file); ++ ++ sb_start_pagefault(inode->i_sb); ++ file_update_time(vma->vm_file); ++ down_read(&EXT4_I(inode)->i_mmap_sem); ++ err = __dax_mkwrite(vma, vmf, ext4_get_block_dax, ++ ext4_end_io_unwritten); ++ up_read(&EXT4_I(inode)->i_mmap_sem); ++ sb_end_pagefault(inode->i_sb); ++ ++ return err; ++} ++ ++/* ++ * Handle write fault for VM_MIXEDMAP mappings. Similarly to ext4_dax_mkwrite() ++ * handler we check for races agaist truncate. Note that since we cycle through ++ * i_mmap_sem, we are sure that also any hole punching that began before we ++ * were called is finished by now and so if it included part of the file we ++ * are working on, our pte will get unmapped and the check for pte_same() in ++ * wp_pfn_shared() fails. Thus fault gets retried and things work out as ++ * desired. ++ */ ++static int ext4_dax_pfn_mkwrite(struct vm_area_struct *vma, ++ struct vm_fault *vmf) ++{ ++ struct inode *inode = file_inode(vma->vm_file); ++ struct super_block *sb = inode->i_sb; ++ int ret = VM_FAULT_NOPAGE; ++ loff_t size; ++ ++ sb_start_pagefault(sb); ++ file_update_time(vma->vm_file); ++ down_read(&EXT4_I(inode)->i_mmap_sem); ++ size = (i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT; ++ if (vmf->pgoff >= size) ++ ret = VM_FAULT_SIGBUS; ++ up_read(&EXT4_I(inode)->i_mmap_sem); ++ sb_end_pagefault(sb); ++ ++ return ret; + } + + static const struct vm_operations_struct ext4_dax_vm_ops = { + .fault = ext4_dax_fault, + .pmd_fault = ext4_dax_pmd_fault, + .page_mkwrite = ext4_dax_mkwrite, +- .pfn_mkwrite = dax_pfn_mkwrite, ++ .pfn_mkwrite = ext4_dax_pfn_mkwrite, + }; + #else + #define ext4_dax_vm_ops ext4_file_vm_ops + #endif + + static const struct vm_operations_struct ext4_file_vm_ops = { +- .fault = filemap_fault, ++ .fault = ext4_filemap_fault, + .map_pages = filemap_map_pages, + .page_mkwrite = ext4_page_mkwrite, + }; +diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c +index 06bda03..e573d11 100644 +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -3587,6 +3587,35 @@ int ext4_can_truncate(struct inode *inode) + } + + /* ++ * We have to make sure i_disksize gets properly updated before we truncate ++ * page cache due to hole punching or zero range. Otherwise i_disksize update ++ * can get lost as it may have been postponed to submission of writeback but ++ * that will never happen after we truncate page cache. ++ */ ++int ext4_update_disksize_before_punch(struct inode *inode, loff_t offset, ++ loff_t len) ++{ ++ handle_t *handle; ++ loff_t size = i_size_read(inode); ++ ++ WARN_ON(!mutex_is_locked(&inode->i_mutex)); ++ if (offset > size || offset + len < size) ++ return 0; ++ ++ if (EXT4_I(inode)->i_disksize >= size) ++ return 0; ++ ++ handle = ext4_journal_start(inode, EXT4_HT_MISC, 1); ++ if (IS_ERR(handle)) ++ return PTR_ERR(handle); ++ ext4_update_i_disksize(inode, size); ++ ext4_mark_inode_dirty(handle, inode); ++ ext4_journal_stop(handle); ++ ++ return 0; ++} ++ ++/* + * ext4_punch_hole: punches a hole in a file by releaseing the blocks + * associated with the given offset and length + * +@@ -3651,17 +3680,26 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length) + + } + ++ /* Wait all existing dio workers, newcomers will block on i_mutex */ ++ ext4_inode_block_unlocked_dio(inode); ++ inode_dio_wait(inode); ++ ++ /* ++ * Prevent page faults from reinstantiating pages we have released from ++ * page cache. ++ */ ++ down_write(&EXT4_I(inode)->i_mmap_sem); + first_block_offset = round_up(offset, sb->s_blocksize); + last_block_offset = round_down((offset + length), sb->s_blocksize) - 1; + + /* Now release the pages and zero block aligned part of pages*/ +- if (last_block_offset > first_block_offset) ++ if (last_block_offset > first_block_offset) { ++ ret = ext4_update_disksize_before_punch(inode, offset, length); ++ if (ret) ++ goto out_dio; + truncate_pagecache_range(inode, first_block_offset, + last_block_offset); +- +- /* Wait all existing dio workers, newcomers will block on i_mutex */ +- ext4_inode_block_unlocked_dio(inode); +- inode_dio_wait(inode); ++ } + + if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) + credits = ext4_writepage_trans_blocks(inode); +@@ -3708,16 +3746,12 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length) + if (IS_SYNC(inode)) + ext4_handle_sync(handle); + +- /* Now release the pages again to reduce race window */ +- if (last_block_offset > first_block_offset) +- truncate_pagecache_range(inode, first_block_offset, +- last_block_offset); +- + inode->i_mtime = inode->i_ctime = ext4_current_time(inode); + ext4_mark_inode_dirty(handle, inode); + out_stop: + ext4_journal_stop(handle); + out_dio: ++ up_write(&EXT4_I(inode)->i_mmap_sem); + ext4_inode_resume_unlocked_dio(inode); + out_mutex: + mutex_unlock(&inode->i_mutex); +@@ -4851,6 +4885,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) + } else + ext4_wait_for_tail_page_commit(inode); + } ++ down_write(&EXT4_I(inode)->i_mmap_sem); + /* + * Truncate pagecache after we've waited for commit + * in data=journal mode to make pages freeable. +@@ -4858,6 +4893,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) + truncate_pagecache(inode, inode->i_size); + if (shrink) + ext4_truncate(inode); ++ up_write(&EXT4_I(inode)->i_mmap_sem); + } + + if (!rc) { +@@ -5306,6 +5342,8 @@ int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) + + sb_start_pagefault(inode->i_sb); + file_update_time(vma->vm_file); ++ ++ down_read(&EXT4_I(inode)->i_mmap_sem); + /* Delalloc case is easy... */ + if (test_opt(inode->i_sb, DELALLOC) && + !ext4_should_journal_data(inode) && +@@ -5375,6 +5413,19 @@ retry_alloc: + out_ret: + ret = block_page_mkwrite_return(ret); + out: ++ up_read(&EXT4_I(inode)->i_mmap_sem); + sb_end_pagefault(inode->i_sb); + return ret; + } ++ ++int ext4_filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) ++{ ++ struct inode *inode = file_inode(vma->vm_file); ++ int err; ++ ++ down_read(&EXT4_I(inode)->i_mmap_sem); ++ err = filemap_fault(vma, vmf); ++ up_read(&EXT4_I(inode)->i_mmap_sem); ++ ++ return err; ++} diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 61eaf74..01a829b 100644 --- a/fs/ext4/mballoc.c @@ -81056,10 +82340,18 @@ index 34038e3..322fe62 100644 err = ext4_handle_dirty_metadata(handle, NULL, bh); if (unlikely(err)) diff --git a/fs/ext4/super.c b/fs/ext4/super.c -index c9ab67d..3c937171 100644 +index c9ab67d..74fc72e 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c -@@ -1274,7 +1274,7 @@ static ext4_fsblk_t get_sb_block(void **data) +@@ -958,6 +958,7 @@ static void init_once(void *foo) + INIT_LIST_HEAD(&ei->i_orphan); + init_rwsem(&ei->xattr_sem); + init_rwsem(&ei->i_data_sem); ++ init_rwsem(&ei->i_mmap_sem); + inode_init_once(&ei->vfs_inode); + } + +@@ -1274,7 +1275,7 @@ static ext4_fsblk_t get_sb_block(void **data) } #define DEFAULT_JOURNAL_IOPRIO (IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 3)) @@ -81081,6 +82373,21 @@ index 1420a3c..e87523c 100644 static ssize_t session_write_kbytes_show(struct ext4_attr *a, struct ext4_sb_info *sbi, char *buf) +diff --git a/fs/ext4/truncate.h b/fs/ext4/truncate.h +index 011ba66..c70d06a 100644 +--- a/fs/ext4/truncate.h ++++ b/fs/ext4/truncate.h +@@ -10,8 +10,10 @@ + */ + static inline void ext4_truncate_failed_write(struct inode *inode) + { ++ down_write(&EXT4_I(inode)->i_mmap_sem); + truncate_inode_pages(inode->i_mapping, inode->i_size); + ext4_truncate(inode); ++ up_write(&EXT4_I(inode)->i_mmap_sem); + } + + /* diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 6b6b3e7..0cbeeb9 100644 --- a/fs/ext4/xattr.c @@ -81122,7 +82429,7 @@ index ee85cd4..9dd0d20 100644 } EXPORT_SYMBOL(__f_setown); diff --git a/fs/fhandle.c b/fs/fhandle.c -index d59712d..2c63363 100644 +index d59712d..0c5456e 100644 --- a/fs/fhandle.c +++ b/fs/fhandle.c @@ -8,6 +8,7 @@ @@ -81161,6 +82468,15 @@ index d59712d..2c63363 100644 f_handle.handle_bytes)) { retval = -EFAULT; goto out_handle; +@@ -228,7 +228,7 @@ long do_handle_open(int mountdirfd, + path_put(&path); + return fd; + } +- file = file_open_root(path.dentry, path.mnt, "", open_flag); ++ file = file_open_root(path.dentry, path.mnt, "", open_flag, 0); + if (IS_ERR(file)) { + put_unused_fd(fd); + retval = PTR_ERR(file); diff --git a/fs/file.c b/fs/file.c index 39f8f15..898d887 100644 --- a/fs/file.c @@ -84168,6 +85484,23 @@ index 3e2071a..c09f4b6 100644 } EXPORT_SYMBOL_GPL(nfs_inc_attr_generation_counter); +diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h +index 9dea85f..ceb98c9 100644 +--- a/fs/nfs/internal.h ++++ b/fs/nfs/internal.h +@@ -612,9 +612,10 @@ unsigned long nfs_block_size(unsigned long bsize, unsigned char *nrbitsp) + static inline + void nfs_super_set_maxbytes(struct super_block *sb, __u64 maxfilesize) + { +- sb->s_maxbytes = (loff_t)maxfilesize; +- if (sb->s_maxbytes > MAX_LFS_FILESIZE || sb->s_maxbytes <= 0) ++ if (maxfilesize > MAX_LFS_FILESIZE || maxfilesize == 0) + sb->s_maxbytes = MAX_LFS_FILESIZE; ++ else ++ sb->s_maxbytes = (loff_t)maxfilesize; + } + + /* diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index a9f096c..fa0310f 100644 --- a/fs/nfsd/nfs4proc.c @@ -84677,7 +86010,7 @@ index 2de4c8a..a106a0d 100644 /* Copy the blockcheck stats from the superblock probe */ osb->osb_ecc_stats = *stats; diff --git a/fs/open.c b/fs/open.c -index b6f1e96..3108eed 100644 +index b6f1e96..c16baf7 100644 --- a/fs/open.c +++ b/fs/open.c @@ -32,6 +32,8 @@ @@ -84781,7 +86114,24 @@ index b6f1e96..3108eed 100644 retry_deleg: newattrs.ia_valid = ATTR_CTIME; if (user != (uid_t) -1) { -@@ -1029,6 +1066,7 @@ long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode) +@@ -995,14 +1032,12 @@ struct file *filp_open(const char *filename, int flags, umode_t mode) + EXPORT_SYMBOL(filp_open); + + struct file *file_open_root(struct dentry *dentry, struct vfsmount *mnt, +- const char *filename, int flags) ++ const char *filename, int flags, umode_t mode) + { + struct open_flags op; +- int err = build_open_flags(flags, 0, &op); ++ int err = build_open_flags(flags, mode, &op); + if (err) + return ERR_PTR(err); +- if (flags & O_CREAT) +- return ERR_PTR(-EINVAL); + return do_file_open_root(dentry, mnt, filename, &op); + } + EXPORT_SYMBOL(file_open_root); +@@ -1029,6 +1064,7 @@ long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode) } else { fsnotify_open(f); fd_install(fd, f); @@ -86183,9 +87533,18 @@ index a352d57..cb94a5c 100644 } fs_initcall(proc_interrupts_init); diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c -index 92e6726..93a72d0 100644 +index 92e6726..47a8d4c 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c +@@ -316,7 +316,7 @@ static char *storenote(struct memelfnote *men, char *bufp) + * store an ELF coredump header in the supplied buffer + * nphdr is the number of elf_phdr to insert + */ +-static void elf_kcore_store_hdr(char *bufp, int nphdr, int dataoff) ++static void elf_kcore_store_hdr(char *bufp, int nphdr, size_t dataoff) + { + struct elf_prstatus prstatus; /* NT_PRSTATUS */ + struct elf_prpsinfo prpsinfo; /* NT_PRPSINFO */ @@ -483,9 +483,10 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos) * the addresses in the elf_phdr on our list. */ @@ -101318,7 +102677,7 @@ index 5295535..9852c7e 100644 int iterate_fd(struct files_struct *, unsigned, int (*)(const void *, struct file *, unsigned), diff --git a/include/linux/fs.h b/include/linux/fs.h -index 3aa5142..8b8d8ee 100644 +index 3aa5142..264567c 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -439,7 +439,7 @@ struct address_space { @@ -101385,6 +102744,15 @@ index 3aa5142..8b8d8ee 100644 struct inode_operations { struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int); +@@ -2217,7 +2218,7 @@ extern long do_sys_open(int dfd, const char __user *filename, int flags, + extern struct file *file_open_name(struct filename *, int, umode_t); + extern struct file *filp_open(const char *, int, umode_t); + extern struct file *file_open_root(struct dentry *, struct vfsmount *, +- const char *, int); ++ const char *, int, umode_t); + extern struct file * dentry_open(const struct path *, int, const struct cred *); + extern int filp_close(struct file *, fl_owner_t id); + @@ -2336,7 +2337,7 @@ extern int register_chrdev_region(dev_t, unsigned, const char *); extern int __register_chrdev(unsigned int major, unsigned int baseminor, unsigned int count, const char *name, @@ -107812,7 +109180,7 @@ index 487ef34..d457f98 100644 /* Get the size of a DATA chunk payload. */ diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h -index eea9bde..909b45c 100644 +index eea9bde..1d4ec5d 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -513,7 +513,7 @@ struct sctp_pf { @@ -107824,6 +109192,15 @@ index eea9bde..909b45c 100644 /* Structure to track chunk fragments that have been acked, but peer +@@ -1099,7 +1099,7 @@ int sctp_bind_addr_dup(struct sctp_bind_addr *dest, + const struct sctp_bind_addr *src, + gfp_t gfp); + int sctp_add_bind_addr(struct sctp_bind_addr *, union sctp_addr *, +- __u8 addr_state, gfp_t gfp); ++ int new_size, __u8 addr_state, gfp_t gfp); + int sctp_del_bind_addr(struct sctp_bind_addr *, union sctp_addr *); + int sctp_bind_addr_match(struct sctp_bind_addr *, const union sctp_addr *, + struct sctp_sock *); diff --git a/include/net/snmp.h b/include/net/snmp.h index 35512ac..edbd85b 100644 --- a/include/net/snmp.h @@ -111291,7 +112668,7 @@ index 11b64a6..d011095 100644 void crash_kexec(struct pt_regs *regs) { diff --git a/kernel/kmod.c b/kernel/kmod.c -index 0277d12..8c01709 100644 +index 0277d12..2d2899c 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c @@ -66,7 +66,7 @@ static void free_modprobe_argv(struct subprocess_info *info) @@ -111440,7 +112817,7 @@ index 0277d12..8c01709 100644 + if ((strncmp(sub_info->path, "/sbin/", 6) && strncmp(sub_info->path, "/usr/lib/", 9) && + strncmp(sub_info->path, "/lib/", 5) && strncmp(sub_info->path, "/lib64/", 7) && + strncmp(sub_info->path, "/usr/libexec/", 13) && strncmp(sub_info->path, "/usr/bin/", 9) && -+ strncmp(sub_info->path, "/usr/sbin/", 10) && ++ strncmp(sub_info->path, "/usr/sbin/", 10) && strcmp(sub_info->path, "/bin/false") && + strcmp(sub_info->path, "/usr/share/apport/apport")) || strstr(sub_info->path, "..")) { + printk(KERN_ALERT "grsec: denied exec of usermode helper binary %.950s located outside of permitted system paths\n", sub_info->path); + retval = -EPERM; @@ -111728,7 +113105,7 @@ index 0551c21..f753f95 100644 debug_mutex_free_waiter(&waiter); mutex_release(&lock->dep_map, 1, ip); diff --git a/kernel/module.c b/kernel/module.c -index 0e5c711..540d4d4 100644 +index 0e5c711..940c5c0 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -59,6 +59,7 @@ @@ -112288,7 +113665,7 @@ index 0e5c711..540d4d4 100644 } /* -@@ -2519,21 +2597,24 @@ static void add_kallsyms(struct module *mod, const struct load_info *info) +@@ -2519,7 +2597,9 @@ static void add_kallsyms(struct module *mod, const struct load_info *info) Elf_Shdr *symsec = &info->sechdrs[info->index.sym]; /* Set up to point into init section. */ @@ -112299,13 +113676,7 @@ index 0e5c711..540d4d4 100644 mod->kallsyms->symtab = (void *)symsec->sh_addr; mod->kallsyms->num_symtab = symsec->sh_size / sizeof(Elf_Sym); - /* Make sure we get permanent strtab: don't use info->strtab. */ - mod->kallsyms->strtab = (void *)info->sechdrs[info->index.str].sh_addr; - -+ - /* Set types up while we still have access to sections. */ - for (i = 0; i < mod->kallsyms->num_symtab; i++) - mod->kallsyms->symtab[i].st_info +@@ -2532,8 +2612,8 @@ static void add_kallsyms(struct module *mod, const struct load_info *info) = elf_type(&mod->kallsyms->symtab[i], info); /* Now populate the cut down core kallsyms for after init. */ @@ -112316,7 +113687,7 @@ index 0e5c711..540d4d4 100644 src = mod->kallsyms->symtab; for (ndst = i = 0; i < mod->kallsyms->num_symtab; i++) { if (i == 0 || -@@ -2545,6 +2626,8 @@ static void add_kallsyms(struct module *mod, const struct load_info *info) +@@ -2545,6 +2625,8 @@ static void add_kallsyms(struct module *mod, const struct load_info *info) } } mod->core_kallsyms.num_symtab = ndst; @@ -112325,7 +113696,7 @@ index 0e5c711..540d4d4 100644 } #else static inline void layout_symtab(struct module *mod, struct load_info *info) -@@ -2844,7 +2927,15 @@ static struct module *setup_load_info(struct load_info *info, int flags) +@@ -2844,7 +2926,15 @@ static struct module *setup_load_info(struct load_info *info, int flags) mod = (void *)info->sechdrs[info->index.mod].sh_addr; if (info->index.sym == 0) { @@ -112341,7 +113712,7 @@ index 0e5c711..540d4d4 100644 return ERR_PTR(-ENOEXEC); } -@@ -2860,8 +2951,14 @@ static struct module *setup_load_info(struct load_info *info, int flags) +@@ -2860,8 +2950,14 @@ static struct module *setup_load_info(struct load_info *info, int flags) static int check_modinfo(struct module *mod, struct load_info *info, int flags) { const char *modmagic = get_modinfo(info, "vermagic"); @@ -112356,7 +113727,7 @@ index 0e5c711..540d4d4 100644 if (flags & MODULE_INIT_IGNORE_VERMAGIC) modmagic = NULL; -@@ -2886,7 +2983,7 @@ static int check_modinfo(struct module *mod, struct load_info *info, int flags) +@@ -2886,7 +2982,7 @@ static int check_modinfo(struct module *mod, struct load_info *info, int flags) } /* Set up license info based on the info section */ @@ -112365,7 +113736,7 @@ index 0e5c711..540d4d4 100644 return 0; } -@@ -2983,7 +3080,7 @@ static int move_module(struct module *mod, struct load_info *info) +@@ -2983,7 +3079,7 @@ static int move_module(struct module *mod, struct load_info *info) void *ptr; /* Do the allocs. */ @@ -112374,7 +113745,7 @@ index 0e5c711..540d4d4 100644 /* * The pointer to this block is stored in the module structure * which is inside the block. Just mark it as not being a -@@ -2993,11 +3090,11 @@ static int move_module(struct module *mod, struct load_info *info) +@@ -2993,11 +3089,11 @@ static int move_module(struct module *mod, struct load_info *info) if (!ptr) return -ENOMEM; @@ -112390,7 +113761,7 @@ index 0e5c711..540d4d4 100644 /* * The pointer to this block is stored in the module structure * which is inside the block. This block doesn't need to be -@@ -3006,13 +3103,45 @@ static int move_module(struct module *mod, struct load_info *info) +@@ -3006,13 +3102,45 @@ static int move_module(struct module *mod, struct load_info *info) */ kmemleak_ignore(ptr); if (!ptr) { @@ -112423,7 +113794,7 @@ index 0e5c711..540d4d4 100644 + if (mod->init_size_rx) { + ptr = module_alloc_exec(mod->init_size_rx); + kmemleak_ignore(ptr); -+ if (!ptr && mod->init_size_rx) { ++ if (!ptr) { + module_memfree_exec(mod->module_core_rx); + if (mod->module_init_rw) + module_memfree(mod->module_init_rw); @@ -112440,7 +113811,7 @@ index 0e5c711..540d4d4 100644 /* Transfer each section which specifies SHF_ALLOC */ pr_debug("final section addresses:\n"); -@@ -3023,16 +3152,45 @@ static int move_module(struct module *mod, struct load_info *info) +@@ -3023,16 +3151,45 @@ static int move_module(struct module *mod, struct load_info *info) if (!(shdr->sh_flags & SHF_ALLOC)) continue; @@ -112493,7 +113864,7 @@ index 0e5c711..540d4d4 100644 pr_debug("\t0x%lx %s\n", (long)shdr->sh_addr, info->secstrings + shdr->sh_name); } -@@ -3089,12 +3247,12 @@ static void flush_module_icache(const struct module *mod) +@@ -3089,12 +3246,12 @@ static void flush_module_icache(const struct module *mod) * Do it before processing of module parameters, so the module * can provide parameter accessor functions of its own. */ @@ -112512,7 +113883,7 @@ index 0e5c711..540d4d4 100644 set_fs(old_fs); } -@@ -3152,8 +3310,10 @@ static void module_deallocate(struct module *mod, struct load_info *info) +@@ -3152,8 +3309,10 @@ static void module_deallocate(struct module *mod, struct load_info *info) { percpu_modfree(mod); module_arch_freeing_init(mod); @@ -112525,7 +113896,7 @@ index 0e5c711..540d4d4 100644 } int __weak module_finalize(const Elf_Ehdr *hdr, -@@ -3166,7 +3326,9 @@ int __weak module_finalize(const Elf_Ehdr *hdr, +@@ -3166,7 +3325,9 @@ int __weak module_finalize(const Elf_Ehdr *hdr, static int post_relocation(struct module *mod, const struct load_info *info) { /* Sort exception table now relocations are done. */ @@ -112535,7 +113906,7 @@ index 0e5c711..540d4d4 100644 /* Copy relocated percpu area over. */ percpu_modcopy(mod, (void *)info->sechdrs[info->index.pcpu].sh_addr, -@@ -3214,13 +3376,15 @@ static void do_mod_ctors(struct module *mod) +@@ -3214,13 +3375,15 @@ static void do_mod_ctors(struct module *mod) /* For freeing module_init on success, in case kallsyms traversing */ struct mod_initfree { struct rcu_head rcu; @@ -112553,7 +113924,7 @@ index 0e5c711..540d4d4 100644 kfree(m); } -@@ -3240,7 +3404,8 @@ static noinline int do_init_module(struct module *mod) +@@ -3240,7 +3403,8 @@ static noinline int do_init_module(struct module *mod) ret = -ENOMEM; goto fail; } @@ -112563,7 +113934,7 @@ index 0e5c711..540d4d4 100644 /* * We want to find out whether @mod uses async during init. Clear -@@ -3299,10 +3464,10 @@ static noinline int do_init_module(struct module *mod) +@@ -3299,10 +3463,10 @@ static noinline int do_init_module(struct module *mod) mod_tree_remove_init(mod); unset_module_init_ro_nx(mod); module_arch_freeing_init(mod); @@ -112578,7 +113949,7 @@ index 0e5c711..540d4d4 100644 /* * We want to free module_init, but be aware that kallsyms may be * walking this with preempt disabled. In all the failure paths, we -@@ -3392,16 +3557,16 @@ static int complete_formation(struct module *mod, struct load_info *info) +@@ -3392,16 +3556,16 @@ static int complete_formation(struct module *mod, struct load_info *info) module_bug_finalize(info->hdr, info->sechdrs, mod); /* Set RO and NX regions for core */ @@ -112603,7 +113974,7 @@ index 0e5c711..540d4d4 100644 /* Mark state as coming so strong_try_module_get() ignores us, * but kallsyms etc. can see us. */ -@@ -3496,9 +3661,38 @@ static int load_module(struct load_info *info, const char __user *uargs, +@@ -3496,9 +3660,38 @@ static int load_module(struct load_info *info, const char __user *uargs, if (err) goto free_unload; @@ -112642,7 +114013,7 @@ index 0e5c711..540d4d4 100644 /* Fix up syms, so that st_value is a pointer to location. */ err = simplify_symbols(mod, info); if (err < 0) -@@ -3514,13 +3708,6 @@ static int load_module(struct load_info *info, const char __user *uargs, +@@ -3514,13 +3707,6 @@ static int load_module(struct load_info *info, const char __user *uargs, flush_module_icache(mod); @@ -112656,7 +114027,7 @@ index 0e5c711..540d4d4 100644 dynamic_debug_setup(info->debug, info->num_debug); /* Ftrace init must be called in the MODULE_STATE_UNFORMED state */ -@@ -3572,11 +3759,10 @@ static int load_module(struct load_info *info, const char __user *uargs, +@@ -3572,11 +3758,10 @@ static int load_module(struct load_info *info, const char __user *uargs, ddebug_cleanup: dynamic_debug_remove(info->debug); synchronize_sched(); @@ -112669,7 +114040,7 @@ index 0e5c711..540d4d4 100644 free_unload: module_unload_free(mod); unlink_mod: -@@ -3596,7 +3782,8 @@ static int load_module(struct load_info *info, const char __user *uargs, +@@ -3596,7 +3781,8 @@ static int load_module(struct load_info *info, const char __user *uargs, */ ftrace_release_mod(mod); /* Free lock-classes; relies on the preceding sync_rcu() */ @@ -112679,7 +114050,7 @@ index 0e5c711..540d4d4 100644 module_deallocate(mod, info); free_copy: -@@ -3679,10 +3866,16 @@ static const char *get_ksymbol(struct module *mod, +@@ -3679,10 +3865,16 @@ static const char *get_ksymbol(struct module *mod, struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms); /* At worse, next value is at end of module */ @@ -112699,7 +114070,7 @@ index 0e5c711..540d4d4 100644 /* Scan for closest preceding symbol, and next symbol. (ELF starts real symbols at 1). */ -@@ -3935,7 +4128,7 @@ static int m_show(struct seq_file *m, void *p) +@@ -3935,7 +4127,7 @@ static int m_show(struct seq_file *m, void *p) return 0; seq_printf(m, "%s %u", @@ -112708,7 +114079,7 @@ index 0e5c711..540d4d4 100644 print_unload_info(m, mod); /* Informative for users. */ -@@ -3944,7 +4137,7 @@ static int m_show(struct seq_file *m, void *p) +@@ -3944,7 +4136,7 @@ static int m_show(struct seq_file *m, void *p) mod->state == MODULE_STATE_COMING ? "Loading" : "Live"); /* Used by oprofile and other similar tools. */ @@ -112717,7 +114088,7 @@ index 0e5c711..540d4d4 100644 /* Taints info */ if (mod->taints) -@@ -3980,7 +4173,17 @@ static const struct file_operations proc_modules_operations = { +@@ -3980,7 +4172,17 @@ static const struct file_operations proc_modules_operations = { static int __init proc_modules_init(void) { @@ -112735,7 +114106,7 @@ index 0e5c711..540d4d4 100644 return 0; } module_init(proc_modules_init); -@@ -4041,7 +4244,8 @@ struct module *__module_address(unsigned long addr) +@@ -4041,7 +4243,8 @@ struct module *__module_address(unsigned long addr) { struct module *mod; @@ -112745,7 +114116,7 @@ index 0e5c711..540d4d4 100644 return NULL; module_assert_mutex_or_preempt(); -@@ -4084,11 +4288,20 @@ bool is_module_text_address(unsigned long addr) +@@ -4084,11 +4287,20 @@ bool is_module_text_address(unsigned long addr) */ struct module *__module_text_address(unsigned long addr) { @@ -113440,7 +114811,7 @@ index 944b1b4..45d1d75 100644 __rcu_process_callbacks(&rcu_sched_ctrlblk); __rcu_process_callbacks(&rcu_bh_ctrlblk); diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c -index f07343b..d59d264 100644 +index f07343b..5a4e86f5 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -336,7 +336,7 @@ static void rcu_momentary_dyntick_idle(void) @@ -113548,7 +114919,7 @@ index f07343b..d59d264 100644 * Do RCU core processing for the current CPU. */ -static void rcu_process_callbacks(struct softirq_action *unused) -+static void rcu_process_callbacks(void) ++static __latent_entropy void rcu_process_callbacks(void) { struct rcu_state *rsp; @@ -114217,7 +115588,7 @@ index d264f59..48b8da3 100644 mutex_unlock(&smpboot_threads_lock); put_online_cpus(); diff --git a/kernel/softirq.c b/kernel/softirq.c -index 479e443..66d845e1 100644 +index 479e443..4072c49 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -53,7 +53,7 @@ irq_cpustat_t irq_stat[NR_CPUS] ____cacheline_aligned; @@ -114252,7 +115623,7 @@ index 479e443..66d845e1 100644 EXPORT_SYMBOL(__tasklet_hi_schedule_first); -static void tasklet_action(struct softirq_action *a) -+static void tasklet_action(void) ++static __latent_entropy void tasklet_action(void) { struct tasklet_struct *list; @@ -114274,6 +115645,19 @@ index 479e443..66d845e1 100644 .store = &ksoftirqd, .thread_should_run = ksoftirqd_should_run, .thread_fn = run_ksoftirqd, +diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c +index a3bbaee..e8cd0bf 100644 +--- a/kernel/stop_machine.c ++++ b/kernel/stop_machine.c +@@ -503,7 +503,7 @@ void stop_machine_unpark(int cpu) + kthread_unpark(stopper->thread); + } + +-static struct smp_hotplug_thread cpu_stop_threads = { ++static struct smp_hotplug_thread cpu_stop_threads __read_only = { + .store = &cpu_stopper.thread, + .thread_should_run = cpu_stop_should_run, + .thread_fn = cpu_stopper_thread, diff --git a/kernel/sys.c b/kernel/sys.c index 78947de..cb182d1 100644 --- a/kernel/sys.c @@ -114867,6 +116251,19 @@ index dc6858d..93aa01c 100644 +EXPORT_SYMBOL(proc_dostring_modpriv); EXPORT_SYMBOL(proc_doulongvec_minmax); EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax); +diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c +index 7e7746a..10a1d7d 100644 +--- a/kernel/sysctl_binary.c ++++ b/kernel/sysctl_binary.c +@@ -1321,7 +1321,7 @@ static ssize_t binary_sysctl(const int *name, int nlen, + } + + mnt = task_active_pid_ns(current)->proc_mnt; +- file = file_open_root(mnt->mnt_root, mnt, pathname, flags); ++ file = file_open_root(mnt->mnt_root, mnt, pathname, flags, 0); + result = PTR_ERR(file); + if (IS_ERR(file)) + goto out_putname; diff --git a/kernel/taskstats.c b/kernel/taskstats.c index 21f82c2..c1984e5 100644 --- a/kernel/taskstats.c @@ -117073,10 +118470,30 @@ index 668aa35..1b35d47 100644 {VM_NORESERVE, "noreserve" }, {VM_HUGETLB, "hugetlb" }, diff --git a/mm/filemap.c b/mm/filemap.c -index 1bb0076..6244c1d 100644 +index 1bb0076..b1f8586 100644 --- a/mm/filemap.c +++ b/mm/filemap.c -@@ -2161,7 +2161,7 @@ int generic_file_mmap(struct file * file, struct vm_area_struct * vma) +@@ -1759,15 +1759,16 @@ generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) + ssize_t retval = 0; + loff_t *ppos = &iocb->ki_pos; + loff_t pos = *ppos; ++ size_t count = iov_iter_count(iter); ++ ++ if (!count) ++ goto out; /* skip atime */ + + if (iocb->ki_flags & IOCB_DIRECT) { + struct address_space *mapping = file->f_mapping; + struct inode *inode = mapping->host; +- size_t count = iov_iter_count(iter); + loff_t size; + +- if (!count) +- goto out; /* skip atime */ + size = i_size_read(inode); + retval = filemap_write_and_wait_range(mapping, pos, + pos + count - 1); +@@ -2161,7 +2162,7 @@ int generic_file_mmap(struct file * file, struct vm_area_struct * vma) struct address_space *mapping = file->f_mapping; if (!mapping->a_ops->readpage) @@ -117085,7 +118502,7 @@ index 1bb0076..6244c1d 100644 file_accessed(file); vma->vm_ops = &generic_file_vm_ops; return 0; -@@ -2342,6 +2342,7 @@ inline ssize_t generic_write_checks(struct kiocb *iocb, struct iov_iter *from) +@@ -2342,6 +2343,7 @@ inline ssize_t generic_write_checks(struct kiocb *iocb, struct iov_iter *from) pos = iocb->ki_pos; if (limit != RLIM_INFINITY) { @@ -123052,10 +124469,19 @@ index 40197ff..58633af 100644 .priv_size = sizeof(struct net_bridge), .setup = br_dev_setup, diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c -index f46ca41..c4a7eea 100644 +index f46ca41..6e76045 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c -@@ -1535,7 +1535,7 @@ static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) +@@ -1513,6 +1513,8 @@ static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) + if (copy_from_user(&tmp, user, sizeof(tmp))) + return -EFAULT; + ++ tmp.name[sizeof(tmp.name) - 1] = '\0'; ++ + t = find_table_lock(net, tmp.name, &ret, &ebt_mutex); + if (!t) + return ret; +@@ -1535,7 +1537,7 @@ static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) tmp.valid_hooks = t->table->valid_hooks; } mutex_unlock(&ebt_mutex); @@ -123064,7 +124490,16 @@ index f46ca41..c4a7eea 100644 BUGPRINT("c2u Didn't work\n"); ret = -EFAULT; break; -@@ -2341,7 +2341,7 @@ static int compat_do_ebt_get_ctl(struct sock *sk, int cmd, +@@ -2328,6 +2330,8 @@ static int compat_do_ebt_get_ctl(struct sock *sk, int cmd, + if (copy_from_user(&tmp, user, sizeof(tmp))) + return -EFAULT; + ++ tmp.name[sizeof(tmp.name) - 1] = '\0'; ++ + t = find_table_lock(net, tmp.name, &ret, &ebt_mutex); + if (!t) + return ret; +@@ -2341,7 +2345,7 @@ static int compat_do_ebt_get_ctl(struct sock *sk, int cmd, goto out; tmp.valid_hooks = t->valid_hooks; @@ -123073,7 +124508,7 @@ index f46ca41..c4a7eea 100644 ret = -EFAULT; break; } -@@ -2352,7 +2352,7 @@ static int compat_do_ebt_get_ctl(struct sock *sk, int cmd, +@@ -2352,7 +2356,7 @@ static int compat_do_ebt_get_ctl(struct sock *sk, int cmd, tmp.entries_size = t->table->entries_size; tmp.valid_hooks = t->table->valid_hooks; @@ -124328,7 +125763,7 @@ index 59b3e0e..ff060b8 100644 struct dst_entry *dst = NULL; diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c -index f6303b1..d524bab 100644 +index f6303b1..329a13a 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -69,7 +69,8 @@ @@ -124351,7 +125786,25 @@ index f6303b1..d524bab 100644 [IPV4_DEVCONF_SEND_REDIRECTS - 1] = 1, [IPV4_DEVCONF_SECURE_REDIRECTS - 1] = 1, [IPV4_DEVCONF_SHARED_MEDIA - 1] = 1, -@@ -1579,7 +1581,7 @@ static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) +@@ -334,6 +336,9 @@ static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, + + ASSERT_RTNL(); + ++ if (in_dev->dead) ++ goto no_promotions; ++ + /* 1. Deleting primary ifaddr forces deletion all secondaries + * unless alias promotion is set + **/ +@@ -380,6 +385,7 @@ static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, + fib_del_ifaddr(ifa, ifa1); + } + ++no_promotions: + /* 2. Unlink it */ + + *ifap = ifa1->ifa_next; +@@ -1579,7 +1585,7 @@ static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) idx = 0; head = &net->dev_index_head[h]; rcu_read_lock(); @@ -124360,7 +125813,7 @@ index f6303b1..d524bab 100644 net->dev_base_seq; hlist_for_each_entry_rcu(dev, head, index_hlist) { if (idx < s_idx) -@@ -1907,7 +1909,7 @@ static int inet_netconf_dump_devconf(struct sk_buff *skb, +@@ -1907,7 +1913,7 @@ static int inet_netconf_dump_devconf(struct sk_buff *skb, idx = 0; head = &net->dev_index_head[h]; rcu_read_lock(); @@ -124369,7 +125822,7 @@ index f6303b1..d524bab 100644 net->dev_base_seq; hlist_for_each_entry_rcu(dev, head, index_hlist) { if (idx < s_idx) -@@ -2148,7 +2150,7 @@ static int ipv4_doint_and_flush(struct ctl_table *ctl, int write, +@@ -2148,7 +2154,7 @@ static int ipv4_doint_and_flush(struct ctl_table *ctl, int write, #define DEVINET_SYSCTL_FLUSHING_ENTRY(attr, name) \ DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, ipv4_doint_and_flush) @@ -124378,7 +125831,7 @@ index f6303b1..d524bab 100644 struct ctl_table_header *sysctl_header; struct ctl_table devinet_vars[__IPV4_DEVCONF_MAX]; } devinet_sysctl = { -@@ -2282,7 +2284,7 @@ static __net_init int devinet_init_net(struct net *net) +@@ -2282,7 +2288,7 @@ static __net_init int devinet_init_net(struct net *net) int err; struct ipv4_devconf *all, *dflt; #ifdef CONFIG_SYSCTL @@ -124387,7 +125840,7 @@ index f6303b1..d524bab 100644 struct ctl_table_header *forw_hdr; #endif -@@ -2300,7 +2302,7 @@ static __net_init int devinet_init_net(struct net *net) +@@ -2300,7 +2306,7 @@ static __net_init int devinet_init_net(struct net *net) goto err_alloc_dflt; #ifdef CONFIG_SYSCTL @@ -124396,7 +125849,7 @@ index f6303b1..d524bab 100644 if (!tbl) goto err_alloc_ctl; -@@ -2320,7 +2322,10 @@ static __net_init int devinet_init_net(struct net *net) +@@ -2320,7 +2326,10 @@ static __net_init int devinet_init_net(struct net *net) goto err_reg_dflt; err = -ENOMEM; @@ -124408,7 +125861,7 @@ index f6303b1..d524bab 100644 if (!forw_hdr) goto err_reg_ctl; net->ipv4.forw_hdr = forw_hdr; -@@ -2336,8 +2341,7 @@ err_reg_ctl: +@@ -2336,8 +2345,7 @@ err_reg_ctl: err_reg_dflt: __devinet_sysctl_unregister(all); err_reg_all: @@ -124419,10 +125872,28 @@ index f6303b1..d524bab 100644 #endif if (dflt != &ipv4_devconf_dflt) diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c -index 4734475..8ef3aab 100644 +index 4734475..abceb0a 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c -@@ -1133,12 +1133,12 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event, +@@ -922,6 +922,9 @@ void fib_del_ifaddr(struct in_ifaddr *ifa, struct in_ifaddr *iprim) + subnet = 1; + } + ++ if (in_dev->dead) ++ goto no_promotions; ++ + /* Deletion is more complicated than add. + * We should take care of not to delete too much :-) + * +@@ -997,6 +1000,7 @@ void fib_del_ifaddr(struct in_ifaddr *ifa, struct in_ifaddr *iprim) + } + } + ++no_promotions: + if (!(ok & BRD_OK)) + fib_magic(RTM_DELROUTE, RTN_BROADCAST, ifa->ifa_broadcast, 32, prim); + if (subnet && ifa->ifa_prefixlen < 31) { +@@ -1133,12 +1137,12 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event, #ifdef CONFIG_IP_ROUTE_MULTIPATH fib_sync_up(dev, RTNH_F_DEAD); #endif @@ -124437,7 +125908,7 @@ index 4734475..8ef3aab 100644 if (!ifa->ifa_dev->ifa_list) { /* Last address was deleted from this interface. * Disable IP. -@@ -1178,7 +1178,7 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo +@@ -1178,7 +1182,7 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo #ifdef CONFIG_IP_ROUTE_MULTIPATH fib_sync_up(dev, RTNH_F_DEAD); #endif @@ -124757,9 +126228,112 @@ index a09fb0d..24e19b2 100644 .maxtype = IFLA_IPTUN_MAX, .policy = ipip_policy, diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c -index 11dccba..60aa8e6 100644 +index 11dccba..db794f4 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c +@@ -359,11 +359,12 @@ unsigned int arpt_do_table(struct sk_buff *skb, + } + + /* All zeroes == unconditional rule. */ +-static inline bool unconditional(const struct arpt_arp *arp) ++static inline bool unconditional(const struct arpt_entry *e) + { + static const struct arpt_arp uncond; + +- return memcmp(arp, &uncond, sizeof(uncond)) == 0; ++ return e->target_offset == sizeof(struct arpt_entry) && ++ memcmp(&e->arp, &uncond, sizeof(uncond)) == 0; + } + + /* Figures out from what hook each rule can be called: returns 0 if +@@ -402,11 +403,10 @@ static int mark_source_chains(const struct xt_table_info *newinfo, + |= ((1 << hook) | (1 << NF_ARP_NUMHOOKS)); + + /* Unconditional return/END. */ +- if ((e->target_offset == sizeof(struct arpt_entry) && ++ if ((unconditional(e) && + (strcmp(t->target.u.user.name, + XT_STANDARD_TARGET) == 0) && +- t->verdict < 0 && unconditional(&e->arp)) || +- visited) { ++ t->verdict < 0) || visited) { + unsigned int oldpos, size; + + if ((strcmp(t->target.u.user.name, +@@ -474,14 +474,12 @@ next: + return 1; + } + +-static inline int check_entry(const struct arpt_entry *e, const char *name) ++static inline int check_entry(const struct arpt_entry *e) + { + const struct xt_entry_target *t; + +- if (!arp_checkentry(&e->arp)) { +- duprintf("arp_tables: arp check failed %p %s.\n", e, name); ++ if (!arp_checkentry(&e->arp)) + return -EINVAL; +- } + + if (e->target_offset + sizeof(struct xt_entry_target) > e->next_offset) + return -EINVAL; +@@ -522,10 +520,6 @@ find_check_entry(struct arpt_entry *e, const char *name, unsigned int size) + struct xt_target *target; + int ret; + +- ret = check_entry(e, name); +- if (ret) +- return ret; +- + e->counters.pcnt = xt_percpu_counter_alloc(); + if (IS_ERR_VALUE(e->counters.pcnt)) + return -ENOMEM; +@@ -557,7 +551,7 @@ static bool check_underflow(const struct arpt_entry *e) + const struct xt_entry_target *t; + unsigned int verdict; + +- if (!unconditional(&e->arp)) ++ if (!unconditional(e)) + return false; + t = arpt_get_target_c(e); + if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0) +@@ -576,9 +570,11 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e, + unsigned int valid_hooks) + { + unsigned int h; ++ int err; + + if ((unsigned long)e % __alignof__(struct arpt_entry) != 0 || +- (unsigned char *)e + sizeof(struct arpt_entry) >= limit) { ++ (unsigned char *)e + sizeof(struct arpt_entry) >= limit || ++ (unsigned char *)e + e->next_offset > limit) { + duprintf("Bad offset %p\n", e); + return -EINVAL; + } +@@ -590,6 +586,10 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e, + return -EINVAL; + } + ++ err = check_entry(e); ++ if (err) ++ return err; ++ + /* Check hooks & underflows */ + for (h = 0; h < NF_ARP_NUMHOOKS; h++) { + if (!(valid_hooks & (1 << h))) +@@ -598,9 +598,9 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e, + newinfo->hook_entry[h] = hook_entries[h]; + if ((unsigned char *)e - base == underflows[h]) { + if (!check_underflow(e)) { +- pr_err("Underflows must be unconditional and " +- "use the STANDARD target with " +- "ACCEPT/DROP\n"); ++ pr_debug("Underflows must be unconditional and " ++ "use the STANDARD target with " ++ "ACCEPT/DROP\n"); + return -EINVAL; + } + newinfo->underflow[h] = underflows[h]; @@ -892,14 +892,14 @@ static int compat_table_info(const struct xt_table_info *info, #endif @@ -124787,7 +126361,42 @@ index 11dccba..60aa8e6 100644 ret = -EFAULT; else ret = 0; -@@ -1701,7 +1701,7 @@ static int compat_do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, +@@ -969,6 +969,7 @@ static int get_entries(struct net *net, struct arpt_get_entries __user *uptr, + sizeof(struct arpt_get_entries) + get.size); + return -EINVAL; + } ++ get.name[sizeof(get.name) - 1] = '\0'; + + t = xt_find_table_lock(net, NFPROTO_ARP, get.name); + if (!IS_ERR_OR_NULL(t)) { +@@ -1233,7 +1234,8 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e, + + duprintf("check_compat_entry_size_and_hooks %p\n", e); + if ((unsigned long)e % __alignof__(struct compat_arpt_entry) != 0 || +- (unsigned char *)e + sizeof(struct compat_arpt_entry) >= limit) { ++ (unsigned char *)e + sizeof(struct compat_arpt_entry) >= limit || ++ (unsigned char *)e + e->next_offset > limit) { + duprintf("Bad offset %p, limit = %p\n", e, limit); + return -EINVAL; + } +@@ -1246,7 +1248,7 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e, + } + + /* For purposes of check_entry casting the compat entry is fine */ +- ret = check_entry((struct arpt_entry *)e, name); ++ ret = check_entry((struct arpt_entry *)e); + if (ret) + return ret; + +@@ -1662,6 +1664,7 @@ static int compat_get_entries(struct net *net, + *len, sizeof(get) + get.size); + return -EINVAL; + } ++ get.name[sizeof(get.name) - 1] = '\0'; + + xt_compat_lock(NFPROTO_ARP); + t = xt_find_table_lock(net, NFPROTO_ARP, get.name); +@@ -1701,7 +1704,7 @@ static int compat_do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, switch (cmd) { case ARPT_SO_GET_INFO: @@ -124796,7 +126405,7 @@ index 11dccba..60aa8e6 100644 break; case ARPT_SO_GET_ENTRIES: ret = compat_get_entries(sock_net(sk), user, len); -@@ -1746,7 +1746,7 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len +@@ -1746,7 +1749,7 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len switch (cmd) { case ARPT_SO_GET_INFO: @@ -124806,10 +126415,127 @@ index 11dccba..60aa8e6 100644 case ARPT_SO_GET_ENTRIES: diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c -index b99affa..7fc00c8 100644 +index b99affa..c657db5 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c -@@ -1078,14 +1078,14 @@ static int compat_table_info(const struct xt_table_info *info, +@@ -168,11 +168,12 @@ get_entry(const void *base, unsigned int offset) + + /* All zeroes == unconditional rule. */ + /* Mildly perf critical (only if packet tracing is on) */ +-static inline bool unconditional(const struct ipt_ip *ip) ++static inline bool unconditional(const struct ipt_entry *e) + { + static const struct ipt_ip uncond; + +- return memcmp(ip, &uncond, sizeof(uncond)) == 0; ++ return e->target_offset == sizeof(struct ipt_entry) && ++ memcmp(&e->ip, &uncond, sizeof(uncond)) == 0; + #undef FWINV + } + +@@ -229,11 +230,10 @@ get_chainname_rulenum(const struct ipt_entry *s, const struct ipt_entry *e, + } else if (s == e) { + (*rulenum)++; + +- if (s->target_offset == sizeof(struct ipt_entry) && ++ if (unconditional(s) && + strcmp(t->target.u.kernel.target->name, + XT_STANDARD_TARGET) == 0 && +- t->verdict < 0 && +- unconditional(&s->ip)) { ++ t->verdict < 0) { + /* Tail of chains: STANDARD target (return/policy) */ + *comment = *chainname == hookname + ? comments[NF_IP_TRACE_COMMENT_POLICY] +@@ -476,11 +476,10 @@ mark_source_chains(const struct xt_table_info *newinfo, + e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS)); + + /* Unconditional return/END. */ +- if ((e->target_offset == sizeof(struct ipt_entry) && ++ if ((unconditional(e) && + (strcmp(t->target.u.user.name, + XT_STANDARD_TARGET) == 0) && +- t->verdict < 0 && unconditional(&e->ip)) || +- visited) { ++ t->verdict < 0) || visited) { + unsigned int oldpos, size; + + if ((strcmp(t->target.u.user.name, +@@ -569,14 +568,12 @@ static void cleanup_match(struct xt_entry_match *m, struct net *net) + } + + static int +-check_entry(const struct ipt_entry *e, const char *name) ++check_entry(const struct ipt_entry *e) + { + const struct xt_entry_target *t; + +- if (!ip_checkentry(&e->ip)) { +- duprintf("ip check failed %p %s.\n", e, name); ++ if (!ip_checkentry(&e->ip)) + return -EINVAL; +- } + + if (e->target_offset + sizeof(struct xt_entry_target) > + e->next_offset) +@@ -666,10 +663,6 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name, + struct xt_mtchk_param mtpar; + struct xt_entry_match *ematch; + +- ret = check_entry(e, name); +- if (ret) +- return ret; +- + e->counters.pcnt = xt_percpu_counter_alloc(); + if (IS_ERR_VALUE(e->counters.pcnt)) + return -ENOMEM; +@@ -721,7 +714,7 @@ static bool check_underflow(const struct ipt_entry *e) + const struct xt_entry_target *t; + unsigned int verdict; + +- if (!unconditional(&e->ip)) ++ if (!unconditional(e)) + return false; + t = ipt_get_target_c(e); + if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0) +@@ -741,9 +734,11 @@ check_entry_size_and_hooks(struct ipt_entry *e, + unsigned int valid_hooks) + { + unsigned int h; ++ int err; + + if ((unsigned long)e % __alignof__(struct ipt_entry) != 0 || +- (unsigned char *)e + sizeof(struct ipt_entry) >= limit) { ++ (unsigned char *)e + sizeof(struct ipt_entry) >= limit || ++ (unsigned char *)e + e->next_offset > limit) { + duprintf("Bad offset %p\n", e); + return -EINVAL; + } +@@ -755,6 +750,10 @@ check_entry_size_and_hooks(struct ipt_entry *e, + return -EINVAL; + } + ++ err = check_entry(e); ++ if (err) ++ return err; ++ + /* Check hooks & underflows */ + for (h = 0; h < NF_INET_NUMHOOKS; h++) { + if (!(valid_hooks & (1 << h))) +@@ -763,9 +762,9 @@ check_entry_size_and_hooks(struct ipt_entry *e, + newinfo->hook_entry[h] = hook_entries[h]; + if ((unsigned char *)e - base == underflows[h]) { + if (!check_underflow(e)) { +- pr_err("Underflows must be unconditional and " +- "use the STANDARD target with " +- "ACCEPT/DROP\n"); ++ pr_debug("Underflows must be unconditional and " ++ "use the STANDARD target with " ++ "ACCEPT/DROP\n"); + return -EINVAL; + } + newinfo->underflow[h] = underflows[h]; +@@ -1078,14 +1077,14 @@ static int compat_table_info(const struct xt_table_info *info, #endif static int get_info(struct net *net, void __user *user, @@ -124827,7 +126553,7 @@ index b99affa..7fc00c8 100644 sizeof(struct ipt_getinfo)); return -EINVAL; } -@@ -1122,7 +1122,7 @@ static int get_info(struct net *net, void __user *user, +@@ -1122,7 +1121,7 @@ static int get_info(struct net *net, void __user *user, info.size = private->size; strcpy(info.name, name); @@ -124836,7 +126562,42 @@ index b99affa..7fc00c8 100644 ret = -EFAULT; else ret = 0; -@@ -1973,7 +1973,7 @@ compat_do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) +@@ -1157,6 +1156,7 @@ get_entries(struct net *net, struct ipt_get_entries __user *uptr, + *len, sizeof(get) + get.size); + return -EINVAL; + } ++ get.name[sizeof(get.name) - 1] = '\0'; + + t = xt_find_table_lock(net, AF_INET, get.name); + if (!IS_ERR_OR_NULL(t)) { +@@ -1493,7 +1493,8 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e, + + duprintf("check_compat_entry_size_and_hooks %p\n", e); + if ((unsigned long)e % __alignof__(struct compat_ipt_entry) != 0 || +- (unsigned char *)e + sizeof(struct compat_ipt_entry) >= limit) { ++ (unsigned char *)e + sizeof(struct compat_ipt_entry) >= limit || ++ (unsigned char *)e + e->next_offset > limit) { + duprintf("Bad offset %p, limit = %p\n", e, limit); + return -EINVAL; + } +@@ -1506,7 +1507,7 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e, + } + + /* For purposes of check_entry casting the compat entry is fine */ +- ret = check_entry((struct ipt_entry *)e, name); ++ ret = check_entry((struct ipt_entry *)e); + if (ret) + return ret; + +@@ -1935,6 +1936,7 @@ compat_get_entries(struct net *net, struct compat_ipt_get_entries __user *uptr, + *len, sizeof(get) + get.size); + return -EINVAL; + } ++ get.name[sizeof(get.name) - 1] = '\0'; + + xt_compat_lock(AF_INET); + t = xt_find_table_lock(net, AF_INET, get.name); +@@ -1973,7 +1975,7 @@ compat_do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) switch (cmd) { case IPT_SO_GET_INFO: @@ -124845,7 +126606,7 @@ index b99affa..7fc00c8 100644 break; case IPT_SO_GET_ENTRIES: ret = compat_get_entries(sock_net(sk), user, len); -@@ -2020,7 +2020,7 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) +@@ -2020,7 +2022,7 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) switch (cmd) { case IPT_SO_GET_INFO: @@ -124867,6 +126628,31 @@ index 4a9e6db..06174e1 100644 if (!cn->procdir) { pr_err("Unable to proc dir entry\n"); return -ENOMEM; +diff --git a/net/ipv4/netfilter/nf_nat_masquerade_ipv4.c b/net/ipv4/netfilter/nf_nat_masquerade_ipv4.c +index c6eb421..ea91058 100644 +--- a/net/ipv4/netfilter/nf_nat_masquerade_ipv4.c ++++ b/net/ipv4/netfilter/nf_nat_masquerade_ipv4.c +@@ -108,10 +108,18 @@ static int masq_inet_event(struct notifier_block *this, + unsigned long event, + void *ptr) + { +- struct net_device *dev = ((struct in_ifaddr *)ptr)->ifa_dev->dev; ++ struct in_device *idev = ((struct in_ifaddr *)ptr)->ifa_dev; + struct netdev_notifier_info info; + +- netdev_notifier_info_init(&info, dev); ++ /* The masq_dev_notifier will catch the case of the device going ++ * down. So if the inetdev is dead and being destroyed we have ++ * no work to do. Otherwise this is an individual address removal ++ * and we have to perform the flush. ++ */ ++ if (idev->dead) ++ return NOTIFY_DONE; ++ ++ netdev_notifier_info_init(&info, idev->dev); + return masq_device_event(this, event, &info); + } + diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index aa67e0e..3c65672 100644 --- a/net/ipv4/ping.c @@ -125961,10 +127747,127 @@ index 84afb9a..d7dcc41 100644 if (skb && ipv6_chk_addr_and_flags(dev_net(dev), &ipv6_hdr(skb)->saddr, dev, 1, diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c -index 99425cf..262204d 100644 +index 99425cf..cc99e7c 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c -@@ -1090,14 +1090,14 @@ static int compat_table_info(const struct xt_table_info *info, +@@ -198,11 +198,12 @@ get_entry(const void *base, unsigned int offset) + + /* All zeroes == unconditional rule. */ + /* Mildly perf critical (only if packet tracing is on) */ +-static inline bool unconditional(const struct ip6t_ip6 *ipv6) ++static inline bool unconditional(const struct ip6t_entry *e) + { + static const struct ip6t_ip6 uncond; + +- return memcmp(ipv6, &uncond, sizeof(uncond)) == 0; ++ return e->target_offset == sizeof(struct ip6t_entry) && ++ memcmp(&e->ipv6, &uncond, sizeof(uncond)) == 0; + } + + static inline const struct xt_entry_target * +@@ -258,11 +259,10 @@ get_chainname_rulenum(const struct ip6t_entry *s, const struct ip6t_entry *e, + } else if (s == e) { + (*rulenum)++; + +- if (s->target_offset == sizeof(struct ip6t_entry) && ++ if (unconditional(s) && + strcmp(t->target.u.kernel.target->name, + XT_STANDARD_TARGET) == 0 && +- t->verdict < 0 && +- unconditional(&s->ipv6)) { ++ t->verdict < 0) { + /* Tail of chains: STANDARD target (return/policy) */ + *comment = *chainname == hookname + ? comments[NF_IP6_TRACE_COMMENT_POLICY] +@@ -488,11 +488,10 @@ mark_source_chains(const struct xt_table_info *newinfo, + e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS)); + + /* Unconditional return/END. */ +- if ((e->target_offset == sizeof(struct ip6t_entry) && ++ if ((unconditional(e) && + (strcmp(t->target.u.user.name, + XT_STANDARD_TARGET) == 0) && +- t->verdict < 0 && +- unconditional(&e->ipv6)) || visited) { ++ t->verdict < 0) || visited) { + unsigned int oldpos, size; + + if ((strcmp(t->target.u.user.name, +@@ -581,14 +580,12 @@ static void cleanup_match(struct xt_entry_match *m, struct net *net) + } + + static int +-check_entry(const struct ip6t_entry *e, const char *name) ++check_entry(const struct ip6t_entry *e) + { + const struct xt_entry_target *t; + +- if (!ip6_checkentry(&e->ipv6)) { +- duprintf("ip_tables: ip check failed %p %s.\n", e, name); ++ if (!ip6_checkentry(&e->ipv6)) + return -EINVAL; +- } + + if (e->target_offset + sizeof(struct xt_entry_target) > + e->next_offset) +@@ -679,10 +676,6 @@ find_check_entry(struct ip6t_entry *e, struct net *net, const char *name, + struct xt_mtchk_param mtpar; + struct xt_entry_match *ematch; + +- ret = check_entry(e, name); +- if (ret) +- return ret; +- + e->counters.pcnt = xt_percpu_counter_alloc(); + if (IS_ERR_VALUE(e->counters.pcnt)) + return -ENOMEM; +@@ -733,7 +726,7 @@ static bool check_underflow(const struct ip6t_entry *e) + const struct xt_entry_target *t; + unsigned int verdict; + +- if (!unconditional(&e->ipv6)) ++ if (!unconditional(e)) + return false; + t = ip6t_get_target_c(e); + if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0) +@@ -753,9 +746,11 @@ check_entry_size_and_hooks(struct ip6t_entry *e, + unsigned int valid_hooks) + { + unsigned int h; ++ int err; + + if ((unsigned long)e % __alignof__(struct ip6t_entry) != 0 || +- (unsigned char *)e + sizeof(struct ip6t_entry) >= limit) { ++ (unsigned char *)e + sizeof(struct ip6t_entry) >= limit || ++ (unsigned char *)e + e->next_offset > limit) { + duprintf("Bad offset %p\n", e); + return -EINVAL; + } +@@ -767,6 +762,10 @@ check_entry_size_and_hooks(struct ip6t_entry *e, + return -EINVAL; + } + ++ err = check_entry(e); ++ if (err) ++ return err; ++ + /* Check hooks & underflows */ + for (h = 0; h < NF_INET_NUMHOOKS; h++) { + if (!(valid_hooks & (1 << h))) +@@ -775,9 +774,9 @@ check_entry_size_and_hooks(struct ip6t_entry *e, + newinfo->hook_entry[h] = hook_entries[h]; + if ((unsigned char *)e - base == underflows[h]) { + if (!check_underflow(e)) { +- pr_err("Underflows must be unconditional and " +- "use the STANDARD target with " +- "ACCEPT/DROP\n"); ++ pr_debug("Underflows must be unconditional and " ++ "use the STANDARD target with " ++ "ACCEPT/DROP\n"); + return -EINVAL; + } + newinfo->underflow[h] = underflows[h]; +@@ -1090,14 +1089,14 @@ static int compat_table_info(const struct xt_table_info *info, #endif static int get_info(struct net *net, void __user *user, @@ -125982,7 +127885,7 @@ index 99425cf..262204d 100644 sizeof(struct ip6t_getinfo)); return -EINVAL; } -@@ -1134,7 +1134,7 @@ static int get_info(struct net *net, void __user *user, +@@ -1134,7 +1133,7 @@ static int get_info(struct net *net, void __user *user, info.size = private->size; strcpy(info.name, name); @@ -125991,7 +127894,42 @@ index 99425cf..262204d 100644 ret = -EFAULT; else ret = 0; -@@ -1982,7 +1982,7 @@ compat_do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) +@@ -1169,6 +1168,7 @@ get_entries(struct net *net, struct ip6t_get_entries __user *uptr, + *len, sizeof(get) + get.size); + return -EINVAL; + } ++ get.name[sizeof(get.name) - 1] = '\0'; + + t = xt_find_table_lock(net, AF_INET6, get.name); + if (!IS_ERR_OR_NULL(t)) { +@@ -1505,7 +1505,8 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e, + + duprintf("check_compat_entry_size_and_hooks %p\n", e); + if ((unsigned long)e % __alignof__(struct compat_ip6t_entry) != 0 || +- (unsigned char *)e + sizeof(struct compat_ip6t_entry) >= limit) { ++ (unsigned char *)e + sizeof(struct compat_ip6t_entry) >= limit || ++ (unsigned char *)e + e->next_offset > limit) { + duprintf("Bad offset %p, limit = %p\n", e, limit); + return -EINVAL; + } +@@ -1518,7 +1519,7 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e, + } + + /* For purposes of check_entry casting the compat entry is fine */ +- ret = check_entry((struct ip6t_entry *)e, name); ++ ret = check_entry((struct ip6t_entry *)e); + if (ret) + return ret; + +@@ -1944,6 +1945,7 @@ compat_get_entries(struct net *net, struct compat_ip6t_get_entries __user *uptr, + *len, sizeof(get) + get.size); + return -EINVAL; + } ++ get.name[sizeof(get.name) - 1] = '\0'; + + xt_compat_lock(AF_INET6); + t = xt_find_table_lock(net, AF_INET6, get.name); +@@ -1982,7 +1984,7 @@ compat_do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) switch (cmd) { case IP6T_SO_GET_INFO: @@ -126000,7 +127938,7 @@ index 99425cf..262204d 100644 break; case IP6T_SO_GET_ENTRIES: ret = compat_get_entries(sock_net(sk), user, len); -@@ -2029,7 +2029,7 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) +@@ -2029,7 +2031,7 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) switch (cmd) { case IP6T_SO_GET_INFO: @@ -128436,7 +130374,7 @@ index e6144b8..4f9fda6 100644 if (likely(*recent == gen)) return 0; diff --git a/net/rds/ib.h b/net/rds/ib.h -index b3fdebb..43e973b 100644 +index b3fdebb5..43e973b 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h @@ -156,7 +156,7 @@ struct rds_ib_connection { @@ -128857,6 +130795,86 @@ index 16bc83b..a7df216b 100644 linkwatch_fire_event(dev); } } +diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c +index a4afde1..030ed2c 100644 +--- a/net/sched/sch_tbf.c ++++ b/net/sched/sch_tbf.c +@@ -160,7 +160,8 @@ static int tbf_segment(struct sk_buff *skb, struct Qdisc *sch) + struct tbf_sched_data *q = qdisc_priv(sch); + struct sk_buff *segs, *nskb; + netdev_features_t features = netif_skb_features(skb); +- int ret, nb; ++ int ret; ++ unsigned int nb; + + segs = skb_gso_segment(skb, features & ~NETIF_F_GSO_MASK); + +@@ -182,8 +183,10 @@ static int tbf_segment(struct sk_buff *skb, struct Qdisc *sch) + segs = nskb; + } + sch->q.qlen += nb; +- if (nb > 1) +- qdisc_tree_decrease_qlen(sch, 1 - nb); ++ if (nb > 1) { ++ nb--; ++ qdisc_tree_decrease_qlen(sch, -nb); ++ } + consume_skb(skb); + return nb > 0 ? NET_XMIT_SUCCESS : NET_XMIT_DROP; + } +diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c +index 871cdf9..401c607 100644 +--- a/net/sctp/bind_addr.c ++++ b/net/sctp/bind_addr.c +@@ -111,7 +111,8 @@ int sctp_bind_addr_dup(struct sctp_bind_addr *dest, + dest->port = src->port; + + list_for_each_entry(addr, &src->address_list, list) { +- error = sctp_add_bind_addr(dest, &addr->a, 1, gfp); ++ error = sctp_add_bind_addr(dest, &addr->a, sizeof(addr->a), ++ 1, gfp); + if (error < 0) + break; + } +@@ -150,7 +151,7 @@ void sctp_bind_addr_free(struct sctp_bind_addr *bp) + + /* Add an address to the bind address list in the SCTP_bind_addr structure. */ + int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new, +- __u8 addr_state, gfp_t gfp) ++ int new_size, __u8 addr_state, gfp_t gfp) + { + struct sctp_sockaddr_entry *addr; + +@@ -159,7 +160,7 @@ int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new, + if (!addr) + return -ENOMEM; + +- memcpy(&addr->a, new, sizeof(*new)); ++ memcpy(&addr->a, new, min_t(size_t, sizeof(*new), new_size)); + + /* Fix up the port if it has not yet been set. + * Both v4 and v6 have the port at the same offset. +@@ -291,7 +292,8 @@ int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw_addr_list, + } + + af->from_addr_param(&addr, rawaddr, htons(port), 0); +- retval = sctp_add_bind_addr(bp, &addr, SCTP_ADDR_SRC, gfp); ++ retval = sctp_add_bind_addr(bp, &addr, sizeof(addr), ++ SCTP_ADDR_SRC, gfp); + if (retval) { + /* Can't finish building the list, clean up. */ + sctp_bind_addr_clean(bp); +@@ -453,8 +455,8 @@ static int sctp_copy_one_addr(struct net *net, struct sctp_bind_addr *dest, + (((AF_INET6 == addr->sa.sa_family) && + (flags & SCTP_ADDR6_ALLOWED) && + (flags & SCTP_ADDR6_PEERSUPP)))) +- error = sctp_add_bind_addr(dest, addr, SCTP_ADDR_SRC, +- gfp); ++ error = sctp_add_bind_addr(dest, addr, sizeof(*addr), ++ SCTP_ADDR_SRC, gfp); + } + + return error; diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index ec52912..059504b 100644 --- a/net/sctp/ipv6.c @@ -128889,10 +130907,18 @@ index ec52912..059504b 100644 /* Initialize IPv6 support and register with socket layer. */ diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c -index 8b4ff31..92b21ee 100644 +index 8b4ff31..9e73fb3 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c -@@ -858,8 +858,10 @@ int sctp_register_af(struct sctp_af *af) +@@ -216,6 +216,7 @@ int sctp_copy_local_addr_list(struct net *net, struct sctp_bind_addr *bp, + (copy_flags & SCTP_ADDR6_ALLOWED) && + (copy_flags & SCTP_ADDR6_PEERSUPP)))) { + error = sctp_add_bind_addr(bp, &addr->a, ++ sizeof(addr->a), + SCTP_ADDR_SRC, GFP_ATOMIC); + if (error) + goto end_copy; +@@ -858,8 +859,10 @@ int sctp_register_af(struct sctp_af *af) return 0; } @@ -128904,7 +130930,7 @@ index 8b4ff31..92b21ee 100644 return 1; } -@@ -989,7 +991,7 @@ static inline int sctp_v4_xmit(struct sk_buff *skb, +@@ -989,7 +992,7 @@ static inline int sctp_v4_xmit(struct sk_buff *skb, static struct sctp_af sctp_af_inet; @@ -128913,7 +130939,7 @@ index 8b4ff31..92b21ee 100644 .event_msgname = sctp_inet_event_msgname, .skb_msgname = sctp_inet_skb_msgname, .af_supported = sctp_inet_af_supported, -@@ -1061,7 +1063,7 @@ static const struct net_protocol sctp_protocol = { +@@ -1061,7 +1064,7 @@ static const struct net_protocol sctp_protocol = { }; /* IPv4 address related functions. */ @@ -128922,7 +130948,7 @@ index 8b4ff31..92b21ee 100644 .sa_family = AF_INET, .sctp_xmit = sctp_v4_xmit, .setsockopt = ip_setsockopt, -@@ -1145,7 +1147,7 @@ static void sctp_v4_pf_init(void) +@@ -1145,7 +1148,7 @@ static void sctp_v4_pf_init(void) static void sctp_v4_pf_exit(void) { @@ -128931,6 +130957,20 @@ index 8b4ff31..92b21ee 100644 } static int sctp_v4_protosw_init(void) +diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c +index 5d6a03f..7fe971e 100644 +--- a/net/sctp/sm_make_chunk.c ++++ b/net/sctp/sm_make_chunk.c +@@ -1830,7 +1830,8 @@ no_hmac: + /* Also, add the destination address. */ + if (list_empty(&retval->base.bind_addr.address_list)) { + sctp_add_bind_addr(&retval->base.bind_addr, &chunk->dest, +- SCTP_ADDR_SRC, GFP_ATOMIC); ++ sizeof(chunk->dest), SCTP_ADDR_SRC, ++ GFP_ATOMIC); + } + + retval->next_tsn = retval->c.initial_tsn; diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 6098d4c..9920c54 100644 --- a/net/sctp/sm_sideeffect.c @@ -129076,10 +131116,28 @@ index 22c2bf3..f1f08c8 100644 /* diff --git a/net/sctp/socket.c b/net/sctp/socket.c -index be1489f..5364cd7 100644 +index be1489f..9d8cbd9 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c -@@ -2192,11 +2192,13 @@ static int sctp_setsockopt_events(struct sock *sk, char __user *optval, +@@ -386,7 +386,8 @@ static int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len) + /* Add the address to the bind address list. + * Use GFP_ATOMIC since BHs will be disabled. + */ +- ret = sctp_add_bind_addr(bp, addr, SCTP_ADDR_SRC, GFP_ATOMIC); ++ ret = sctp_add_bind_addr(bp, addr, af->sockaddr_len, ++ SCTP_ADDR_SRC, GFP_ATOMIC); + + /* Copy back into socket for getsockname() use. */ + if (!ret) { +@@ -577,6 +578,7 @@ static int sctp_send_asconf_add_ip(struct sock *sk, + af = sctp_get_af_specific(addr->v4.sin_family); + memcpy(&saveaddr, addr, af->sockaddr_len); + retval = sctp_add_bind_addr(bp, &saveaddr, ++ sizeof(saveaddr), + SCTP_ADDR_NEW, GFP_ATOMIC); + addr_buf += af->sockaddr_len; + } +@@ -2192,11 +2194,13 @@ static int sctp_setsockopt_events(struct sock *sk, char __user *optval, { struct sctp_association *asoc; struct sctp_ulpevent *event; @@ -129094,7 +131152,7 @@ index be1489f..5364cd7 100644 /* At the time when a user app subscribes to SCTP_SENDER_DRY_EVENT, * if there is no data to be sent or retransmit, the stack will -@@ -4371,13 +4373,16 @@ static int sctp_getsockopt_disable_fragments(struct sock *sk, int len, +@@ -4371,13 +4375,16 @@ static int sctp_getsockopt_disable_fragments(struct sock *sk, int len, static int sctp_getsockopt_events(struct sock *sk, int len, char __user *optval, int __user *optlen) { @@ -129112,7 +131170,7 @@ index be1489f..5364cd7 100644 return -EFAULT; return 0; } -@@ -4395,6 +4400,8 @@ static int sctp_getsockopt_events(struct sock *sk, int len, char __user *optval, +@@ -4395,6 +4402,8 @@ static int sctp_getsockopt_events(struct sock *sk, int len, char __user *optval, */ static int sctp_getsockopt_autoclose(struct sock *sk, int len, char __user *optval, int __user *optlen) { @@ -129121,7 +131179,7 @@ index be1489f..5364cd7 100644 /* Applicable to UDP-style socket only */ if (sctp_style(sk, TCP)) return -EOPNOTSUPP; -@@ -4403,7 +4410,8 @@ static int sctp_getsockopt_autoclose(struct sock *sk, int len, char __user *optv +@@ -4403,7 +4412,8 @@ static int sctp_getsockopt_autoclose(struct sock *sk, int len, char __user *optv len = sizeof(int); if (put_user(len, optlen)) return -EFAULT; @@ -129131,7 +131189,7 @@ index be1489f..5364cd7 100644 return -EFAULT; return 0; } -@@ -4777,12 +4785,15 @@ static int sctp_getsockopt_delayed_ack(struct sock *sk, int len, +@@ -4777,12 +4787,15 @@ static int sctp_getsockopt_delayed_ack(struct sock *sk, int len, */ static int sctp_getsockopt_initmsg(struct sock *sk, int len, char __user *optval, int __user *optlen) { @@ -129148,7 +131206,7 @@ index be1489f..5364cd7 100644 return -EFAULT; return 0; } -@@ -4823,6 +4834,8 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len, +@@ -4823,6 +4836,8 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len, ->addr_to_user(sp, &temp); if (space_left < addrlen) return -ENOMEM; @@ -130458,16 +132516,13 @@ index 4efedcb..0220ab2 100644 warning-2 += -Wdisabled-optimization diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins new file mode 100644 -index 0000000..f1bb96d +index 0000000..2972943 --- /dev/null +++ b/scripts/Makefile.gcc-plugins -@@ -0,0 +1,79 @@ +@@ -0,0 +1,72 @@ +ifndef DISABLE_PAX_PLUGINS -+ifeq ($(call cc-ifversion, -ge, 0408, y), y) -+PLUGINCC := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-plugin.sh "$(HOSTCXX)" "$(HOSTCXX)" "$(CC)") -+else -+PLUGINCC := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-plugin.sh "$(HOSTCC)" "$(HOSTCXX)" "$(CC)") -+endif ++__PLUGINCC := $(call cc-ifversion, -ge, 0408, $(HOSTCXX), $(HOSTCC)) ++PLUGINCC := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-plugin.sh "$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)") +ifneq ($(PLUGINCC),) +ifdef CONFIG_PAX_CONSTIFY_PLUGIN +CONSTIFY_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/constify_plugin.so -DCONSTIFY_PLUGIN @@ -130528,12 +132583,8 @@ index 0000000..f1bb96d +else +gcc-plugins: +ifeq ($(call cc-ifversion, -ge, 0405, y), y) -+ifeq ($(call cc-ifversion, -ge, 0408, y), y) -+ $(CONFIG_SHELL) -x $(srctree)/scripts/gcc-plugin.sh "$(HOSTCXX)" "$(HOSTCXX)" "$(CC)" -+else -+ $(CONFIG_SHELL) -x $(srctree)/scripts/gcc-plugin.sh "$(HOSTCC)" "$(HOSTCXX)" "$(CC)" -+endif + $(error Your gcc installation does not support plugins. If the necessary headers for plugin support are missing, they should be installed. On Debian, apt-get install gcc-<ver>-plugin-dev. If you choose to ignore this error and lessen the improvements provided by this patch, re-run make with the DISABLE_PAX_PLUGINS=y argument.) ++ $(CONFIG_SHELL) -x $(srctree)/scripts/gcc-plugin.sh "$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)" +else + $(warning Warning, your gcc version does not support plugins, you should upgrade it to gcc 4.5 at least.) +endif @@ -130542,7 +132593,7 @@ index 0000000..f1bb96d +endif + diff --git a/scripts/Makefile.host b/scripts/Makefile.host -index 133edfa..4d180d9 100644 +index 133edfa..3cc6af2 100644 --- a/scripts/Makefile.host +++ b/scripts/Makefile.host @@ -20,7 +20,25 @@ @@ -130571,14 +132622,13 @@ index 133edfa..4d180d9 100644 # C code # Executables compiled from a single .c file -@@ -42,6 +60,19 @@ host-cxxmulti := $(foreach m,$(__hostprogs),$(if $($(m)-cxxobjs),$(m))) +@@ -42,6 +60,18 @@ host-cxxmulti := $(foreach m,$(__hostprogs),$(if $($(m)-cxxobjs),$(m))) # C++ Object (.o) files compiled from .cc files host-cxxobjs := $(sort $(foreach m,$(host-cxxmulti),$($(m)-cxxobjs))) +# Shared libaries (only .c supported) +# Shared libraries (.so) - all .so files referenced in "xxx-objs" -+host-cshlib := $(sort $(filter %.so, $(host-cobjs))) -+host-cshlib += $(sort $(filter %.so, $(__hostlibs))) ++host-cshlib := $(sort $(filter %.so, $(__hostlibs))) +host-cxxshlib := $(sort $(filter %.so, $(__hostcxxlibs))) +# Remove .so files from "xxx-objs" +host-cobjs := $(filter-out %.so,$(host-cobjs)) @@ -130591,7 +132641,7 @@ index 133edfa..4d180d9 100644 # output directory for programs/.o files # hostprogs-y := tools/build may have been specified. # Retrieve also directory of .o files from prog-objs or prog-cxxobjs notation -@@ -56,6 +87,10 @@ host-cmulti := $(addprefix $(obj)/,$(host-cmulti)) +@@ -56,6 +86,10 @@ host-cmulti := $(addprefix $(obj)/,$(host-cmulti)) host-cobjs := $(addprefix $(obj)/,$(host-cobjs)) host-cxxmulti := $(addprefix $(obj)/,$(host-cxxmulti)) host-cxxobjs := $(addprefix $(obj)/,$(host-cxxobjs)) @@ -130602,7 +132652,7 @@ index 133edfa..4d180d9 100644 host-objdirs := $(addprefix $(obj)/,$(host-objdirs)) obj-dirs += $(host-objdirs) -@@ -124,5 +159,37 @@ quiet_cmd_host-cxxobjs = HOSTCXX $@ +@@ -124,5 +158,37 @@ quiet_cmd_host-cxxobjs = HOSTCXX $@ $(host-cxxobjs): $(obj)/%.o: $(src)/%.cc FORCE $(call if_changed_dep,host-cxxobjs) @@ -133219,6 +135269,21 @@ index 175f9e4..3518d31 100644 } #endif /* modular kernel */ +diff --git a/sound/core/timer.c b/sound/core/timer.c +index f24c9fc..b982d1b 100644 +--- a/sound/core/timer.c ++++ b/sound/core/timer.c +@@ -1051,8 +1051,8 @@ static int snd_timer_s_start(struct snd_timer * timer) + njiff += timer->sticks - priv->correction; + priv->correction = 0; + } +- priv->last_expires = priv->tlist.expires = njiff; +- add_timer(&priv->tlist); ++ priv->last_expires = njiff; ++ mod_timer(&priv->tlist, njiff); + return 0; + } + diff --git a/sound/drivers/mts64.c b/sound/drivers/mts64.c index 2a008a9..a1efb3f 100644 --- a/sound/drivers/mts64.c @@ -139252,10 +141317,10 @@ index 0000000..f74d85a +targets += size_overflow_hash.h size_overflow_hash_aux.h disable_size_overflow_hash.h diff --git a/tools/gcc/size_overflow_plugin/disable_size_overflow_hash.data b/tools/gcc/size_overflow_plugin/disable_size_overflow_hash.data new file mode 100644 -index 0000000..f4a8606 +index 0000000..9957f8c --- /dev/null +++ b/tools/gcc/size_overflow_plugin/disable_size_overflow_hash.data -@@ -0,0 +1,12437 @@ +@@ -0,0 +1,12440 @@ +disable_so_interrupt_pnode_gru_message_queue_desc_4 interrupt_pnode gru_message_queue_desc 0 4 NULL +disable_so_bch_btree_insert_fndecl_12 bch_btree_insert fndecl 0 12 NULL +disable_so_macvlan_sync_address_fndecl_22 macvlan_sync_address fndecl 0 22 NULL nohasharray @@ -148708,7 +150773,8 @@ index 0000000..f4a8606 +disable_so_mtrr_type_lookup_fndecl_49929 mtrr_type_lookup fndecl 1-2 49929 NULL +disable_so_persistent_offset_sst_module_runtime_49933 persistent_offset sst_module_runtime 0 49933 NULL +disable_so_lvb_ictime_packed_ocfs2_meta_lvb_49940 lvb_ictime_packed ocfs2_meta_lvb 0 49940 NULL -+disable_so_boost_freq_lm3533_platform_data_49943 boost_freq lm3533_platform_data 0 49943 NULL ++enable_so_inode_number_squashfs_dir_entry_49943 inode_number squashfs_dir_entry 0 49943 NULL nohasharray ++disable_so_boost_freq_lm3533_platform_data_49943 boost_freq lm3533_platform_data 0 49943 &enable_so_inode_number_squashfs_dir_entry_49943 +disable_so_inet_twsk_schedule_fndecl_49946 inet_twsk_schedule fndecl 2 49946 NULL +disable_so_host_time_adj_time_work_49952 host_time adj_time_work 0 49952 NULL +disable_so_b43_dma_address_fndecl_49953 b43_dma_address fndecl 0-2 49953 NULL @@ -151693,6 +153759,8 @@ index 0000000..f4a8606 +enable_so_dsack_tcp_options_received_27706 dsack tcp_options_received 0 27706 NULL +enable_so_inbufBits_bunzip_data_13788 inbufBits bunzip_data 0 13788 NULL +enable_so_i_ino_inode_8428 i_ino inode 0 8428 NULL ++enable_so_squashfs_iget_fndecl_37485 squashfs_iget fndecl 3 37485 NULL ++enable_so_new_offset_mdp_superblock_1_6501 new_offset mdp_superblock_1 0 6501 NULL diff --git a/tools/gcc/size_overflow_plugin/generate_size_overflow_hash.sh b/tools/gcc/size_overflow_plugin/generate_size_overflow_hash.sh new file mode 100644 index 0000000..be9724d @@ -153981,10 +156049,10 @@ index 0000000..fc58e16 +} diff --git a/tools/gcc/size_overflow_plugin/size_overflow_hash.data b/tools/gcc/size_overflow_plugin/size_overflow_hash.data new file mode 100644 -index 0000000..3702ccea +index 0000000..ca51973 --- /dev/null +++ b/tools/gcc/size_overflow_plugin/size_overflow_hash.data -@@ -0,0 +1,21512 @@ +@@ -0,0 +1,21509 @@ +enable_so_recv_ctrl_pipe_us_data_0 recv_ctrl_pipe us_data 0 0 NULL +enable_so___earlyonly_bootmem_alloc_fndecl_3 __earlyonly_bootmem_alloc fndecl 2-3-4 3 NULL +enable_so_v9fs_xattr_get_acl_fndecl_4 v9fs_xattr_get_acl fndecl 5 4 NULL @@ -156071,7 +158139,6 @@ index 0000000..3702ccea +enable_so_beep_amp_ad198x_spec_6490 beep_amp ad198x_spec 0 6490 &enable_so_datasize_vub300_mmc_host_6490 nohasharray +enable_so_probe_kernel_write_fndecl_6490 probe_kernel_write fndecl 3 6490 &enable_so_beep_amp_ad198x_spec_6490 +enable_so_curr_dma_words_tegra_spi_data_6500 curr_dma_words tegra_spi_data 0 6500 NULL -+enable_so_new_offset_mdp_superblock_1_6501 new_offset mdp_superblock_1 0 6501 NULL +enable_so_f_read_cntrs_qib_devdata_6502 f_read_cntrs qib_devdata 0 6502 NULL +enable_so_inc_remap_and_issue_cell_fndecl_6505 inc_remap_and_issue_cell fndecl 3 6505 NULL +enable_so_hugetlb_file_setup_fndecl_6506 hugetlb_file_setup fndecl 2 6506 NULL @@ -166352,8 +168419,7 @@ index 0000000..3702ccea +enable_so_length_drm_event_37471 length drm_event 0 37471 NULL +enable_so_s_apbshift_ufs_sb_private_info_37473 s_apbshift ufs_sb_private_info 0 37473 NULL +enable_so_TupleLink_tuple_t_37482 TupleLink tuple_t 0 37482 NULL -+enable_so_squashfs_iget_fndecl_37485 squashfs_iget fndecl 3 37485 NULL nohasharray -+enable_so_ath10k_mac_create_fndecl_37485 ath10k_mac_create fndecl 1 37485 &enable_so_squashfs_iget_fndecl_37485 ++enable_so_ath10k_mac_create_fndecl_37485 ath10k_mac_create fndecl 1 37485 NULL +enable_so_qib_resize_cq_fndecl_37489 qib_resize_cq fndecl 2 37489 NULL +enable_so_params_len_nfc_evt_transaction_37500 params_len nfc_evt_transaction 0 37500 NULL +enable_so_lines_ivtv_osd_coords_37504 lines ivtv_osd_coords 0 37504 NULL nohasharray @@ -170423,8 +172489,7 @@ index 0000000..3702ccea +enable_so_SyS_select_fndecl_49930 SyS_select fndecl 1 49930 NULL +enable_so_skd_max_queue_depth_vardecl_skd_main_c_49938 skd_max_queue_depth vardecl_skd_main.c 0 49938 NULL +enable_so_cx18_prepare_buffer_fndecl_49942 cx18_prepare_buffer fndecl 6-5 49942 NULL -+enable_so_inode_number_squashfs_dir_entry_49943 inode_number squashfs_dir_entry 0 49943 NULL nohasharray -+enable_so_repair_io_failure_fndecl_49943 repair_io_failure fndecl 6-3 49943 &enable_so_inode_number_squashfs_dir_entry_49943 ++enable_so_repair_io_failure_fndecl_49943 repair_io_failure fndecl 6-3 49943 NULL +enable_so_internal_ewma_pkt_len_49944 internal ewma_pkt_len 0 49944 NULL nohasharray +enable_so_mmc_switch_fndecl_49944 mmc_switch fndecl 0 49944 &enable_so_internal_ewma_pkt_len_49944 +enable_so_tomoyo_update_policy_fndecl_49945 tomoyo_update_policy fndecl 2 49945 NULL @@ -180347,7 +182412,7 @@ index 0a578fe..b81f62d 100644 }) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c -index 7338e30..5adab9c 100644 +index 7338e30..7b0dc7f 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -90,12 +90,17 @@ LIST_HEAD(vm_list); @@ -180370,7 +182435,49 @@ index 7338e30..5adab9c 100644 struct dentry *kvm_debugfs_dir; EXPORT_SYMBOL_GPL(kvm_debugfs_dir); -@@ -842,7 +847,7 @@ int __kvm_set_memory_region(struct kvm *kvm, +@@ -547,6 +552,16 @@ static struct kvm *kvm_create_vm(unsigned long type) + if (!kvm) + return ERR_PTR(-ENOMEM); + ++ spin_lock_init(&kvm->mmu_lock); ++ atomic_inc(¤t->mm->mm_count); ++ kvm->mm = current->mm; ++ kvm_eventfd_init(kvm); ++ mutex_init(&kvm->lock); ++ mutex_init(&kvm->irq_lock); ++ mutex_init(&kvm->slots_lock); ++ atomic_set(&kvm->users_count, 1); ++ INIT_LIST_HEAD(&kvm->devices); ++ + r = kvm_arch_init_vm(kvm, type); + if (r) + goto out_err_no_disable; +@@ -579,16 +594,6 @@ static struct kvm *kvm_create_vm(unsigned long type) + goto out_err; + } + +- spin_lock_init(&kvm->mmu_lock); +- kvm->mm = current->mm; +- atomic_inc(&kvm->mm->mm_count); +- kvm_eventfd_init(kvm); +- mutex_init(&kvm->lock); +- mutex_init(&kvm->irq_lock); +- mutex_init(&kvm->slots_lock); +- atomic_set(&kvm->users_count, 1); +- INIT_LIST_HEAD(&kvm->devices); +- + r = kvm_init_mmu_notifier(kvm); + if (r) + goto out_err; +@@ -613,6 +618,7 @@ out_err_no_disable: + for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) + kvm_free_memslots(kvm, kvm->memslots[i]); + kvm_arch_free_vm(kvm); ++ mmdrop(current->mm); + return ERR_PTR(r); + } + +@@ -842,7 +848,7 @@ int __kvm_set_memory_region(struct kvm *kvm, /* We can read the guest memory with __xxx_user() later on. */ if ((id < KVM_USER_MEM_SLOTS) && ((mem->userspace_addr & (PAGE_SIZE - 1)) || @@ -180379,7 +182486,7 @@ index 7338e30..5adab9c 100644 (void __user *)(unsigned long)mem->userspace_addr, mem->memory_size))) goto out; -@@ -1897,9 +1902,17 @@ EXPORT_SYMBOL_GPL(kvm_read_guest_cached); +@@ -1897,9 +1903,17 @@ EXPORT_SYMBOL_GPL(kvm_read_guest_cached); int kvm_clear_guest_page(struct kvm *kvm, gfn_t gfn, int offset, int len) { @@ -180399,7 +182506,7 @@ index 7338e30..5adab9c 100644 } EXPORT_SYMBOL_GPL(kvm_clear_guest_page); -@@ -2236,7 +2249,7 @@ static int kvm_vcpu_release(struct inode *inode, struct file *filp) +@@ -2236,7 +2250,7 @@ static int kvm_vcpu_release(struct inode *inode, struct file *filp) return 0; } @@ -180408,7 +182515,7 @@ index 7338e30..5adab9c 100644 .release = kvm_vcpu_release, .unlocked_ioctl = kvm_vcpu_ioctl, #ifdef CONFIG_KVM_COMPAT -@@ -2952,7 +2965,7 @@ out: +@@ -2952,7 +2966,7 @@ out: } #endif @@ -180417,7 +182524,7 @@ index 7338e30..5adab9c 100644 .release = kvm_vm_release, .unlocked_ioctl = kvm_vm_ioctl, #ifdef CONFIG_KVM_COMPAT -@@ -3023,7 +3036,7 @@ out: +@@ -3023,7 +3037,7 @@ out: return r; } @@ -180426,7 +182533,7 @@ index 7338e30..5adab9c 100644 .unlocked_ioctl = kvm_dev_ioctl, .compat_ioctl = kvm_dev_ioctl, .llseek = noop_llseek, -@@ -3049,7 +3062,7 @@ static void hardware_enable_nolock(void *junk) +@@ -3049,7 +3063,7 @@ static void hardware_enable_nolock(void *junk) if (r) { cpumask_clear_cpu(cpu, cpus_hardware_enabled); @@ -180435,7 +182542,7 @@ index 7338e30..5adab9c 100644 pr_info("kvm: enabling virtualization on CPU%d failed\n", cpu); } } -@@ -3104,10 +3117,10 @@ static int hardware_enable_all(void) +@@ -3104,10 +3118,10 @@ static int hardware_enable_all(void) kvm_usage_count++; if (kvm_usage_count == 1) { @@ -180448,7 +182555,7 @@ index 7338e30..5adab9c 100644 hardware_disable_all_nolock(); r = -EBUSY; } -@@ -3571,7 +3584,7 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, +@@ -3571,7 +3585,7 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, if (!vcpu_align) vcpu_align = __alignof__(struct kvm_vcpu); kvm_vcpu_cache = kmem_cache_create("kvm_vcpu", vcpu_size, vcpu_align, @@ -180457,7 +182564,7 @@ index 7338e30..5adab9c 100644 if (!kvm_vcpu_cache) { r = -ENOMEM; goto out_free_3; -@@ -3581,9 +3594,11 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, +@@ -3581,9 +3595,11 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, if (r) goto out_free; @@ -180469,7 +182576,7 @@ index 7338e30..5adab9c 100644 r = misc_register(&kvm_dev); if (r) { -@@ -3593,9 +3608,6 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, +@@ -3593,9 +3609,6 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, register_syscore_ops(&kvm_syscore_ops); |