summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony G. Basile <blueness@gentoo.org>2016-04-03 05:35:02 -0400
committerAnthony G. Basile <blueness@gentoo.org>2016-04-03 05:35:02 -0400
commitcdf70bd2fcd9e90bb82e2d1ecc7701d8efba0808 (patch)
treef3026138d22bc936a2e74d8988391b6dcc9e3460
parentgrsecurity-3.1-4.4.6-201603221748 (diff)
downloadhardened-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_README2
-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(&current->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);