aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2014-09-15 06:28:58 +0000
committerNatanael Copa <ncopa@alpinelinux.org>2014-09-15 06:29:32 +0000
commit678bd9ae1a333b5d9e0d38344a3a13aefb689d3e (patch)
tree828eaa57b3a20f8235d7e003041798ace94ee9f8
parent49634869f2741fc89b0a35617536a48e84b42b5f (diff)
downloadaports-678bd9ae1a333b5d9e0d38344a3a13aefb689d3e.tar.bz2
aports-678bd9ae1a333b5d9e0d38344a3a13aefb689d3e.tar.xz
main/linux-grsec: upgrade to grsecurity-3.0-3.14.18-201409141906
-rw-r--r--main/linux-grsec/APKBUILD10
-rw-r--r--main/linux-grsec/grsecurity-3.0-3.14.18-201409141906.patch (renamed from main/linux-grsec/grsecurity-3.0-3.14.18-201409082127.patch)1160
2 files changed, 1102 insertions, 68 deletions
diff --git a/main/linux-grsec/APKBUILD b/main/linux-grsec/APKBUILD
index 11c21822b6..f929298742 100644
--- a/main/linux-grsec/APKBUILD
+++ b/main/linux-grsec/APKBUILD
@@ -7,7 +7,7 @@ case $pkgver in
*.*.*) _kernver=${pkgver%.*};;
*.*) _kernver=${pkgver};;
esac
-pkgrel=0
+pkgrel=1
pkgdesc="Linux kernel with grsecurity"
url=http://grsecurity.net
depends="mkinitfs linux-firmware"
@@ -17,7 +17,7 @@ _config=${config:-kernelconfig.${CARCH}}
install=
source="http://ftp.kernel.org/pub/linux/kernel/v3.x/linux-$_kernver.tar.xz
http://ftp.kernel.org/pub/linux/kernel/v3.x/patch-$pkgver.xz
- grsecurity-3.0-3.14.18-201409082127.patch
+ grsecurity-3.0-3.14.18-201409141906.patch
fix-memory-map-for-PIE-applications.patch
imx6q-no-unclocked-sleep.patch
@@ -166,7 +166,7 @@ dev() {
md5sums="b621207b3f6ecbb67db18b13258f8ea8 linux-3.14.tar.xz
f00741b35127573c3cf085fc43f6e3f0 patch-3.14.18.xz
-43a6f021cff545fa3e3c0386e473ff23 grsecurity-3.0-3.14.18-201409082127.patch
+eb7a53b063df0e0018014049a08f5b40 grsecurity-3.0-3.14.18-201409141906.patch
c6a4ae7e8ca6159e1631545515805216 fix-memory-map-for-PIE-applications.patch
1a307fc1d63231bf01d22493a4f14378 imx6q-no-unclocked-sleep.patch
5395777f2ffcaeedb482afce441a0e2f kernelconfig.x86
@@ -174,7 +174,7 @@ c6a4ae7e8ca6159e1631545515805216 fix-memory-map-for-PIE-applications.patch
0d71b1663f7cbfffc6e403deca4bbe86 kernelconfig.armhf"
sha256sums="61558aa490855f42b6340d1a1596be47454909629327c49a5e4e10268065dffa linux-3.14.tar.xz
3723d8d91e1bba0ed57a4951e8089ebfaa21ac186c3b729b4d2bad2da3eaed9f patch-3.14.18.xz
-ac5c311624480651775d6c482a3314edd8f1e1e5730e98f2aa6f648e47e20422 grsecurity-3.0-3.14.18-201409082127.patch
+a9f82ac307226ea1726e7c7e904627e69ee8016985b73fd4cb8dec4f5768b222 grsecurity-3.0-3.14.18-201409141906.patch
500f3577310be52e87b9fecdc2e9c4ca43210fd97d69089f9005d484563f74c7 fix-memory-map-for-PIE-applications.patch
21179fbb22a5b74af0a609350ae1a170e232908572b201d02e791d2ce0a685d3 imx6q-no-unclocked-sleep.patch
c1f2bcf8711c2295895f682a8e32a0719f389557deb0f1fa1ce9e751dd04f8ae kernelconfig.x86
@@ -182,7 +182,7 @@ c1f2bcf8711c2295895f682a8e32a0719f389557deb0f1fa1ce9e751dd04f8ae kernelconfig.x
3cddaac02211dd0f5eb4531aecc3a1427f29dcec7b31d9fe0042192d591bcdc8 kernelconfig.armhf"
sha512sums="5730d83a7a81134c1e77c0bf89e42dee4f8251ad56c1ac2be20c59e26fdfaa7bea55f277e7af156b637f22e1584914a46089af85039177cb43485089c74ac26e linux-3.14.tar.xz
c7c5b281986819cb69592cc4c2b7c7d79f34aa86f21db1dd64b795dda79b5f9df95626dada5c8e0613c58d8d7979f37baf0a87cd458f340018ce61b42e4eb6c5 patch-3.14.18.xz
-2a12ca6dd993fa874da02bdc6913a78a29b21b6621bd243157f5ae65240d4bf934e438f35620935508b7e251445551b1b0c962aec9e26b2d34bca1c8281fdbc2 grsecurity-3.0-3.14.18-201409082127.patch
+ff711fc291a3a795a1421936f0e3168ef8a6b92bcad21f9b7a1468945ee33cf9dcb3e56a5424be99af4cc660bd00e1770812ee2beb0fad9b34dd610558bd9cd9 grsecurity-3.0-3.14.18-201409141906.patch
4665c56ae1bbac311f9205d64918e84ee8b01d47d6e2396ff6b8adfb10aada7f7254531ce62e31edbb65c2a54a830f09ad05d314dfcd75d6272f4068945ad7c7 fix-memory-map-for-PIE-applications.patch
87d1ad59732f265a5b0db54490dc1762c14ea4b868e7eb1aedc3ce57b48046de7bbc08cf5cfcf6f1380fa84063b0edb16ba3d5e3c5670be9bbb229275c88b221 imx6q-no-unclocked-sleep.patch
bba0241bf9d51154959cb06d8ecf328b0475bf1c656baff1c0066285c71f6b0115534c8c4fc238b63b617b5c7a75d0a13371d80a7fe99194eaa4238cd4712357 kernelconfig.x86
diff --git a/main/linux-grsec/grsecurity-3.0-3.14.18-201409082127.patch b/main/linux-grsec/grsecurity-3.0-3.14.18-201409141906.patch
index 2a009861ca..54a332ad20 100644
--- a/main/linux-grsec/grsecurity-3.0-3.14.18-201409082127.patch
+++ b/main/linux-grsec/grsecurity-3.0-3.14.18-201409141906.patch
@@ -876,7 +876,7 @@ index 4733d32..b142a40 100644
kexec is a system call that implements the ability to shutdown your
current kernel, and to start another kernel. It is like a reboot
diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h
-index 62d2cb5..09d45e3 100644
+index 62d2cb5..0d7f7f5 100644
--- a/arch/arm/include/asm/atomic.h
+++ b/arch/arm/include/asm/atomic.h
@@ -18,17 +18,35 @@
@@ -1379,7 +1379,7 @@ index 62d2cb5..09d45e3 100644
" sbc %R0, %R0, %R4\n"
" strexd %1, %0, %H0, [%3]\n"
" teq %1, #0\n"
-@@ -344,16 +691,29 @@ static inline long long atomic64_sub_return(long long i, atomic64_t *v)
+@@ -344,10 +691,25 @@ static inline long long atomic64_sub_return(long long i, atomic64_t *v)
__asm__ __volatile__("@ atomic64_sub_return\n"
"1: ldrexd %0, %H0, [%3]\n"
" subs %Q0, %Q0, %Q4\n"
@@ -1406,13 +1406,7 @@ index 62d2cb5..09d45e3 100644
: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
: "r" (&v->counter), "r" (i)
: "cc");
-
-- smp_mb();
--
- return result;
- }
-
-@@ -382,6 +742,31 @@ static inline long long atomic64_cmpxchg(atomic64_t *ptr, long long old,
+@@ -382,6 +744,31 @@ static inline long long atomic64_cmpxchg(atomic64_t *ptr, long long old,
return oldval;
}
@@ -1444,7 +1438,7 @@ index 62d2cb5..09d45e3 100644
static inline long long atomic64_xchg(atomic64_t *ptr, long long new)
{
long long result;
-@@ -406,20 +791,34 @@ static inline long long atomic64_xchg(atomic64_t *ptr, long long new)
+@@ -406,20 +793,34 @@ static inline long long atomic64_xchg(atomic64_t *ptr, long long new)
static inline long long atomic64_dec_if_positive(atomic64_t *v)
{
long long result;
@@ -1485,7 +1479,7 @@ index 62d2cb5..09d45e3 100644
: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
: "r" (&v->counter)
: "cc");
-@@ -442,13 +841,25 @@ static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u)
+@@ -442,13 +843,25 @@ static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u)
" teq %0, %5\n"
" teqeq %H0, %H5\n"
" moveq %1, #0\n"
@@ -1514,7 +1508,7 @@ index 62d2cb5..09d45e3 100644
: "=&r" (val), "+r" (ret), "=&r" (tmp), "+Qo" (v->counter)
: "r" (&v->counter), "r" (u), "r" (a)
: "cc");
-@@ -461,10 +872,13 @@ static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u)
+@@ -461,10 +874,13 @@ static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u)
#define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0)
#define atomic64_inc(v) atomic64_add(1LL, (v))
@@ -3271,7 +3265,7 @@ index 7bcee5c..e2f3249 100644
__data_loc = .;
#endif
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
-index bd18bb8..87ede26 100644
+index bd18bb8..2bf342f 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -57,7 +57,7 @@ static unsigned long hyp_default_vectors;
@@ -3310,6 +3304,15 @@ index bd18bb8..87ede26 100644
kvm->arch.vmid = kvm_next_vmid;
kvm_next_vmid++;
+@@ -1033,7 +1033,7 @@ static void check_kvm_target_cpu(void *ret)
+ /**
+ * Initialize Hyp-mode and memory mappings on all CPUs.
+ */
+-int kvm_arch_init(void *opaque)
++int kvm_arch_init(const void *opaque)
+ {
+ int err;
+ int ret, cpu;
diff --git a/arch/arm/lib/clear_user.S b/arch/arm/lib/clear_user.S
index 14a0d98..7771a7d 100644
--- a/arch/arm/lib/clear_user.S
@@ -5040,6 +5043,17 @@ index 0c8e553..112d734 100644
help
kexec is a system call that implements the ability to shutdown your
current kernel, and to start another kernel. It is like a reboot
+diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile
+index f37238f..810b95f 100644
+--- a/arch/ia64/Makefile
++++ b/arch/ia64/Makefile
+@@ -99,5 +99,6 @@ endef
+ archprepare: make_nr_irqs_h FORCE
+ PHONY += make_nr_irqs_h FORCE
+
++make_nr_irqs_h: KBUILD_CFLAGS := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS))
+ make_nr_irqs_h: FORCE
+ $(Q)$(MAKE) $(build)=arch/ia64/kernel include/generated/nr-irqs.h
diff --git a/arch/ia64/include/asm/atomic.h b/arch/ia64/include/asm/atomic.h
index 6e6fe18..a6ae668 100644
--- a/arch/ia64/include/asm/atomic.h
@@ -7136,6 +7150,19 @@ index 81e6ae0..6ab6e79 100644
info.si_code = FPE_INTOVF;
info.si_signo = SIGFPE;
+diff --git a/arch/mips/kvm/kvm_mips.c b/arch/mips/kvm/kvm_mips.c
+index 3e0ff8d..9eafbf0b 100644
+--- a/arch/mips/kvm/kvm_mips.c
++++ b/arch/mips/kvm/kvm_mips.c
+@@ -832,7 +832,7 @@ long kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
+ return r;
+ }
+
+-int kvm_arch_init(void *opaque)
++int kvm_arch_init(const void *opaque)
+ {
+ int ret;
+
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index becc42b..9e43d4b 100644
--- a/arch/mips/mm/fault.c
@@ -12269,10 +12296,18 @@ index ad8f795..2c7eec6 100644
/*
* Memory returned by kmalloc() may be used for DMA, so we must make
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
-index e409891..d64a8f7 100644
+index e409891..8ec65be 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
-@@ -126,7 +126,7 @@ config X86
+@@ -22,6 +22,7 @@ config X86_64
+ config X86
+ def_bool y
+ select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS
++ select ARCH_HAS_FAST_MULTIPLIER
+ select ARCH_MIGHT_HAVE_PC_PARPORT
+ select ARCH_MIGHT_HAVE_PC_SERIO
+ select HAVE_AOUT if X86_32
+@@ -126,7 +127,7 @@ config X86
select RTC_LIB
select HAVE_DEBUG_STACKOVERFLOW
select HAVE_IRQ_EXIT_ON_IRQ_STACK if X86_64
@@ -12281,7 +12316,7 @@ index e409891..d64a8f7 100644
select ARCH_SUPPORTS_ATOMIC_RMW
config INSTRUCTION_DECODER
-@@ -252,7 +252,7 @@ config X86_HT
+@@ -252,7 +253,7 @@ config X86_HT
config X86_32_LAZY_GS
def_bool y
@@ -12290,7 +12325,7 @@ index e409891..d64a8f7 100644
config ARCH_HWEIGHT_CFLAGS
string
-@@ -590,6 +590,7 @@ config SCHED_OMIT_FRAME_POINTER
+@@ -590,6 +591,7 @@ config SCHED_OMIT_FRAME_POINTER
menuconfig HYPERVISOR_GUEST
bool "Linux guest support"
@@ -12298,7 +12333,7 @@ index e409891..d64a8f7 100644
---help---
Say Y here to enable options for running Linux under various hyper-
visors. This option enables basic hypervisor detection and platform
-@@ -1129,7 +1130,7 @@ choice
+@@ -1129,7 +1131,7 @@ choice
config NOHIGHMEM
bool "off"
@@ -12307,7 +12342,7 @@ index e409891..d64a8f7 100644
---help---
Linux can use up to 64 Gigabytes of physical memory on x86 systems.
However, the address space of 32-bit x86 processors is only 4
-@@ -1166,7 +1167,7 @@ config NOHIGHMEM
+@@ -1166,7 +1168,7 @@ config NOHIGHMEM
config HIGHMEM4G
bool "4GB"
@@ -12316,7 +12351,7 @@ index e409891..d64a8f7 100644
---help---
Select this if you have a 32-bit processor and between 1 and 4
gigabytes of physical RAM.
-@@ -1219,7 +1220,7 @@ config PAGE_OFFSET
+@@ -1219,7 +1221,7 @@ config PAGE_OFFSET
hex
default 0xB0000000 if VMSPLIT_3G_OPT
default 0x80000000 if VMSPLIT_2G
@@ -12325,7 +12360,7 @@ index e409891..d64a8f7 100644
default 0x40000000 if VMSPLIT_1G
default 0xC0000000
depends on X86_32
-@@ -1624,6 +1625,7 @@ source kernel/Kconfig.hz
+@@ -1624,6 +1626,7 @@ source kernel/Kconfig.hz
config KEXEC
bool "kexec system call"
@@ -12333,7 +12368,7 @@ index e409891..d64a8f7 100644
---help---
kexec is a system call that implements the ability to shutdown your
current kernel, and to start another kernel. It is like a reboot
-@@ -1775,7 +1777,9 @@ config X86_NEED_RELOCS
+@@ -1775,7 +1778,9 @@ config X86_NEED_RELOCS
config PHYSICAL_ALIGN
hex "Alignment value to which kernel should be aligned"
@@ -12344,7 +12379,7 @@ index e409891..d64a8f7 100644
range 0x2000 0x1000000 if X86_32
range 0x200000 0x1000000 if X86_64
---help---
-@@ -1855,9 +1859,10 @@ config DEBUG_HOTPLUG_CPU0
+@@ -1855,9 +1860,10 @@ config DEBUG_HOTPLUG_CPU0
If unsure, say N.
config COMPAT_VDSO
@@ -15762,7 +15797,7 @@ index 69bbb48..32517fe 100644
#define smp_load_acquire(p) \
diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h
-index 9fc1af7..776d75a 100644
+index 9fc1af7..98cab0b 100644
--- a/arch/x86/include/asm/bitops.h
+++ b/arch/x86/include/asm/bitops.h
@@ -49,7 +49,7 @@
@@ -15846,6 +15881,15 @@ index 9fc1af7..776d75a 100644
{
int bitpos = -1;
/*
+@@ -499,8 +499,6 @@ static __always_inline int fls64(__u64 x)
+
+ #include <asm-generic/bitops/sched.h>
+
+-#define ARCH_HAS_FAST_MULTIPLIER 1
+-
+ #include <asm/arch_hweight.h>
+
+ #include <asm-generic/bitops/const_hweight.h>
diff --git a/arch/x86/include/asm/boot.h b/arch/x86/include/asm/boot.h
index 4fa687a..60f2d39 100644
--- a/arch/x86/include/asm/boot.h
@@ -18168,7 +18212,7 @@ index b39e194..9d44fd1 100644
/*
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
-index fdedd38..95c02c2 100644
+index fdedd38..129b180 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -128,7 +128,7 @@ struct cpuinfo_x86 {
@@ -18190,7 +18234,7 @@ index fdedd38..95c02c2 100644
+#define INVPCID_SINGLE_ADDRESS 0UL
+#define INVPCID_SINGLE_CONTEXT 1UL
+#define INVPCID_ALL_GLOBAL 2UL
-+#define INVPCID_ALL_MONGLOBAL 3UL
++#define INVPCID_ALL_NONGLOBAL 3UL
+
+#define PCID_KERNEL 0UL
+#define PCID_USER 1UL
@@ -19295,7 +19339,7 @@ index e1940c0..ac50dd8 100644
#endif
#endif /* _ASM_X86_THREAD_INFO_H */
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
-index 04905bf..49203ca 100644
+index 04905bf..1178cdf 100644
--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -17,18 +17,44 @@
@@ -19306,7 +19350,7 @@ index 04905bf..49203ca 100644
+ u64 descriptor[2];
+
+ descriptor[0] = PCID_KERNEL;
-+ asm volatile(__ASM_INVPCID : : "d"(&descriptor), "a"(INVPCID_ALL_MONGLOBAL) : "memory");
++ asm volatile(__ASM_INVPCID : : "d"(&descriptor), "a"(INVPCID_ALL_NONGLOBAL) : "memory");
+ return;
+ }
+
@@ -29166,7 +29210,7 @@ index f5cc9eb..51fa319 100644
CFI_ENDPROC
ENDPROC(atomic64_inc_not_zero_cx8)
diff --git a/arch/x86/lib/checksum_32.S b/arch/x86/lib/checksum_32.S
-index e78b8ee..7e173a8 100644
+index e78b8eee..7e173a8 100644
--- a/arch/x86/lib/checksum_32.S
+++ b/arch/x86/lib/checksum_32.S
@@ -29,7 +29,8 @@
@@ -40827,7 +40871,7 @@ index d45d50d..72a5dd2 100644
int
diff --git a/drivers/gpu/drm/nouveau/nouveau_vga.c b/drivers/gpu/drm/nouveau/nouveau_vga.c
-index 471347e..5adc6b9 100644
+index 471347e..5adc6b9d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_vga.c
+++ b/drivers/gpu/drm/nouveau/nouveau_vga.c
@@ -67,7 +67,7 @@ nouveau_switcheroo_can_switch(struct pci_dev *pdev)
@@ -59370,10 +59414,126 @@ index a93f7e6..d58bcbe 100644
return 0;
while (nr) {
diff --git a/fs/dcache.c b/fs/dcache.c
-index 7f3b400..9c911f2 100644
+index 7f3b400..f91b141 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
-@@ -1495,7 +1495,7 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name)
+@@ -106,8 +106,7 @@ static inline struct hlist_bl_head *d_hash(const struct dentry *parent,
+ unsigned int hash)
+ {
+ hash += (unsigned long) parent / L1_CACHE_BYTES;
+- hash = hash + (hash >> d_hash_shift);
+- return dentry_hashtable + (hash & d_hash_mask);
++ return dentry_hashtable + hash_32(hash, d_hash_shift);
+ }
+
+ /* Statistics gathering. */
+@@ -251,7 +250,7 @@ static void __d_free(struct rcu_head *head)
+ */
+ static void d_free(struct dentry *dentry)
+ {
+- BUG_ON((int)dentry->d_lockref.count > 0);
++ BUG_ON((int)__lockref_read(&dentry->d_lockref) > 0);
+ this_cpu_dec(nr_dentry);
+ if (dentry->d_op && dentry->d_op->d_release)
+ dentry->d_op->d_release(dentry);
+@@ -597,7 +596,7 @@ repeat:
+ dentry->d_flags |= DCACHE_REFERENCED;
+ dentry_lru_add(dentry);
+
+- dentry->d_lockref.count--;
++ __lockref_dec(&dentry->d_lockref);
+ spin_unlock(&dentry->d_lock);
+ return;
+
+@@ -652,7 +651,7 @@ int d_invalidate(struct dentry * dentry)
+ * We also need to leave mountpoints alone,
+ * directory or not.
+ */
+- if (dentry->d_lockref.count > 1 && dentry->d_inode) {
++ if (__lockref_read(&dentry->d_lockref) > 1 && dentry->d_inode) {
+ if (S_ISDIR(dentry->d_inode->i_mode) || d_mountpoint(dentry)) {
+ spin_unlock(&dentry->d_lock);
+ return -EBUSY;
+@@ -668,7 +667,7 @@ EXPORT_SYMBOL(d_invalidate);
+ /* This must be called with d_lock held */
+ static inline void __dget_dlock(struct dentry *dentry)
+ {
+- dentry->d_lockref.count++;
++ __lockref_inc(&dentry->d_lockref);
+ }
+
+ static inline void __dget(struct dentry *dentry)
+@@ -709,8 +708,8 @@ repeat:
+ goto repeat;
+ }
+ rcu_read_unlock();
+- BUG_ON(!ret->d_lockref.count);
+- ret->d_lockref.count++;
++ BUG_ON(!__lockref_read(&ret->d_lockref));
++ __lockref_inc(&ret->d_lockref);
+ spin_unlock(&ret->d_lock);
+ return ret;
+ }
+@@ -793,7 +792,7 @@ restart:
+ spin_lock(&inode->i_lock);
+ hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) {
+ spin_lock(&dentry->d_lock);
+- if (!dentry->d_lockref.count) {
++ if (!__lockref_read(&dentry->d_lockref)) {
+ /*
+ * inform the fs via d_prune that this dentry
+ * is about to be unhashed and destroyed.
+@@ -885,7 +884,7 @@ static void shrink_dentry_list(struct list_head *list)
+ * We found an inuse dentry which was not removed from
+ * the LRU because of laziness during lookup. Do not free it.
+ */
+- if (dentry->d_lockref.count) {
++ if (__lockref_read(&dentry->d_lockref)) {
+ spin_unlock(&dentry->d_lock);
+ continue;
+ }
+@@ -931,7 +930,7 @@ dentry_lru_isolate(struct list_head *item, spinlock_t *lru_lock, void *arg)
+ * counts, just remove them from the LRU. Otherwise give them
+ * another pass through the LRU.
+ */
+- if (dentry->d_lockref.count) {
++ if (__lockref_read(&dentry->d_lockref) > 0) {
+ d_lru_isolate(dentry);
+ spin_unlock(&dentry->d_lock);
+ return LRU_REMOVED;
+@@ -1269,7 +1268,7 @@ static enum d_walk_ret select_collect(void *_data, struct dentry *dentry)
+ * loop in shrink_dcache_parent() might not make any progress
+ * and loop forever.
+ */
+- if (dentry->d_lockref.count) {
++ if (__lockref_read(&dentry->d_lockref)) {
+ dentry_lru_del(dentry);
+ } else if (!(dentry->d_flags & DCACHE_SHRINK_LIST)) {
+ /*
+@@ -1323,11 +1322,11 @@ static enum d_walk_ret umount_collect(void *_data, struct dentry *dentry)
+ struct select_data *data = _data;
+ enum d_walk_ret ret = D_WALK_CONTINUE;
+
+- if (dentry->d_lockref.count) {
++ if (__lockref_read(&dentry->d_lockref)) {
+ dentry_lru_del(dentry);
+ if (likely(!list_empty(&dentry->d_subdirs)))
+ goto out;
+- if (dentry == data->start && dentry->d_lockref.count == 1)
++ if (dentry == data->start && __lockref_read(&dentry->d_lockref) == 1)
+ goto out;
+ printk(KERN_ERR
+ "BUG: Dentry %p{i=%lx,n=%s}"
+@@ -1337,7 +1336,7 @@ static enum d_walk_ret umount_collect(void *_data, struct dentry *dentry)
+ dentry->d_inode ?
+ dentry->d_inode->i_ino : 0UL,
+ dentry->d_name.name,
+- dentry->d_lockref.count,
++ __lockref_read(&dentry->d_lockref),
+ dentry->d_sb->s_type->name,
+ dentry->d_sb->s_id);
+ BUG();
+@@ -1495,7 +1494,7 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name)
*/
dentry->d_iname[DNAME_INLINE_LEN-1] = 0;
if (name->len > DNAME_INLINE_LEN-1) {
@@ -59382,7 +59542,43 @@ index 7f3b400..9c911f2 100644
if (!dname) {
kmem_cache_free(dentry_cache, dentry);
return NULL;
-@@ -3430,7 +3430,8 @@ void __init vfs_caches_init(unsigned long mempages)
+@@ -1513,7 +1512,7 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name)
+ smp_wmb();
+ dentry->d_name.name = dname;
+
+- dentry->d_lockref.count = 1;
++ __lockref_set(&dentry->d_lockref, 1);
+ dentry->d_flags = 0;
+ spin_lock_init(&dentry->d_lock);
+ seqcount_init(&dentry->d_seq);
+@@ -2276,7 +2275,7 @@ struct dentry *__d_lookup(const struct dentry *parent, const struct qstr *name)
+ goto next;
+ }
+
+- dentry->d_lockref.count++;
++ __lockref_inc(&dentry->d_lockref);
+ found = dentry;
+ spin_unlock(&dentry->d_lock);
+ break;
+@@ -2375,7 +2374,7 @@ again:
+ spin_lock(&dentry->d_lock);
+ inode = dentry->d_inode;
+ isdir = S_ISDIR(inode->i_mode);
+- if (dentry->d_lockref.count == 1) {
++ if (__lockref_read(&dentry->d_lockref) == 1) {
+ if (!spin_trylock(&inode->i_lock)) {
+ spin_unlock(&dentry->d_lock);
+ cpu_relax();
+@@ -3314,7 +3313,7 @@ static enum d_walk_ret d_genocide_kill(void *data, struct dentry *dentry)
+
+ if (!(dentry->d_flags & DCACHE_GENOCIDE)) {
+ dentry->d_flags |= DCACHE_GENOCIDE;
+- dentry->d_lockref.count--;
++ __lockref_dec(&dentry->d_lockref);
+ }
+ }
+ return D_WALK_CONTINUE;
+@@ -3430,7 +3429,8 @@ void __init vfs_caches_init(unsigned long mempages)
mempages -= reserve;
names_cachep = kmem_cache_create("names_cache", PATH_MAX, 0,
@@ -62537,10 +62733,18 @@ index b29e42f..5ea7fdf 100644
#define MNT_NS_INTERNAL ERR_PTR(-EINVAL) /* distinct from any mnt_namespace */
diff --git a/fs/namei.c b/fs/namei.c
-index bdea109..e242796 100644
+index bdea109..6e919ab 100644
--- a/fs/namei.c
+++ b/fs/namei.c
-@@ -330,17 +330,34 @@ int generic_permission(struct inode *inode, int mask)
+@@ -34,6 +34,7 @@
+ #include <linux/device_cgroup.h>
+ #include <linux/fs_struct.h>
+ #include <linux/posix_acl.h>
++#include <linux/hash.h>
+ #include <asm/uaccess.h>
+
+ #include "internal.h"
+@@ -330,17 +331,34 @@ int generic_permission(struct inode *inode, int mask)
if (ret != -EACCES)
return ret;
@@ -62578,7 +62782,7 @@ index bdea109..e242796 100644
* Read/write DACs are always overridable.
* Executable DACs are overridable when there is
* at least one exec bit set.
-@@ -349,14 +366,6 @@ int generic_permission(struct inode *inode, int mask)
+@@ -349,14 +367,6 @@ int generic_permission(struct inode *inode, int mask)
if (capable_wrt_inode_uidgid(inode, CAP_DAC_OVERRIDE))
return 0;
@@ -62593,7 +62797,7 @@ index bdea109..e242796 100644
return -EACCES;
}
-@@ -822,7 +831,7 @@ follow_link(struct path *link, struct nameidata *nd, void **p)
+@@ -822,7 +832,7 @@ follow_link(struct path *link, struct nameidata *nd, void **p)
{
struct dentry *dentry = link->dentry;
int error;
@@ -62602,7 +62806,7 @@ index bdea109..e242796 100644
BUG_ON(nd->flags & LOOKUP_RCU);
-@@ -843,6 +852,12 @@ follow_link(struct path *link, struct nameidata *nd, void **p)
+@@ -843,6 +853,12 @@ follow_link(struct path *link, struct nameidata *nd, void **p)
if (error)
goto out_put_nd_path;
@@ -62615,7 +62819,7 @@ index bdea109..e242796 100644
nd->last_type = LAST_BIND;
*p = dentry->d_inode->i_op->follow_link(dentry, nd);
error = PTR_ERR(*p);
-@@ -1591,6 +1606,8 @@ static inline int nested_symlink(struct path *path, struct nameidata *nd)
+@@ -1591,6 +1607,8 @@ static inline int nested_symlink(struct path *path, struct nameidata *nd)
if (res)
break;
res = walk_component(nd, path, LOOKUP_FOLLOW);
@@ -62624,6 +62828,16 @@ index bdea109..e242796 100644
put_link(nd, &link, cookie);
} while (res > 0);
+@@ -1624,8 +1642,7 @@ static inline int nested_symlink(struct path *path, struct nameidata *nd)
+
+ static inline unsigned int fold_hash(unsigned long hash)
+ {
+- hash += hash >> (8*sizeof(int));
+- return hash;
++ return hash_64(hash, 32);
+ }
+
+ #else /* 32-bit case */
@@ -1664,7 +1681,7 @@ EXPORT_SYMBOL(full_name_hash);
static inline unsigned long hash_name(const char *name, unsigned int *hashp)
{
@@ -63483,6 +63697,28 @@ index 287a22c..4e56e4e 100644
group->fanotify_data.f_flags = event_f_flags;
#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
oevent->response = 0;
+diff --git a/fs/notify/fdinfo.c b/fs/notify/fdinfo.c
+index 238a593..9d7e2b9 100644
+--- a/fs/notify/fdinfo.c
++++ b/fs/notify/fdinfo.c
+@@ -42,7 +42,7 @@ static int show_mark_fhandle(struct seq_file *m, struct inode *inode)
+ {
+ struct {
+ struct file_handle handle;
+- u8 pad[64];
++ u8 pad[MAX_HANDLE_SZ];
+ } f;
+ int size, ret, i;
+
+@@ -50,7 +50,7 @@ static int show_mark_fhandle(struct seq_file *m, struct inode *inode)
+ size = f.handle.handle_bytes >> 2;
+
+ ret = exportfs_encode_inode_fh(inode, (struct fid *)f.handle.f_handle, &size, 0);
+- if ((ret == 255) || (ret == -ENOSPC)) {
++ if ((ret == FILEID_INVALID) || (ret < 0)) {
+ WARN_ONCE(1, "Can't encode file handler for inotify: %d\n", ret);
+ return 0;
+ }
diff --git a/fs/notify/notification.c b/fs/notify/notification.c
index 1e58402..bb2d6f4 100644
--- a/fs/notify/notification.c
@@ -66416,6 +66652,133 @@ index e18b988..f1d4ad0f 100644
{
int err;
+diff --git a/fs/udf/inode.c b/fs/udf/inode.c
+index 982ce05..c693331 100644
+--- a/fs/udf/inode.c
++++ b/fs/udf/inode.c
+@@ -51,7 +51,6 @@ MODULE_LICENSE("GPL");
+
+ static umode_t udf_convert_permissions(struct fileEntry *);
+ static int udf_update_inode(struct inode *, int);
+-static void udf_fill_inode(struct inode *, struct buffer_head *);
+ static int udf_sync_inode(struct inode *inode);
+ static int udf_alloc_i_data(struct inode *inode, size_t size);
+ static sector_t inode_getblk(struct inode *, sector_t, int *, int *);
+@@ -1271,13 +1270,25 @@ update_time:
+ return 0;
+ }
+
++/*
++ * Maximum length of linked list formed by ICB hierarchy. The chosen number is
++ * arbitrary - just that we hopefully don't limit any real use of rewritten
++ * inode on write-once media but avoid looping for too long on corrupted media.
++ */
++#define UDF_MAX_ICB_NESTING 1024
++
+ static void __udf_read_inode(struct inode *inode)
+ {
+ struct buffer_head *bh = NULL;
+ struct fileEntry *fe;
++ struct extendedFileEntry *efe;
+ uint16_t ident;
+ struct udf_inode_info *iinfo = UDF_I(inode);
++ struct udf_sb_info *sbi = UDF_SB(inode->i_sb);
++ unsigned int link_count;
++ unsigned int indirections = 0;
+
++reread:
+ /*
+ * Set defaults, but the inode is still incomplete!
+ * Note: get_new_inode() sets the following on a new inode:
+@@ -1307,6 +1318,7 @@ static void __udf_read_inode(struct inode *inode)
+ }
+
+ fe = (struct fileEntry *)bh->b_data;
++ efe = (struct extendedFileEntry *)bh->b_data;
+
+ if (fe->icbTag.strategyType == cpu_to_le16(4096)) {
+ struct buffer_head *ibh;
+@@ -1314,28 +1326,26 @@ static void __udf_read_inode(struct inode *inode)
+ ibh = udf_read_ptagged(inode->i_sb, &iinfo->i_location, 1,
+ &ident);
+ if (ident == TAG_IDENT_IE && ibh) {
+- struct buffer_head *nbh = NULL;
+ struct kernel_lb_addr loc;
+ struct indirectEntry *ie;
+
+ ie = (struct indirectEntry *)ibh->b_data;
+ loc = lelb_to_cpu(ie->indirectICB.extLocation);
+
+- if (ie->indirectICB.extLength &&
+- (nbh = udf_read_ptagged(inode->i_sb, &loc, 0,
+- &ident))) {
+- if (ident == TAG_IDENT_FE ||
+- ident == TAG_IDENT_EFE) {
+- memcpy(&iinfo->i_location,
+- &loc,
+- sizeof(struct kernel_lb_addr));
+- brelse(bh);
+- brelse(ibh);
+- brelse(nbh);
+- __udf_read_inode(inode);
++ if (ie->indirectICB.extLength) {
++ brelse(bh);
++ brelse(ibh);
++ memcpy(&iinfo->i_location, &loc,
++ sizeof(struct kernel_lb_addr));
++ if (++indirections > UDF_MAX_ICB_NESTING) {
++ udf_err(inode->i_sb,
++ "too many ICBs in ICB hierarchy"
++ " (max %d supported)\n",
++ UDF_MAX_ICB_NESTING);
++ make_bad_inode(inode);
+ return;
+ }
+- brelse(nbh);
++ goto reread;
+ }
+ }
+ brelse(ibh);
+@@ -1346,22 +1356,6 @@ static void __udf_read_inode(struct inode *inode)
+ make_bad_inode(inode);
+ return;
+ }
+- udf_fill_inode(inode, bh);
+-
+- brelse(bh);
+-}
+-
+-static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
+-{
+- struct fileEntry *fe;
+- struct extendedFileEntry *efe;
+- struct udf_sb_info *sbi = UDF_SB(inode->i_sb);
+- struct udf_inode_info *iinfo = UDF_I(inode);
+- unsigned int link_count;
+-
+- fe = (struct fileEntry *)bh->b_data;
+- efe = (struct extendedFileEntry *)bh->b_data;
+-
+ if (fe->icbTag.strategyType == cpu_to_le16(4))
+ iinfo->i_strat4096 = 0;
+ else /* if (fe->icbTag.strategyType == cpu_to_le16(4096)) */
+@@ -1551,6 +1545,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
+ } else
+ make_bad_inode(inode);
+ }
++ brelse(bh);
+ }
+
+ static int udf_alloc_i_data(struct inode *inode, size_t size)
+@@ -1664,7 +1659,7 @@ static int udf_update_inode(struct inode *inode, int do_sync)
+ FE_PERM_U_DELETE | FE_PERM_U_CHATTR));
+ fe->permissions = cpu_to_le32(udfperms);
+
+- if (S_ISDIR(inode->i_mode))
++ if (S_ISDIR(inode->i_mode) && inode->i_nlink > 0)
+ fe->fileLinkCount = cpu_to_le16(inode->i_nlink - 1);
+ else
+ fe->fileLinkCount = cpu_to_le16(inode->i_nlink);
diff --git a/fs/udf/misc.c b/fs/udf/misc.c
index c175b4d..8f36a16 100644
--- a/fs/udf/misc.c
@@ -80906,10 +81269,28 @@ index 0000000..e7ffaaf
+
+#endif
diff --git a/include/linux/hash.h b/include/linux/hash.h
-index bd1754c..8240892 100644
+index bd1754c..69b7715 100644
--- a/include/linux/hash.h
+++ b/include/linux/hash.h
-@@ -83,7 +83,7 @@ static inline u32 hash32_ptr(const void *ptr)
+@@ -37,6 +37,9 @@ static __always_inline u64 hash_64(u64 val, unsigned int bits)
+ {
+ u64 hash = val;
+
++#if defined(CONFIG_ARCH_HAS_FAST_MULTIPLIER) && BITS_PER_LONG == 64
++ hash = hash * GOLDEN_RATIO_PRIME_64;
++#else
+ /* Sigh, gcc can't optimise this alone like it does for 32 bits. */
+ u64 n = hash;
+ n <<= 18;
+@@ -51,6 +54,7 @@ static __always_inline u64 hash_64(u64 val, unsigned int bits)
+ hash += n;
+ n <<= 2;
+ hash += n;
++#endif
+
+ /* High bits are more random, so use them. */
+ return hash >> (64 - bits);
+@@ -83,7 +87,7 @@ static inline u32 hash32_ptr(const void *ptr)
struct fast_hash_ops {
u32 (*hash)(const void *data, u32 len, u32 seed);
u32 (*hash2)(const u32 *data, u32 len, u32 seed);
@@ -81425,6 +81806,47 @@ index ef95941..82db65a 100644
/**
* list_move - delete from one list and add as another's head
* @list: the entry to move
+diff --git a/include/linux/lockref.h b/include/linux/lockref.h
+index 4bfde0e..d6e2e09 100644
+--- a/include/linux/lockref.h
++++ b/include/linux/lockref.h
+@@ -47,4 +47,36 @@ static inline int __lockref_is_dead(const struct lockref *l)
+ return ((int)l->count < 0);
+ }
+
++static inline unsigned int __lockref_read(struct lockref *lockref)
++{
++ return lockref->count;
++}
++
++static inline void __lockref_set(struct lockref *lockref, unsigned int count)
++{
++ lockref->count = count;
++}
++
++static inline void __lockref_inc(struct lockref *lockref)
++{
++
++#ifdef CONFIG_PAX_REFCOUNT
++ atomic_inc((atomic_t *)&lockref->count);
++#else
++ lockref->count++;
++#endif
++
++}
++
++static inline void __lockref_dec(struct lockref *lockref)
++{
++
++#ifdef CONFIG_PAX_REFCOUNT
++ atomic_dec((atomic_t *)&lockref->count);
++#else
++ lockref->count--;
++#endif
++
++}
++
+ #endif /* __LINUX_LOCKREF_H */
diff --git a/include/linux/math64.h b/include/linux/math64.h
index c45c089..298841c 100644
--- a/include/linux/math64.h
@@ -87733,7 +88155,7 @@ index c44bff8..a3c5876 100644
else
new_fs = fs;
diff --git a/kernel/futex.c b/kernel/futex.c
-index e3087af..8e3b90f 100644
+index e3087af..4730710 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -54,6 +54,7 @@
@@ -87783,7 +88205,15 @@ index e3087af..8e3b90f 100644
pagefault_disable();
ret = __copy_from_user_inatomic(dest, from, sizeof(u32));
-@@ -3019,6 +3025,7 @@ static void __init futex_detect_cmpxchg(void)
+@@ -2614,6 +2620,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags,
+ * shared futexes. We need to compare the keys:
+ */
+ if (match_futex(&q.key, &key2)) {
++ queue_unlock(hb);
+ ret = -EINVAL;
+ goto out_put_keys;
+ }
+@@ -3019,6 +3026,7 @@ static void __init futex_detect_cmpxchg(void)
{
#ifndef CONFIG_HAVE_FUTEX_CMPXCHG
u32 curval;
@@ -87791,7 +88221,7 @@ index e3087af..8e3b90f 100644
/*
* This will fail and we want it. Some arch implementations do
-@@ -3030,8 +3037,11 @@ static void __init futex_detect_cmpxchg(void)
+@@ -3030,8 +3038,11 @@ static void __init futex_detect_cmpxchg(void)
* implementation, the non-functional ones will return
* -ENOSYS.
*/
@@ -88025,10 +88455,26 @@ index 3127ad5..159d880 100644
return -ENOMEM;
reset_iter(iter, 0);
diff --git a/kernel/kcmp.c b/kernel/kcmp.c
-index e30ac0f..3528cac 100644
+index e30ac0f..a7fcafb 100644
--- a/kernel/kcmp.c
+++ b/kernel/kcmp.c
-@@ -99,6 +99,10 @@ SYSCALL_DEFINE5(kcmp, pid_t, pid1, pid_t, pid2, int, type,
+@@ -44,11 +44,12 @@ static long kptr_obfuscate(long v, int type)
+ */
+ static int kcmp_ptr(void *v1, void *v2, enum kcmp_type type)
+ {
+- long ret;
++ long t1, t2;
+
+- ret = kptr_obfuscate((long)v1, type) - kptr_obfuscate((long)v2, type);
++ t1 = kptr_obfuscate((long)v1, type);
++ t2 = kptr_obfuscate((long)v2, type);
+
+- return (ret < 0) | ((ret > 0) << 1);
++ return (t1 < t2) | ((t1 > t2) << 1);
+ }
+
+ /* The caller must have pinned the task */
+@@ -99,6 +100,10 @@ SYSCALL_DEFINE5(kcmp, pid_t, pid1, pid_t, pid2, int, type,
struct task_struct *task1, *task2;
int ret;
@@ -91717,10 +92163,71 @@ index 7c7964c..2a0d412 100644
update_vsyscall_tz();
if (firsttime) {
diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c
-index fe75444..190c528 100644
+index fe75444..b8a1463 100644
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
-@@ -811,7 +811,7 @@ static int __init alarmtimer_init(void)
+@@ -464,18 +464,26 @@ static enum alarmtimer_type clock2alarm(clockid_t clockid)
+ static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm,
+ ktime_t now)
+ {
++ unsigned long flags;
+ struct k_itimer *ptr = container_of(alarm, struct k_itimer,
+ it.alarm.alarmtimer);
+- if (posix_timer_event(ptr, 0) != 0)
+- ptr->it_overrun++;
++ enum alarmtimer_restart result = ALARMTIMER_NORESTART;
++
++ spin_lock_irqsave(&ptr->it_lock, flags);
++ if ((ptr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) {
++ if (posix_timer_event(ptr, 0) != 0)
++ ptr->it_overrun++;
++ }
+
+ /* Re-add periodic timers */
+ if (ptr->it.alarm.interval.tv64) {
+ ptr->it_overrun += alarm_forward(alarm, now,
+ ptr->it.alarm.interval);
+- return ALARMTIMER_RESTART;
++ result = ALARMTIMER_RESTART;
+ }
+- return ALARMTIMER_NORESTART;
++ spin_unlock_irqrestore(&ptr->it_lock, flags);
++
++ return result;
+ }
+
+ /**
+@@ -541,18 +549,22 @@ static int alarm_timer_create(struct k_itimer *new_timer)
+ * @new_timer: k_itimer pointer
+ * @cur_setting: itimerspec data to fill
+ *
+- * Copies the itimerspec data out from the k_itimer
++ * Copies out the current itimerspec data
+ */
+ static void alarm_timer_get(struct k_itimer *timr,
+ struct itimerspec *cur_setting)
+ {
+- memset(cur_setting, 0, sizeof(struct itimerspec));
++ ktime_t relative_expiry_time =
++ alarm_expires_remaining(&(timr->it.alarm.alarmtimer));
+
+- cur_setting->it_interval =
+- ktime_to_timespec(timr->it.alarm.interval);
+- cur_setting->it_value =
+- ktime_to_timespec(timr->it.alarm.alarmtimer.node.expires);
+- return;
++ if (ktime_to_ns(relative_expiry_time) > 0) {
++ cur_setting->it_value = ktime_to_timespec(relative_expiry_time);
++ } else {
++ cur_setting->it_value.tv_sec = 0;
++ cur_setting->it_value.tv_nsec = 0;
++ }
++
++ cur_setting->it_interval = ktime_to_timespec(timr->it.alarm.interval);
+ }
+
+ /**
+@@ -811,7 +823,7 @@ static int __init alarmtimer_init(void)
struct platform_device *pdev;
int error = 0;
int i;
@@ -92504,6 +93011,20 @@ index b4defde..f092808 100644
}
spin_unlock_irq(&pool->lock);
+diff --git a/lib/Kconfig b/lib/Kconfig
+index 991c98b..88061cf 100644
+--- a/lib/Kconfig
++++ b/lib/Kconfig
+@@ -51,6 +51,9 @@ config PERCPU_RWSEM
+ config ARCH_USE_CMPXCHG_LOCKREF
+ bool
+
++config ARCH_HAS_FAST_MULTIPLIER
++ bool
++
+ config CRC_CCITT
+ tristate "CRC-CCITT functions"
+ help
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index a48abea..e108def 100644
--- a/lib/Kconfig.debug
@@ -92584,10 +93105,25 @@ index 48140e3..de854e5 100644
ifneq ($(CONFIG_HAVE_DEC_LOCK),y)
diff --git a/lib/assoc_array.c b/lib/assoc_array.c
-index c0b1007..ae146f0 100644
+index c0b1007..2404d03 100644
--- a/lib/assoc_array.c
+++ b/lib/assoc_array.c
-@@ -1735,7 +1735,7 @@ ascend_old_tree:
+@@ -1723,11 +1723,13 @@ ascend_old_tree:
+ shortcut = assoc_array_ptr_to_shortcut(ptr);
+ slot = shortcut->parent_slot;
+ cursor = shortcut->back_pointer;
++ if (!cursor)
++ goto gc_complete;
+ } else {
+ slot = node->parent_slot;
+ cursor = ptr;
+ }
+- BUG_ON(!ptr);
++ BUG_ON(!cursor);
+ node = assoc_array_ptr_to_node(cursor);
+ slot++;
+ goto continue_node;
+@@ -1735,7 +1737,7 @@ ascend_old_tree:
gc_complete:
edit->set[0].to = new_root;
assoc_array_apply_edit(edit);
@@ -92754,6 +93290,28 @@ index fea973f..386626f 100644
.hash = jhash,
.hash2 = jhash2,
};
+diff --git a/lib/hweight.c b/lib/hweight.c
+index b7d81ba..9a5c1f2 100644
+--- a/lib/hweight.c
++++ b/lib/hweight.c
+@@ -11,7 +11,7 @@
+
+ unsigned int __sw_hweight32(unsigned int w)
+ {
+-#ifdef ARCH_HAS_FAST_MULTIPLIER
++#ifdef CONFIG_ARCH_HAS_FAST_MULTIPLIER
+ w -= (w >> 1) & 0x55555555;
+ w = (w & 0x33333333) + ((w >> 2) & 0x33333333);
+ w = (w + (w >> 4)) & 0x0f0f0f0f;
+@@ -49,7 +49,7 @@ unsigned long __sw_hweight64(__u64 w)
+ return __sw_hweight32((unsigned int)(w >> 32)) +
+ __sw_hweight32((unsigned int)w);
+ #elif BITS_PER_LONG == 64
+-#ifdef ARCH_HAS_FAST_MULTIPLIER
++#ifdef CONFIG_ARCH_HAS_FAST_MULTIPLIER
+ w -= (w >> 1) & 0x5555555555555555ul;
+ w = (w & 0x3333333333333333ul) + ((w >> 2) & 0x3333333333333333ul);
+ w = (w + (w >> 4)) & 0x0f0f0f0f0f0f0f0ful;
diff --git a/lib/inflate.c b/lib/inflate.c
index 013a761..c28f3fc 100644
--- a/lib/inflate.c
@@ -93040,6 +93598,98 @@ index c24c2f7..f0296f4 100644
+ pax_close_kernel();
+}
+EXPORT_SYMBOL(pax_list_del_rcu);
+diff --git a/lib/lockref.c b/lib/lockref.c
+index f07a40d..0a445a7 100644
+--- a/lib/lockref.c
++++ b/lib/lockref.c
+@@ -49,13 +49,13 @@
+ void lockref_get(struct lockref *lockref)
+ {
+ CMPXCHG_LOOP(
+- new.count++;
++ __lockref_inc(&new);
+ ,
+ return;
+ );
+
+ spin_lock(&lockref->lock);
+- lockref->count++;
++ __lockref_inc(lockref);
+ spin_unlock(&lockref->lock);
+ }
+ EXPORT_SYMBOL(lockref_get);
+@@ -70,7 +70,7 @@ int lockref_get_not_zero(struct lockref *lockref)
+ int retval;
+
+ CMPXCHG_LOOP(
+- new.count++;
++ __lockref_inc(&new);
+ if (!old.count)
+ return 0;
+ ,
+@@ -80,7 +80,7 @@ int lockref_get_not_zero(struct lockref *lockref)
+ spin_lock(&lockref->lock);
+ retval = 0;
+ if (lockref->count) {
+- lockref->count++;
++ __lockref_inc(lockref);
+ retval = 1;
+ }
+ spin_unlock(&lockref->lock);
+@@ -97,7 +97,7 @@ EXPORT_SYMBOL(lockref_get_not_zero);
+ int lockref_get_or_lock(struct lockref *lockref)
+ {
+ CMPXCHG_LOOP(
+- new.count++;
++ __lockref_inc(&new);
+ if (!old.count)
+ break;
+ ,
+@@ -107,7 +107,7 @@ int lockref_get_or_lock(struct lockref *lockref)
+ spin_lock(&lockref->lock);
+ if (!lockref->count)
+ return 0;
+- lockref->count++;
++ __lockref_inc(lockref);
+ spin_unlock(&lockref->lock);
+ return 1;
+ }
+@@ -121,7 +121,7 @@ EXPORT_SYMBOL(lockref_get_or_lock);
+ int lockref_put_or_lock(struct lockref *lockref)
+ {
+ CMPXCHG_LOOP(
+- new.count--;
++ __lockref_dec(&new);
+ if (old.count <= 1)
+ break;
+ ,
+@@ -131,7 +131,7 @@ int lockref_put_or_lock(struct lockref *lockref)
+ spin_lock(&lockref->lock);
+ if (lockref->count <= 1)
+ return 0;
+- lockref->count--;
++ __lockref_dec(lockref);
+ spin_unlock(&lockref->lock);
+ return 1;
+ }
+@@ -158,7 +158,7 @@ int lockref_get_not_dead(struct lockref *lockref)
+ int retval;
+
+ CMPXCHG_LOOP(
+- new.count++;
++ __lockref_inc(&new);
+ if ((int)old.count < 0)
+ return 0;
+ ,
+@@ -168,7 +168,7 @@ int lockref_get_not_dead(struct lockref *lockref)
+ spin_lock(&lockref->lock);
+ retval = 0;
+ if ((int) lockref->count >= 0) {
+- lockref->count++;
++ __lockref_inc(lockref);
+ retval = 1;
+ }
+ spin_unlock(&lockref->lock);
diff --git a/lib/percpu-refcount.c b/lib/percpu-refcount.c
index 963b703..438bc51 100644
--- a/lib/percpu-refcount.c
@@ -93106,6 +93756,22 @@ index 0922579..9d7adb9 100644
+ printk("%lu pages hwpoisoned\n", atomic_long_read_unchecked(&num_poisoned_pages));
#endif
}
+diff --git a/lib/string.c b/lib/string.c
+index e5878de..315fad2 100644
+--- a/lib/string.c
++++ b/lib/string.c
+@@ -789,9 +789,9 @@ void *memchr_inv(const void *start, int c, size_t bytes)
+ return check_bytes8(start, value, bytes);
+
+ value64 = value;
+-#if defined(ARCH_HAS_FAST_MULTIPLIER) && BITS_PER_LONG == 64
++#if defined(CONFIG_ARCH_HAS_FAST_MULTIPLIER) && BITS_PER_LONG == 64
+ value64 *= 0x0101010101010101;
+-#elif defined(ARCH_HAS_FAST_MULTIPLIER)
++#elif defined(CONFIG_ARCH_HAS_FAST_MULTIPLIER)
+ value64 *= 0x01010101;
+ value64 |= value64 << 32;
+ #else
diff --git a/lib/strncpy_from_user.c b/lib/strncpy_from_user.c
index bb2b201..46abaf9 100644
--- a/lib/strncpy_from_user.c
@@ -98926,6 +99592,340 @@ index b543470..d2ddae2 100644
if (!can_dir) {
printk(KERN_INFO "can: failed to create /proc/net/can . "
+diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c
+index 96238ba..de6662b 100644
+--- a/net/ceph/auth_x.c
++++ b/net/ceph/auth_x.c
+@@ -13,8 +13,6 @@
+ #include "auth_x.h"
+ #include "auth_x_protocol.h"
+
+-#define TEMP_TICKET_BUF_LEN 256
+-
+ static void ceph_x_validate_tickets(struct ceph_auth_client *ac, int *pneed);
+
+ static int ceph_x_is_authenticated(struct ceph_auth_client *ac)
+@@ -64,7 +62,7 @@ static int ceph_x_encrypt(struct ceph_crypto_key *secret,
+ }
+
+ static int ceph_x_decrypt(struct ceph_crypto_key *secret,
+- void **p, void *end, void *obuf, size_t olen)
++ void **p, void *end, void **obuf, size_t olen)
+ {
+ struct ceph_x_encrypt_header head;
+ size_t head_len = sizeof(head);
+@@ -75,8 +73,14 @@ static int ceph_x_decrypt(struct ceph_crypto_key *secret,
+ return -EINVAL;
+
+ dout("ceph_x_decrypt len %d\n", len);
+- ret = ceph_decrypt2(secret, &head, &head_len, obuf, &olen,
+- *p, len);
++ if (*obuf == NULL) {
++ *obuf = kmalloc(len, GFP_NOFS);
++ if (!*obuf)
++ return -ENOMEM;
++ olen = len;
++ }
++
++ ret = ceph_decrypt2(secret, &head, &head_len, *obuf, &olen, *p, len);
+ if (ret)
+ return ret;
+ if (head.struct_v != 1 || le64_to_cpu(head.magic) != CEPHX_ENC_MAGIC)
+@@ -129,145 +133,154 @@ static void remove_ticket_handler(struct ceph_auth_client *ac,
+ kfree(th);
+ }
+
++static int process_one_ticket(struct ceph_auth_client *ac,
++ struct ceph_crypto_key *secret,
++ void **p, void *end)
++{
++ struct ceph_x_info *xi = ac->private;
++ int type;
++ u8 tkt_struct_v, blob_struct_v;
++ struct ceph_x_ticket_handler *th;
++ void *dbuf = NULL;
++ void *dp, *dend;
++ int dlen;
++ char is_enc;
++ struct timespec validity;
++ struct ceph_crypto_key old_key;
++ void *ticket_buf = NULL;
++ void *tp, *tpend;
++ struct ceph_timespec new_validity;
++ struct ceph_crypto_key new_session_key;
++ struct ceph_buffer *new_ticket_blob;
++ unsigned long new_expires, new_renew_after;
++ u64 new_secret_id;
++ int ret;
++
++ ceph_decode_need(p, end, sizeof(u32) + 1, bad);
++
++ type = ceph_decode_32(p);
++ dout(" ticket type %d %s\n", type, ceph_entity_type_name(type));
++
++ tkt_struct_v = ceph_decode_8(p);
++ if (tkt_struct_v != 1)
++ goto bad;
++
++ th = get_ticket_handler(ac, type);
++ if (IS_ERR(th)) {
++ ret = PTR_ERR(th);
++ goto out;
++ }
++
++ /* blob for me */
++ dlen = ceph_x_decrypt(secret, p, end, &dbuf, 0);
++ if (dlen <= 0) {
++ ret = dlen;
++ goto out;
++ }
++ dout(" decrypted %d bytes\n", dlen);
++ dp = dbuf;
++ dend = dp + dlen;
++
++ tkt_struct_v = ceph_decode_8(&dp);
++ if (tkt_struct_v != 1)
++ goto bad;
++
++ memcpy(&old_key, &th->session_key, sizeof(old_key));
++ ret = ceph_crypto_key_decode(&new_session_key, &dp, dend);
++ if (ret)
++ goto out;
++
++ ceph_decode_copy(&dp, &new_validity, sizeof(new_validity));
++ ceph_decode_timespec(&validity, &new_validity);
++ new_expires = get_seconds() + validity.tv_sec;
++ new_renew_after = new_expires - (validity.tv_sec / 4);
++ dout(" expires=%lu renew_after=%lu\n", new_expires,
++ new_renew_after);
++
++ /* ticket blob for service */
++ ceph_decode_8_safe(p, end, is_enc, bad);
++ if (is_enc) {
++ /* encrypted */
++ dout(" encrypted ticket\n");
++ dlen = ceph_x_decrypt(&old_key, p, end, &ticket_buf, 0);
++ if (dlen < 0) {
++ ret = dlen;
++ goto out;
++ }
++ tp = ticket_buf;
++ dlen = ceph_decode_32(&tp);
++ } else {
++ /* unencrypted */
++ ceph_decode_32_safe(p, end, dlen, bad);
++ ticket_buf = kmalloc(dlen, GFP_NOFS);
++ if (!ticket_buf) {
++ ret = -ENOMEM;
++ goto out;
++ }
++ tp = ticket_buf;
++ ceph_decode_need(p, end, dlen, bad);
++ ceph_decode_copy(p, ticket_buf, dlen);
++ }
++ tpend = tp + dlen;
++ dout(" ticket blob is %d bytes\n", dlen);
++ ceph_decode_need(&tp, tpend, 1 + sizeof(u64), bad);
++ blob_struct_v = ceph_decode_8(&tp);
++ new_secret_id = ceph_decode_64(&tp);
++ ret = ceph_decode_buffer(&new_ticket_blob, &tp, tpend);
++ if (ret)
++ goto out;
++
++ /* all is well, update our ticket */
++ ceph_crypto_key_destroy(&th->session_key);
++ if (th->ticket_blob)
++ ceph_buffer_put(th->ticket_blob);
++ th->session_key = new_session_key;
++ th->ticket_blob = new_ticket_blob;
++ th->validity = new_validity;
++ th->secret_id = new_secret_id;
++ th->expires = new_expires;
++ th->renew_after = new_renew_after;
++ dout(" got ticket service %d (%s) secret_id %lld len %d\n",
++ type, ceph_entity_type_name(type), th->secret_id,
++ (int)th->ticket_blob->vec.iov_len);
++ xi->have_keys |= th->service;
++
++out:
++ kfree(ticket_buf);
++ kfree(dbuf);
++ return ret;
++
++bad:
++ ret = -EINVAL;
++ goto out;
++}
++
+ static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac,
+ struct ceph_crypto_key *secret,
+ void *buf, void *end)
+ {
+- struct ceph_x_info *xi = ac->private;
+- int num;
+ void *p = buf;
+- int ret;
+- char *dbuf;
+- char *ticket_buf;
+ u8 reply_struct_v;
++ u32 num;
++ int ret;
+
+- dbuf = kmalloc(TEMP_TICKET_BUF_LEN, GFP_NOFS);
+- if (!dbuf)
+- return -ENOMEM;
+-
+- ret = -ENOMEM;
+- ticket_buf = kmalloc(TEMP_TICKET_BUF_LEN, GFP_NOFS);
+- if (!ticket_buf)
+- goto out_dbuf;
+-
+- ceph_decode_need(&p, end, 1 + sizeof(u32), bad);
+- reply_struct_v = ceph_decode_8(&p);
++ ceph_decode_8_safe(&p, end, reply_struct_v, bad);
+ if (reply_struct_v != 1)
+- goto bad;
+- num = ceph_decode_32(&p);
++ return -EINVAL;
++
++ ceph_decode_32_safe(&p, end, num, bad);
+ dout("%d tickets\n", num);
++
+ while (num--) {
+- int type;
+- u8 tkt_struct_v, blob_struct_v;
+- struct ceph_x_ticket_handler *th;
+- void *dp, *dend;
+- int dlen;
+- char is_enc;
+- struct timespec validity;
+- struct ceph_crypto_key old_key;
+- void *tp, *tpend;
+- struct ceph_timespec new_validity;
+- struct ceph_crypto_key new_session_key;
+- struct ceph_buffer *new_ticket_blob;
+- unsigned long new_expires, new_renew_after;
+- u64 new_secret_id;
+-
+- ceph_decode_need(&p, end, sizeof(u32) + 1, bad);
+-
+- type = ceph_decode_32(&p);
+- dout(" ticket type %d %s\n", type, ceph_entity_type_name(type));
+-
+- tkt_struct_v = ceph_decode_8(&p);
+- if (tkt_struct_v != 1)
+- goto bad;
+-
+- th = get_ticket_handler(ac, type);
+- if (IS_ERR(th)) {
+- ret = PTR_ERR(th);
+- goto out;
+- }
+-
+- /* blob for me */
+- dlen = ceph_x_decrypt(secret, &p, end, dbuf,
+- TEMP_TICKET_BUF_LEN);
+- if (dlen <= 0) {
+- ret = dlen;
+- goto out;
+- }
+- dout(" decrypted %d bytes\n", dlen);
+- dend = dbuf + dlen;
+- dp = dbuf;
+-
+- tkt_struct_v = ceph_decode_8(&dp);
+- if (tkt_struct_v != 1)
+- goto bad;
+-
+- memcpy(&old_key, &th->session_key, sizeof(old_key));
+- ret = ceph_crypto_key_decode(&new_session_key, &dp, dend);
++ ret = process_one_ticket(ac, secret, &p, end);
+ if (ret)
+- goto out;
+-
+- ceph_decode_copy(&dp, &new_validity, sizeof(new_validity));
+- ceph_decode_timespec(&validity, &new_validity);
+- new_expires = get_seconds() + validity.tv_sec;
+- new_renew_after = new_expires - (validity.tv_sec / 4);
+- dout(" expires=%lu renew_after=%lu\n", new_expires,
+- new_renew_after);
+-
+- /* ticket blob for service */
+- ceph_decode_8_safe(&p, end, is_enc, bad);
+- tp = ticket_buf;
+- if (is_enc) {
+- /* encrypted */
+- dout(" encrypted ticket\n");
+- dlen = ceph_x_decrypt(&old_key, &p, end, ticket_buf,
+- TEMP_TICKET_BUF_LEN);
+- if (dlen < 0) {
+- ret = dlen;
+- goto out;
+- }
+- dlen = ceph_decode_32(&tp);
+- } else {
+- /* unencrypted */
+- ceph_decode_32_safe(&p, end, dlen, bad);
+- ceph_decode_need(&p, end, dlen, bad);
+- ceph_decode_copy(&p, ticket_buf, dlen);
+- }
+- tpend = tp + dlen;
+- dout(" ticket blob is %d bytes\n", dlen);
+- ceph_decode_need(&tp, tpend, 1 + sizeof(u64), bad);
+- blob_struct_v = ceph_decode_8(&tp);
+- new_secret_id = ceph_decode_64(&tp);
+- ret = ceph_decode_buffer(&new_ticket_blob, &tp, tpend);
+- if (ret)
+- goto out;
+-
+- /* all is well, update our ticket */
+- ceph_crypto_key_destroy(&th->session_key);
+- if (th->ticket_blob)
+- ceph_buffer_put(th->ticket_blob);
+- th->session_key = new_session_key;
+- th->ticket_blob = new_ticket_blob;
+- th->validity = new_validity;
+- th->secret_id = new_secret_id;
+- th->expires = new_expires;
+- th->renew_after = new_renew_after;
+- dout(" got ticket service %d (%s) secret_id %lld len %d\n",
+- type, ceph_entity_type_name(type), th->secret_id,
+- (int)th->ticket_blob->vec.iov_len);
+- xi->have_keys |= th->service;
++ return ret;
+ }
+
+- ret = 0;
+-out:
+- kfree(ticket_buf);
+-out_dbuf:
+- kfree(dbuf);
+- return ret;
++ return 0;
+
+ bad:
+- ret = -EINVAL;
+- goto out;
++ return -EINVAL;
+ }
+
+ static int ceph_x_build_authorizer(struct ceph_auth_client *ac,
+@@ -583,13 +596,14 @@ static int ceph_x_verify_authorizer_reply(struct ceph_auth_client *ac,
+ struct ceph_x_ticket_handler *th;
+ int ret = 0;
+ struct ceph_x_authorize_reply reply;
++ void *preply = &reply;
+ void *p = au->reply_buf;
+ void *end = p + sizeof(au->reply_buf);
+
+ th = get_ticket_handler(ac, au->service);
+ if (IS_ERR(th))
+ return PTR_ERR(th);
+- ret = ceph_x_decrypt(&th->session_key, &p, end, &reply, sizeof(reply));
++ ret = ceph_x_decrypt(&th->session_key, &p, end, &preply, sizeof(reply));
+ if (ret < 0)
+ return ret;
+ if (ret != sizeof(reply))
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index 988721a..947846d 100644
--- a/net/ceph/messenger.c
@@ -98948,6 +99948,26 @@ index 988721a..947846d 100644
s = addr_str[i];
switch (ss->ss_family) {
+diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c
+index 2ac9ef3..dbcbf5a 100644
+--- a/net/ceph/mon_client.c
++++ b/net/ceph/mon_client.c
+@@ -1041,7 +1041,15 @@ static struct ceph_msg *mon_alloc_msg(struct ceph_connection *con,
+ if (!m) {
+ pr_info("alloc_msg unknown type %d\n", type);
+ *skip = 1;
++ } else if (front_len > m->front_alloc_len) {
++ pr_warning("mon_alloc_msg front %d > prealloc %d (%u#%llu)\n",
++ front_len, m->front_alloc_len,
++ (unsigned int)con->peer_name.type,
++ le64_to_cpu(con->peer_name.num));
++ ceph_msg_put(m);
++ m = ceph_msg_new(type, front_len, GFP_NOFS, false);
+ }
++
+ return m;
+ }
+
diff --git a/net/compat.c b/net/compat.c
index cbc1a2a..ab7644e 100644
--- a/net/compat.c
@@ -103634,7 +104654,7 @@ index dfa532f..1dcfb44 100644
}
diff --git a/net/socket.c b/net/socket.c
-index a19ae19..89554dc 100644
+index a19ae19..edb5c03 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -88,6 +88,7 @@
@@ -103818,7 +104838,17 @@ index a19ae19..89554dc 100644
int err, err2;
int fput_needed;
-@@ -2065,7 +2131,7 @@ static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
+@@ -1987,6 +2053,9 @@ static int copy_msghdr_from_user(struct msghdr *kmsg,
+ if (copy_from_user(kmsg, umsg, sizeof(struct msghdr)))
+ return -EFAULT;
+
++ if (kmsg->msg_name == NULL)
++ kmsg->msg_namelen = 0;
++
+ if (kmsg->msg_namelen < 0)
+ return -EINVAL;
+
+@@ -2065,7 +2134,7 @@ static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
* checking falls down on this.
*/
if (copy_from_user(ctl_buf,
@@ -103827,7 +104857,7 @@ index a19ae19..89554dc 100644
ctl_len))
goto out_freectl;
msg_sys->msg_control = ctl_buf;
-@@ -2216,7 +2282,7 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
+@@ -2216,7 +2285,7 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
int err, total_len, len;
/* kernel mode address */
@@ -103836,7 +104866,7 @@ index a19ae19..89554dc 100644
/* user mode address pointers */
struct sockaddr __user *uaddr;
-@@ -2245,7 +2311,7 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
+@@ -2245,7 +2314,7 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
/* Save the user-mode address (verify_iovec will change the
* kernel msghdr to use the kernel address space)
*/
@@ -103845,7 +104875,7 @@ index a19ae19..89554dc 100644
uaddr_len = COMPAT_NAMELEN(msg);
if (MSG_CMSG_COMPAT & flags)
err = verify_compat_iovec(msg_sys, iov, &addr, VERIFY_WRITE);
-@@ -2889,7 +2955,7 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
+@@ -2889,7 +2958,7 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
ifr = compat_alloc_user_space(buf_size);
rxnfc = (void __user *)ifr + ALIGN(sizeof(struct ifreq), 8);
@@ -103854,7 +104884,7 @@ index a19ae19..89554dc 100644
return -EFAULT;
if (put_user(convert_in ? rxnfc : compat_ptr(data),
-@@ -3000,7 +3066,7 @@ static int bond_ioctl(struct net *net, unsigned int cmd,
+@@ -3000,7 +3069,7 @@ static int bond_ioctl(struct net *net, unsigned int cmd,
old_fs = get_fs();
set_fs(KERNEL_DS);
err = dev_ioctl(net, cmd,
@@ -103863,7 +104893,7 @@ index a19ae19..89554dc 100644
set_fs(old_fs);
return err;
-@@ -3093,7 +3159,7 @@ static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
+@@ -3093,7 +3162,7 @@ static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
old_fs = get_fs();
set_fs(KERNEL_DS);
@@ -103872,7 +104902,7 @@ index a19ae19..89554dc 100644
set_fs(old_fs);
if (cmd == SIOCGIFMAP && !err) {
-@@ -3177,7 +3243,7 @@ static int routing_ioctl(struct net *net, struct socket *sock,
+@@ -3177,7 +3246,7 @@ static int routing_ioctl(struct net *net, struct socket *sock,
ret |= get_user(rtdev, &(ur4->rt_dev));
if (rtdev) {
ret |= copy_from_user(devname, compat_ptr(rtdev), 15);
@@ -103881,7 +104911,7 @@ index a19ae19..89554dc 100644
devname[15] = 0;
} else
r4.rt_dev = NULL;
-@@ -3404,8 +3470,8 @@ int kernel_getsockopt(struct socket *sock, int level, int optname,
+@@ -3404,8 +3473,8 @@ int kernel_getsockopt(struct socket *sock, int level, int optname,
int __user *uoptlen;
int err;
@@ -103892,7 +104922,7 @@ index a19ae19..89554dc 100644
set_fs(KERNEL_DS);
if (level == SOL_SOCKET)
-@@ -3425,7 +3491,7 @@ int kernel_setsockopt(struct socket *sock, int level, int optname,
+@@ -3425,7 +3494,7 @@ int kernel_setsockopt(struct socket *sock, int level, int optname,
char __user *uoptval;
int err;
@@ -109542,10 +110572,10 @@ index 0000000..89f256d
+}
diff --git a/tools/gcc/latent_entropy_plugin.c b/tools/gcc/latent_entropy_plugin.c
new file mode 100644
-index 0000000..39d7cc7
+index 0000000..e48b323
--- /dev/null
+++ b/tools/gcc/latent_entropy_plugin.c
-@@ -0,0 +1,462 @@
+@@ -0,0 +1,466 @@
+/*
+ * Copyright 2012-2014 by the PaX Team <pageexec@freemail.hu>
+ * Licensed under the GPL v2
@@ -109574,7 +110604,7 @@ index 0000000..39d7cc7
+static tree latent_entropy_decl;
+
+static struct plugin_info latent_entropy_plugin_info = {
-+ .version = "201403280150",
++ .version = "201409101820",
+ .help = NULL
+};
+
@@ -109750,6 +110780,10 @@ index 0000000..39d7cc7
+ if (TREE_THIS_VOLATILE(current_function_decl))
+ return false;
+
++ // gcc-4.5 doesn't discover some trivial noreturn functions
++ if (EDGE_COUNT(EXIT_BLOCK_PTR_FOR_FN(cfun)->preds) == 0)
++ return false;
++
+ return lookup_attribute("latent_entropy", DECL_ATTRIBUTES(current_function_decl)) != NULL_TREE;
+}
+