diff options
Diffstat (limited to 'main/linux-grsec')
-rw-r--r-- | main/linux-grsec/APKBUILD | 28 | ||||
-rw-r--r-- | main/linux-grsec/grsecurity-2.9.1-3.10.10-201308292131.patch (renamed from main/linux-grsec/grsecurity-2.9.1-3.10.9-201308202015.patch) | 2017 | ||||
-rw-r--r-- | main/linux-grsec/kernelconfig.x86 | 7 | ||||
-rw-r--r-- | main/linux-grsec/kernelconfig.x86_64 | 7 |
4 files changed, 1872 insertions, 187 deletions
diff --git a/main/linux-grsec/APKBUILD b/main/linux-grsec/APKBUILD index e61309b237..0f8e7bede0 100644 --- a/main/linux-grsec/APKBUILD +++ b/main/linux-grsec/APKBUILD @@ -2,7 +2,7 @@ _flavor=grsec pkgname=linux-${_flavor} -pkgver=3.10.9 +pkgver=3.10.10 case $pkgver in *.*.*) _kernver=${pkgver%.*};; *.*) _kernver=${pkgver};; @@ -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-2.9.1-3.10.9-201308202015.patch + grsecurity-2.9.1-3.10.10-201308292131.patch 0001-net-inform-NETDEV_CHANGE-callbacks-which-flags-were-.patch 0002-arp-flush-arp-cache-on-IFF_NOARP-change.patch @@ -149,35 +149,35 @@ dev() { } md5sums="4f25cd5bec5f8d5a7d935b3f2ccb8481 linux-3.10.tar.xz -868d7f5315f95da5e48ed56691a36263 patch-3.10.9.xz -f41e229103719b010213ae403c1b7afa grsecurity-2.9.1-3.10.9-201308202015.patch +d010ef17d3e577fd1bdcb6887f2b9836 patch-3.10.10.xz +506c62f254e15b5e03d78712303a3cdc grsecurity-2.9.1-3.10.10-201308292131.patch a16f11b12381efb3bec79b9bfb329836 0001-net-inform-NETDEV_CHANGE-callbacks-which-flags-were-.patch 656ae7b10dd2f18dbfa1011041d08d60 0002-arp-flush-arp-cache-on-IFF_NOARP-change.patch aa454ffb96428586447775c21449e284 0003-ipv4-properly-refresh-rtable-entries-on-pmtu-redirec.patch 2a12a3717052e878c0cd42aa935bfcf4 0004-ipv4-rate-limit-updating-of-next-hop-exceptions-with.patch 6ce5fed63aad3f1a1ff1b9ba7b741822 0005-ipv4-use-separate-genid-for-next-hop-exceptions.patch 1a5800a2122ba0cc0d06733cb3bb8b8f 0006-ipv4-use-next-hop-exceptions-also-for-input-routes.patch -1a111abaeb381bf47d9e979a85fba2ee kernelconfig.x86 -1312267644d0c729bd7c7af979b29c8d kernelconfig.x86_64" +866e6c4daed45d563829804f8ad50ed9 kernelconfig.x86 +272aaddd0a19a5052208bc25551995a3 kernelconfig.x86_64" sha256sums="df27fa92d27a9c410bfe6c4a89f141638500d7eadcca5cce578954efc2ad3544 linux-3.10.tar.xz -851224c4719e362a8ae6785abd7a8e59aa7200ee82fffbea291003da47a64bf6 patch-3.10.9.xz -a66590964d415c30643b25d50533c960b3dbd2f5c2e408d39f489b3b03ccefe6 grsecurity-2.9.1-3.10.9-201308202015.patch +22cb9a7721bacd40d83c2d630f672e09495ce9d29f896e874ea8669bb577e193 patch-3.10.10.xz +a475f44dacf51c64f482ad79ef6b5ab4774fc9fef2b8450bb8160f987095c4ac grsecurity-2.9.1-3.10.10-201308292131.patch 6af3757ac36a6cd3cda7b0a71b08143726383b19261294a569ad7f4042c72df3 0001-net-inform-NETDEV_CHANGE-callbacks-which-flags-were-.patch dc8e82108615657f1fb9d641efd42255a5761c06edde1b00a41ae0d314d548f0 0002-arp-flush-arp-cache-on-IFF_NOARP-change.patch 0985caa0f3ee8ed0959aeaa4214f5f8057ae8e61d50dcae39194912d31e14892 0003-ipv4-properly-refresh-rtable-entries-on-pmtu-redirec.patch 260fd1807838b68305a96992bf7d3302a2a8ef3a3b08fe079ba9a07e6422f736 0004-ipv4-rate-limit-updating-of-next-hop-exceptions-with.patch ae32bb72afa170e6c3788c564b342763aba5945afacc1e2ebfc096adf50d77a3 0005-ipv4-use-separate-genid-for-next-hop-exceptions.patch fc613ac466610b866b721c41836fd5bfb2d4b75bceb67972dc6369d7f62ff47e 0006-ipv4-use-next-hop-exceptions-also-for-input-routes.patch -1ef74cf3703dd26201970a2d9f043fed7e03ad2540a20f810cec8add93f81ccd kernelconfig.x86 -1c4b4a74d982fdc8d3baddcdaa674ae4b4a3390daba024fca55e85604af74507 kernelconfig.x86_64" +7fd28634998ef1fddafed5f2516e902924245d2464b9e86476bfaa55ccfc3bc3 kernelconfig.x86 +f2843ae4f9b3e3c27f3138ce4b740c2803bdab0c7a910c662d951843803b9554 kernelconfig.x86_64" sha512sums="5fb109fcbd59bf3dffc911b853894f0a84afa75151368f783a1252c5ff60c7a1504de216c0012be446df983e2dea400ad8eeed3ce04f24dc61d0ef76c174dc35 linux-3.10.tar.xz -4e1ba00bd38ce248dc9bb160a4bba5800825c2ca8665134ffd56bbfffbfbe7a6acd58bae7fbb7a5490e22393c13a86c1a7937397710c27ca14bffb40ec0d809a patch-3.10.9.xz -1deda71bdaa5ea1133b2d6bb5c7598d31fa98ac9252ce5eca631412e5cc2be45697bfa7e1ad87a36dfd1530540c21ed528227d7b3ef611624070c9b37faddc2a grsecurity-2.9.1-3.10.9-201308202015.patch +3e87e48d009f05bbaafad55b1f601dc84e6f095b14ec1ad3fe68b37d6722bf47f2482639a7e21b00e8a13f141f3f0e78bdb79e049661eef2aea1c9b93579734b patch-3.10.10.xz +67d25b470d250ff2a4d1c465e4e15ac1205d9005a76d314594da16af3d4d5b2fccb941178730d2f0d75e51b979e30c4f9d0a978d044b57bd3403ce6b341c8a31 grsecurity-2.9.1-3.10.10-201308292131.patch 81e78593288e8b0fd2c03ea9fc1450323887707f087e911f172450a122bc9b591ee83394836789730d951aeec13d0b75a64e1c05f04364abf8f80d883ddc4a02 0001-net-inform-NETDEV_CHANGE-callbacks-which-flags-were-.patch 51ecb15b669f6a82940a13a38939116e003bf5dfd24496771c8279e907b72adcc63d607f0340a2940d757e12ddadb7d45c7af78ae311d284935a6296dbcac00c 0002-arp-flush-arp-cache-on-IFF_NOARP-change.patch 57d0a8bd35d19cf657ded58efe24517d2252aec6984040713ba173a34edb5887ececaa2985076bc6a149eaa57639fd98a042c1c2d226ed4ad8dd5ed0e230717e 0003-ipv4-properly-refresh-rtable-entries-on-pmtu-redirec.patch d2f578ad1d6e1fe52b55863e5bf338ae8201b828a498ec3e42e549c55295d3d1c6c3adfa9e226d711e3486628ed56ab996484e219d79ac4b0c0ec684ebd380aa 0004-ipv4-rate-limit-updating-of-next-hop-exceptions-with.patch 28a33e644bf2faf99c8dd6dbccfe14e140dfdd8824a8fb2d58aa7deb9e572f130d92b6b35ee181084050d82166bdf2e498a451a2a538a67b7ab84204405d2d87 0005-ipv4-use-separate-genid-for-next-hop-exceptions.patch 249140374c19a5599876268ff5b3cda2e136681aee103b4a9fff5d7d346f8e3295a907fb43db0701b8a9fece64c299ad2abac0434259cce6631307ce84090205 0006-ipv4-use-next-hop-exceptions-also-for-input-routes.patch -5d2057cb27362175d85cbe1b79586a3daaa16c1b36baa0bf433b594a85284a02460b28e90ee9dc3f5a8c973a7e8316e0be83099a40a039913e6f1c7036570196 kernelconfig.x86 -89b5fe8a4930ef19deb00e18bb8a4ae4c87105bcf29b7e15c677f7e6a4d2618bb5c378da485aed573b5a2342e0cdff4d0ceae60f2b89cde603988de9f3c36929 kernelconfig.x86_64" +1721542ff111c8ec550323dae6f6174131db180668cbf14f01dc4c76ffbbb479715919a80c35d8c8ac22a6479dd3b42700be6ddc5ef2a8b6a62de811c7ae86df kernelconfig.x86 +d49bf57bd0aae17d762d87d5bf983e48219d71ca44bc0c3120db94d357192c07146a8938cef9d435218e4bb748691ec426387545837be637d47e45cdc4482d71 kernelconfig.x86_64" diff --git a/main/linux-grsec/grsecurity-2.9.1-3.10.9-201308202015.patch b/main/linux-grsec/grsecurity-2.9.1-3.10.10-201308292131.patch index 24d81a08cf..ec95bfd86d 100644 --- a/main/linux-grsec/grsecurity-2.9.1-3.10.9-201308202015.patch +++ b/main/linux-grsec/grsecurity-2.9.1-3.10.10-201308292131.patch @@ -281,7 +281,7 @@ index 2fe6e76..889ee23 100644 pcd. [PARIDE] diff --git a/Makefile b/Makefile -index 4b31d62..ac99d49 100644 +index b119684..13ac256 100644 --- a/Makefile +++ b/Makefile @@ -241,8 +241,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ @@ -1968,7 +1968,7 @@ index 86b8fe3..e25f975 100644 #define L_PTE_DIRTY_HIGH (1 << (55 - 32)) diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h -index 9bcd262..fba731c 100644 +index 9bcd262..1ff999b 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h @@ -30,6 +30,9 @@ @@ -1991,20 +1991,18 @@ index 9bcd262..fba731c 100644 extern void __pte_error(const char *file, int line, pte_t); extern void __pmd_error(const char *file, int line, pmd_t); extern void __pgd_error(const char *file, int line, pgd_t); -@@ -53,6 +59,50 @@ extern void __pgd_error(const char *file, int line, pgd_t); +@@ -53,6 +59,48 @@ extern void __pgd_error(const char *file, int line, pgd_t); #define pmd_ERROR(pmd) __pmd_error(__FILE__, __LINE__, pmd) #define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd) +#define __HAVE_ARCH_PAX_OPEN_KERNEL +#define __HAVE_ARCH_PAX_CLOSE_KERNEL + -+#ifdef CONFIG_PAX_KERNEXEC ++#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF) +#include <asm/domain.h> +#include <linux/thread_info.h> +#include <linux/preempt.h> -+#endif + -+#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF) +static inline int test_domain(int domain, int domaintype) +{ + return ((current_thread_info()->cpu_domain) & domain_val(domain, 3)) == domain_val(domain, domaintype); @@ -2042,7 +2040,7 @@ index 9bcd262..fba731c 100644 /* * This is the lowest virtual address we can permit any user space * mapping to be mapped at. This is particularly important for -@@ -72,8 +122,8 @@ extern void __pgd_error(const char *file, int line, pgd_t); +@@ -72,8 +120,8 @@ extern void __pgd_error(const char *file, int line, pgd_t); /* * The pgprot_* and protection_map entries will be fixed up in runtime * to include the cachable and bufferable bits based on memory policy, @@ -2053,7 +2051,7 @@ index 9bcd262..fba731c 100644 */ #define _L_PTE_DEFAULT L_PTE_PRESENT | L_PTE_YOUNG -@@ -257,7 +307,7 @@ static inline pte_t pte_mkspecial(pte_t pte) { return pte; } +@@ -257,7 +305,7 @@ static inline pte_t pte_mkspecial(pte_t pte) { return pte; } static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) { const pteval_t mask = L_PTE_XN | L_PTE_RDONLY | L_PTE_USER | @@ -3634,7 +3632,7 @@ index cad3ca86..1d79e0f 100644 extern void ux500_cpu_die(unsigned int cpu); diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig -index 2950082..d0f0782 100644 +index 08c9fe9..191320c 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -436,7 +436,7 @@ config CPU_32v5 @@ -3662,8 +3660,8 @@ index 2950082..d0f0782 100644 help Warning: disabling this option may break user programs. -@@ -790,7 +792,7 @@ config KUSER_HELPERS - run on ARMv4 through to ARMv7 without modification. +@@ -792,7 +794,7 @@ config KUSER_HELPERS + See Documentation/arm/kernel_user_helpers.txt for details. However, the fixed address nature of these helpers can be used - by ROP (return orientated programming) authors when creating @@ -3737,7 +3735,7 @@ index 6f4585b..7b6f52b 100644 goto fault; \ } while (0) diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c -index 5dbf13f..ee1ec24 100644 +index 5dbf13f..a2d1876 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -25,6 +25,7 @@ @@ -3840,7 +3838,7 @@ index 5dbf13f..ee1ec24 100644 printk(KERN_ALERT "Unhandled fault: %s (0x%03x) at 0x%08lx\n", inf->name, fsr, addr); -@@ -569,15 +631,67 @@ hook_ifault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs * +@@ -569,15 +631,68 @@ hook_ifault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs * ifsr_info[nr].name = name; } @@ -3852,18 +3850,19 @@ index 5dbf13f..ee1ec24 100644 { const struct fsr_info *inf = ifsr_info + fsr_fs(ifsr); struct siginfo info; - ++ unsigned long pc = instruction_pointer(regs); ++ + if (user_mode(regs)) { + unsigned long sigpage = current->mm->context.sigpage; + -+ if (sigpage <= addr && addr < sigpage + 7*4) { -+ if (addr < sigpage + 3*4) ++ if (sigpage <= pc && pc < sigpage + 7*4) { ++ if (pc < sigpage + 3*4) + sys_sigreturn(regs); + else + sys_rt_sigreturn(regs); + return; + } -+ if (addr == 0xffff0fe0UL) { ++ if (pc == 0xffff0fe0UL) { + /* + * PaX: __kuser_get_tls emulation + */ @@ -3878,11 +3877,11 @@ index 5dbf13f..ee1ec24 100644 + if (current->signal->curr_ip) + printk(KERN_ERR "PAX: From %pI4: %s:%d, uid/euid: %u/%u, attempted to execute %s memory at %08lx\n", ¤t->signal->curr_ip, current->comm, task_pid_nr(current), + from_kuid_munged(&init_user_ns, current_uid()), from_kuid_munged(&init_user_ns, current_euid()), -+ addr >= TASK_SIZE ? "non-executable kernel" : "userland", addr); ++ pc >= TASK_SIZE ? "non-executable kernel" : "userland", pc); + else + printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to execute %s memory at %08lx\n", current->comm, task_pid_nr(current), + from_kuid_munged(&init_user_ns, current_uid()), from_kuid_munged(&init_user_ns, current_euid()), -+ addr >= TASK_SIZE ? "non-executable kernel" : "userland", addr); ++ pc >= TASK_SIZE ? "non-executable kernel" : "userland", pc); + goto die; + } +#endif @@ -3891,7 +3890,7 @@ index 5dbf13f..ee1ec24 100644 + if (fsr_fs(ifsr) == FAULT_CODE_DEBUG) { + unsigned int bkpt; + -+ if (!probe_kernel_address((unsigned int *)addr, bkpt) && bkpt == 0xe12f1073) { ++ if (!probe_kernel_address((unsigned int *)pc, bkpt) && cpu_to_le32(bkpt) == 0xe12f1073) { + current->thread.error_code = ifsr; + current->thread.trap_no = 0; + pax_report_refcount_overflow(regs); @@ -3900,7 +3899,7 @@ index 5dbf13f..ee1ec24 100644 + } + } +#endif -+ + if (!inf->fn(addr, ifsr | FSR_LNX_PF, regs)) return; @@ -5347,10 +5346,10 @@ index 4efe96a..60e8699 100644 #define SMP_CACHE_BYTES L1_CACHE_BYTES diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h -index 08b6079..eb272cf 100644 +index 08b6079..e94e6da 100644 --- a/arch/mips/include/asm/atomic.h +++ b/arch/mips/include/asm/atomic.h -@@ -21,6 +21,10 @@ +@@ -21,15 +21,39 @@ #include <asm/cmpxchg.h> #include <asm/war.h> @@ -5360,24 +5359,887 @@ index 08b6079..eb272cf 100644 + #define ATOMIC_INIT(i) { (i) } ++#ifdef CONFIG_64BIT ++#define _ASM_EXTABLE(from, to) \ ++" .section __ex_table,\"a\"\n" \ ++" .dword " #from ", " #to"\n" \ ++" .previous\n" ++#else ++#define _ASM_EXTABLE(from, to) \ ++" .section __ex_table,\"a\"\n" \ ++" .word " #from ", " #to"\n" \ ++" .previous\n" ++#endif ++ /* -@@ -759,6 +763,16 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) + * atomic_read - read atomic variable + * @v: pointer of type atomic_t + * + * Atomically reads the value of @v. */ - #define atomic64_add_negative(i, v) (atomic64_add_return(i, (v)) < 0) +-#define atomic_read(v) (*(volatile int *)&(v)->counter) ++static inline int atomic_read(const atomic_t *v) ++{ ++ return (*(volatile const int *) &v->counter); ++} ++ ++static inline int atomic_read_unchecked(const atomic_unchecked_t *v) ++{ ++ return (*(volatile const int *) &v->counter); ++} -+#define atomic64_read_unchecked(v) atomic64_read(v) -+#define atomic64_set_unchecked(v, i) atomic64_set((v), (i)) -+#define atomic64_add_unchecked(a, v) atomic64_add((a), (v)) -+#define atomic64_add_return_unchecked(a, v) atomic64_add_return((a), (v)) -+#define atomic64_sub_unchecked(a, v) atomic64_sub((a), (v)) -+#define atomic64_inc_unchecked(v) atomic64_inc(v) -+#define atomic64_inc_return_unchecked(v) atomic64_inc_return(v) -+#define atomic64_dec_unchecked(v) atomic64_dec(v) -+#define atomic64_cmpxchg_unchecked(v, o, n) atomic64_cmpxchg((v), (o), (n)) + /* + * atomic_set - set atomic variable +@@ -38,7 +62,15 @@ + * + * Atomically sets the value of @v to @i. + */ +-#define atomic_set(v, i) ((v)->counter = (i)) ++static inline void atomic_set(atomic_t *v, int i) ++{ ++ v->counter = i; ++} + - #endif /* CONFIG_64BIT */ ++static inline void atomic_set_unchecked(atomic_unchecked_t *v, int i) ++{ ++ v->counter = i; ++} + + /* + * atomic_add - add integer to atomic variable +@@ -47,7 +79,67 @@ + * + * Atomically adds @i to @v. + */ +-static __inline__ void atomic_add(int i, atomic_t * v) ++static __inline__ void atomic_add(int i, atomic_t *v) ++{ ++ int temp; ++ ++ if (kernel_uses_llsc && R10000_LLSC_WAR) { ++ __asm__ __volatile__( ++ " .set mips3 \n" ++ "1: ll %0, %1 # atomic_add \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ /* Exception on overflow. */ ++ "2: add %0, %2 \n" ++#else ++ " addu %0, %2 \n" ++#endif ++ " sc %0, %1 \n" ++ " beqzl %0, 1b \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ "3: \n" ++ _ASM_EXTABLE(2b, 3b) ++#endif ++ " .set mips0 \n" ++ : "=&r" (temp), "+m" (v->counter) ++ : "Ir" (i)); ++ } else if (kernel_uses_llsc) { ++ __asm__ __volatile__( ++ " .set mips3 \n" ++ "1: ll %0, %1 # atomic_add \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ /* Exception on overflow. */ ++ "2: add %0, %2 \n" ++#else ++ " addu %0, %2 \n" ++#endif ++ " sc %0, %1 \n" ++ " beqz %0, 1b \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ "3: \n" ++ _ASM_EXTABLE(2b, 3b) ++#endif ++ " .set mips0 \n" ++ : "=&r" (temp), "+m" (v->counter) ++ : "Ir" (i)); ++ } else { ++ unsigned long flags; ++ ++ raw_local_irq_save(flags); ++ __asm__ __volatile__( ++#ifdef CONFIG_PAX_REFCOUNT ++ /* Exception on overflow. */ ++ "1: add %0, %1 \n" ++ "2: \n" ++ _ASM_EXTABLE(1b, 2b) ++#else ++ " addu %0, %1 \n" ++#endif ++ : "+r" (v->counter) : "Ir" (i)); ++ raw_local_irq_restore(flags); ++ } ++} ++ ++static __inline__ void atomic_add_unchecked(int i, atomic_unchecked_t *v) + { + if (kernel_uses_llsc && R10000_LLSC_WAR) { + int temp; +@@ -90,7 +182,67 @@ static __inline__ void atomic_add(int i, atomic_t * v) + * + * Atomically subtracts @i from @v. + */ +-static __inline__ void atomic_sub(int i, atomic_t * v) ++static __inline__ void atomic_sub(int i, atomic_t *v) ++{ ++ int temp; ++ ++ if (kernel_uses_llsc && R10000_LLSC_WAR) { ++ __asm__ __volatile__( ++ " .set mips3 \n" ++ "1: ll %0, %1 # atomic64_sub \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ /* Exception on overflow. */ ++ "2: sub %0, %2 \n" ++#else ++ " subu %0, %2 \n" ++#endif ++ " sc %0, %1 \n" ++ " beqzl %0, 1b \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ "3: \n" ++ _ASM_EXTABLE(2b, 3b) ++#endif ++ " .set mips0 \n" ++ : "=&r" (temp), "+m" (v->counter) ++ : "Ir" (i)); ++ } else if (kernel_uses_llsc) { ++ __asm__ __volatile__( ++ " .set mips3 \n" ++ "1: ll %0, %1 # atomic64_sub \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ /* Exception on overflow. */ ++ "2: sub %0, %2 \n" ++#else ++ " subu %0, %2 \n" ++#endif ++ " sc %0, %1 \n" ++ " beqz %0, 1b \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ "3: \n" ++ _ASM_EXTABLE(2b, 3b) ++#endif ++ " .set mips0 \n" ++ : "=&r" (temp), "+m" (v->counter) ++ : "Ir" (i)); ++ } else { ++ unsigned long flags; ++ ++ raw_local_irq_save(flags); ++ __asm__ __volatile__( ++#ifdef CONFIG_PAX_REFCOUNT ++ /* Exception on overflow. */ ++ "1: sub %0, %1 \n" ++ "2: \n" ++ _ASM_EXTABLE(1b, 2b) ++#else ++ " subu %0, %1 \n" ++#endif ++ : "+r" (v->counter) : "Ir" (i)); ++ raw_local_irq_restore(flags); ++ } ++} ++ ++static __inline__ void atomic_sub_unchecked(long i, atomic_unchecked_t *v) + { + if (kernel_uses_llsc && R10000_LLSC_WAR) { + int temp; +@@ -129,7 +281,93 @@ static __inline__ void atomic_sub(int i, atomic_t * v) + /* + * Same as above, but return the result value + */ +-static __inline__ int atomic_add_return(int i, atomic_t * v) ++static __inline__ int atomic_add_return(int i, atomic_t *v) ++{ ++ int result; ++ int temp; ++ ++ smp_mb__before_llsc(); ++ ++ if (kernel_uses_llsc && R10000_LLSC_WAR) { ++ __asm__ __volatile__( ++ " .set mips3 \n" ++ "1: ll %1, %2 # atomic_add_return \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ "2: add %0, %1, %3 \n" ++#else ++ " addu %0, %1, %3 \n" ++#endif ++ " sc %0, %2 \n" ++ " beqzl %0, 1b \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ " b 4f \n" ++ " .set noreorder \n" ++ "3: b 5f \n" ++ " move %0, %1 \n" ++ " .set reorder \n" ++ _ASM_EXTABLE(2b, 3b) ++#endif ++ "4: addu %0, %1, %3 \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ "5: \n" ++#endif ++ " .set mips0 \n" ++ : "=&r" (result), "=&r" (temp), "+m" (v->counter) ++ : "Ir" (i)); ++ } else if (kernel_uses_llsc) { ++ __asm__ __volatile__( ++ " .set mips3 \n" ++ "1: ll %1, %2 # atomic_add_return \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ "2: add %0, %1, %3 \n" ++#else ++ " addu %0, %1, %3 \n" ++#endif ++ " sc %0, %2 \n" ++ " bnez %0, 4f \n" ++ " b 1b \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ " .set noreorder \n" ++ "3: b 5f \n" ++ " move %0, %1 \n" ++ " .set reorder \n" ++ _ASM_EXTABLE(2b, 3b) ++#endif ++ "4: addu %0, %1, %3 \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ "5: \n" ++#endif ++ " .set mips0 \n" ++ : "=&r" (result), "=&r" (temp), "+m" (v->counter) ++ : "Ir" (i)); ++ } else { ++ unsigned long flags; ++ ++ raw_local_irq_save(flags); ++ __asm__ __volatile__( ++ " lw %0, %1 \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ /* Exception on overflow. */ ++ "1: add %0, %2 \n" ++#else ++ " addu %0, %2 \n" ++#endif ++ " sw %0, %1 \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ /* Note: Dest reg is not modified on overflow */ ++ "2: \n" ++ _ASM_EXTABLE(1b, 2b) ++#endif ++ : "=&r" (result), "+m" (v->counter) : "Ir" (i)); ++ raw_local_irq_restore(flags); ++ } ++ ++ smp_llsc_mb(); ++ ++ return result; ++} ++ ++static __inline__ int atomic_add_return_unchecked(int i, atomic_unchecked_t *v) + { + int result; + +@@ -178,7 +416,93 @@ static __inline__ int atomic_add_return(int i, atomic_t * v) + return result; + } + +-static __inline__ int atomic_sub_return(int i, atomic_t * v) ++static __inline__ int atomic_sub_return(int i, atomic_t *v) ++{ ++ int result; ++ int temp; ++ ++ smp_mb__before_llsc(); ++ ++ if (kernel_uses_llsc && R10000_LLSC_WAR) { ++ __asm__ __volatile__( ++ " .set mips3 \n" ++ "1: ll %1, %2 # atomic_sub_return \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ "2: sub %0, %1, %3 \n" ++#else ++ " subu %0, %1, %3 \n" ++#endif ++ " sc %0, %2 \n" ++ " beqzl %0, 1b \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ " b 4f \n" ++ " .set noreorder \n" ++ "3: b 5f \n" ++ " move %0, %1 \n" ++ " .set reorder \n" ++ _ASM_EXTABLE(2b, 3b) ++#endif ++ "4: subu %0, %1, %3 \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ "5: \n" ++#endif ++ " .set mips0 \n" ++ : "=&r" (result), "=&r" (temp), "=m" (v->counter) ++ : "Ir" (i), "m" (v->counter) ++ : "memory"); ++ } else if (kernel_uses_llsc) { ++ __asm__ __volatile__( ++ " .set mips3 \n" ++ "1: ll %1, %2 # atomic_sub_return \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ "2: sub %0, %1, %3 \n" ++#else ++ " subu %0, %1, %3 \n" ++#endif ++ " sc %0, %2 \n" ++ " bnez %0, 4f \n" ++ " b 1b \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ " .set noreorder \n" ++ "3: b 5f \n" ++ " move %0, %1 \n" ++ " .set reorder \n" ++ _ASM_EXTABLE(2b, 3b) ++#endif ++ "4: subu %0, %1, %3 \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ "5: \n" ++#endif ++ " .set mips0 \n" ++ : "=&r" (result), "=&r" (temp), "+m" (v->counter) ++ : "Ir" (i)); ++ } else { ++ unsigned long flags; ++ ++ raw_local_irq_save(flags); ++ __asm__ __volatile__( ++ " lw %0, %1 \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ /* Exception on overflow. */ ++ "1: sub %0, %2 \n" ++#else ++ " subu %0, %2 \n" ++#endif ++ " sw %0, %1 \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ /* Note: Dest reg is not modified on overflow */ ++ "2: \n" ++ _ASM_EXTABLE(1b, 2b) ++#endif ++ : "=&r" (result), "+m" (v->counter) : "Ir" (i)); ++ raw_local_irq_restore(flags); ++ } ++ ++ smp_llsc_mb(); ++ ++ return result; ++} ++static __inline__ int atomic_sub_return_unchecked(int i, atomic_unchecked_t *v) + { + int result; + +@@ -238,7 +562,7 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v) + * Atomically test @v and subtract @i if @v is greater or equal than @i. + * The function returns the old value of @v minus @i. + */ +-static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) ++static __inline__ int atomic_sub_if_positive(int i, atomic_t *v) + { + int result; + +@@ -295,8 +619,26 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) + return result; + } + +-#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n))) +-#define atomic_xchg(v, new) (xchg(&((v)->counter), (new))) ++static inline int atomic_cmpxchg(atomic_t *v, int old, int new) ++{ ++ return cmpxchg(&v->counter, old, new); ++} ++ ++static inline int atomic_cmpxchg_unchecked(atomic_unchecked_t *v, int old, ++ int new) ++{ ++ return cmpxchg(&(v->counter), old, new); ++} ++ ++static inline int atomic_xchg(atomic_t *v, int new) ++{ ++ return xchg(&v->counter, new); ++} ++ ++static inline int atomic_xchg_unchecked(atomic_unchecked_t *v, int new) ++{ ++ return xchg(&(v->counter), new); ++} + + /** + * __atomic_add_unless - add unless the number is a given value +@@ -324,6 +666,7 @@ 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)) ++#define atomic_inc_return_unchecked(v) atomic_add_return_unchecked(1, (v)) + + /* + * atomic_sub_and_test - subtract value from variable and test result +@@ -345,6 +688,7 @@ 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) ++#define atomic_inc_and_test_unchecked(v) (atomic_add_return_unchecked(1, (v)) == 0) /* + * atomic_dec_and_test - decrement by 1 and test +@@ -369,6 +713,7 @@ 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)) ++#define atomic_inc_unchecked(v) atomic_add_unchecked(1, (v)) + + /* + * atomic_dec - decrement and test +@@ -377,6 +722,7 @@ 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)) ++#define atomic_dec_unchecked(v) atomic_sub_return_unchecked(1, (v)) + + /* + * atomic_add_negative - add and test if negative +@@ -398,14 +744,30 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) + * @v: pointer of type atomic64_t + * + */ +-#define atomic64_read(v) (*(volatile long *)&(v)->counter) ++static inline long atomic64_read(const atomic64_t *v) ++{ ++ return (*(volatile const long *) &v->counter); ++} ++ ++static inline long atomic64_read_unchecked(const atomic64_unchecked_t *v) ++{ ++ return (*(volatile const long *) &v->counter); ++} + + /* + * atomic64_set - set atomic variable + * @v: pointer of type atomic64_t + * @i: required value + */ +-#define atomic64_set(v, i) ((v)->counter = (i)) ++static inline void atomic64_set(atomic64_t *v, long i) ++{ ++ v->counter = i; ++} ++ ++static inline void atomic64_set_unchecked(atomic64_unchecked_t *v, long i) ++{ ++ v->counter = i; ++} + + /* + * atomic64_add - add integer to atomic variable +@@ -414,7 +776,66 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) + * + * Atomically adds @i to @v. + */ +-static __inline__ void atomic64_add(long i, atomic64_t * v) ++static __inline__ void atomic64_add(long i, atomic64_t *v) ++{ ++ long temp; ++ ++ if (kernel_uses_llsc && R10000_LLSC_WAR) { ++ __asm__ __volatile__( ++ " .set mips3 \n" ++ "1: lld %0, %1 # atomic64_add \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ /* Exception on overflow. */ ++ "2: dadd %0, %2 \n" ++#else ++ " daddu %0, %2 \n" ++#endif ++ " scd %0, %1 \n" ++ " beqzl %0, 1b \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ "3: \n" ++ _ASM_EXTABLE(2b, 3b) ++#endif ++ " .set mips0 \n" ++ : "=&r" (temp), "+m" (v->counter) ++ : "Ir" (i)); ++ } else if (kernel_uses_llsc) { ++ __asm__ __volatile__( ++ " .set mips3 \n" ++ "1: lld %0, %1 # atomic64_add \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ /* Exception on overflow. */ ++ "2: dadd %0, %2 \n" ++#else ++ " daddu %0, %2 \n" ++#endif ++ " scd %0, %1 \n" ++ " beqz %0, 1b \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ "3: \n" ++ _ASM_EXTABLE(2b, 3b) ++#endif ++ " .set mips0 \n" ++ : "=&r" (temp), "+m" (v->counter) ++ : "Ir" (i)); ++ } else { ++ unsigned long flags; ++ ++ raw_local_irq_save(flags); ++ __asm__ __volatile__( ++#ifdef CONFIG_PAX_REFCOUNT ++ /* Exception on overflow. */ ++ "1: dadd %0, %1 \n" ++ "2: \n" ++ _ASM_EXTABLE(1b, 2b) ++#else ++ " daddu %0, %1 \n" ++#endif ++ : "+r" (v->counter) : "Ir" (i)); ++ raw_local_irq_restore(flags); ++ } ++} ++static __inline__ void atomic64_add_unchecked(long i, atomic64_unchecked_t *v) + { + if (kernel_uses_llsc && R10000_LLSC_WAR) { + long temp; +@@ -457,7 +878,67 @@ static __inline__ void atomic64_add(long i, atomic64_t * v) + * + * Atomically subtracts @i from @v. + */ +-static __inline__ void atomic64_sub(long i, atomic64_t * v) ++static __inline__ void atomic64_sub(long i, atomic64_t *v) ++{ ++ long temp; ++ ++ if (kernel_uses_llsc && R10000_LLSC_WAR) { ++ __asm__ __volatile__( ++ " .set mips3 \n" ++ "1: lld %0, %1 # atomic64_sub \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ /* Exception on overflow. */ ++ "2: dsub %0, %2 \n" ++#else ++ " dsubu %0, %2 \n" ++#endif ++ " scd %0, %1 \n" ++ " beqzl %0, 1b \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ "3: \n" ++ _ASM_EXTABLE(2b, 3b) ++#endif ++ " .set mips0 \n" ++ : "=&r" (temp), "+m" (v->counter) ++ : "Ir" (i)); ++ } else if (kernel_uses_llsc) { ++ __asm__ __volatile__( ++ " .set mips3 \n" ++ "1: lld %0, %1 # atomic64_sub \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ /* Exception on overflow. */ ++ "2: dsub %0, %2 \n" ++#else ++ " dsubu %0, %2 \n" ++#endif ++ " scd %0, %1 \n" ++ " beqz %0, 1b \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ "3: \n" ++ _ASM_EXTABLE(2b, 3b) ++#endif ++ " .set mips0 \n" ++ : "=&r" (temp), "+m" (v->counter) ++ : "Ir" (i)); ++ } else { ++ unsigned long flags; ++ ++ raw_local_irq_save(flags); ++ __asm__ __volatile__( ++#ifdef CONFIG_PAX_REFCOUNT ++ /* Exception on overflow. */ ++ "1: dsub %0, %1 \n" ++ "2: \n" ++ _ASM_EXTABLE(1b, 2b) ++#else ++ " dsubu %0, %1 \n" ++#endif ++ : "+r" (v->counter) : "Ir" (i)); ++ raw_local_irq_restore(flags); ++ } ++} ++ ++static __inline__ void atomic64_sub_unchecked(long i, atomic64_unchecked_t *v) + { + if (kernel_uses_llsc && R10000_LLSC_WAR) { + long temp; +@@ -496,7 +977,93 @@ static __inline__ void atomic64_sub(long i, atomic64_t * v) + /* + * Same as above, but return the result value + */ +-static __inline__ long atomic64_add_return(long i, atomic64_t * v) ++static __inline__ long atomic64_add_return(long i, atomic64_t *v) ++{ ++ long result; ++ long temp; ++ ++ smp_mb__before_llsc(); ++ ++ if (kernel_uses_llsc && R10000_LLSC_WAR) { ++ __asm__ __volatile__( ++ " .set mips3 \n" ++ "1: lld %1, %2 # atomic64_add_return \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ "2: dadd %0, %1, %3 \n" ++#else ++ " daddu %0, %1, %3 \n" ++#endif ++ " scd %0, %2 \n" ++ " beqzl %0, 1b \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ " b 4f \n" ++ " .set noreorder \n" ++ "3: b 5f \n" ++ " move %0, %1 \n" ++ " .set reorder \n" ++ _ASM_EXTABLE(2b, 3b) ++#endif ++ "4: daddu %0, %1, %3 \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ "5: \n" ++#endif ++ " .set mips0 \n" ++ : "=&r" (result), "=&r" (temp), "+m" (v->counter) ++ : "Ir" (i)); ++ } else if (kernel_uses_llsc) { ++ __asm__ __volatile__( ++ " .set mips3 \n" ++ "1: lld %1, %2 # atomic64_add_return \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ "2: dadd %0, %1, %3 \n" ++#else ++ " daddu %0, %1, %3 \n" ++#endif ++ " scd %0, %2 \n" ++ " bnez %0, 4f \n" ++ " b 1b \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ " .set noreorder \n" ++ "3: b 5f \n" ++ " move %0, %1 \n" ++ " .set reorder \n" ++ _ASM_EXTABLE(2b, 3b) ++#endif ++ "4: daddu %0, %1, %3 \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ "5: \n" ++#endif ++ " .set mips0 \n" ++ : "=&r" (result), "=&r" (temp), "=m" (v->counter) ++ : "Ir" (i), "m" (v->counter) ++ : "memory"); ++ } else { ++ unsigned long flags; ++ ++ raw_local_irq_save(flags); ++ __asm__ __volatile__( ++ " ld %0, %1 \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ /* Exception on overflow. */ ++ "1: dadd %0, %2 \n" ++#else ++ " daddu %0, %2 \n" ++#endif ++ " sd %0, %1 \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ /* Note: Dest reg is not modified on overflow */ ++ "2: \n" ++ _ASM_EXTABLE(1b, 2b) ++#endif ++ : "=&r" (result), "+m" (v->counter) : "Ir" (i)); ++ raw_local_irq_restore(flags); ++ } ++ ++ smp_llsc_mb(); ++ ++ return result; ++} ++static __inline__ long atomic64_add_return_unchecked(long i, atomic64_unchecked_t *v) + { + long result; + +@@ -546,7 +1113,97 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v) + return result; + } + +-static __inline__ long atomic64_sub_return(long i, atomic64_t * v) ++static __inline__ long atomic64_sub_return(long i, atomic64_t *v) ++{ ++ long result; ++ long temp; ++ ++ smp_mb__before_llsc(); ++ ++ if (kernel_uses_llsc && R10000_LLSC_WAR) { ++ long temp; ++ ++ __asm__ __volatile__( ++ " .set mips3 \n" ++ "1: lld %1, %2 # atomic64_sub_return \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ "2: dsub %0, %1, %3 \n" ++#else ++ " dsubu %0, %1, %3 \n" ++#endif ++ " scd %0, %2 \n" ++ " beqzl %0, 1b \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ " b 4f \n" ++ " .set noreorder \n" ++ "3: b 5f \n" ++ " move %0, %1 \n" ++ " .set reorder \n" ++ _ASM_EXTABLE(2b, 3b) ++#endif ++ "4: dsubu %0, %1, %3 \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ "5: \n" ++#endif ++ " .set mips0 \n" ++ : "=&r" (result), "=&r" (temp), "=m" (v->counter) ++ : "Ir" (i), "m" (v->counter) ++ : "memory"); ++ } else if (kernel_uses_llsc) { ++ __asm__ __volatile__( ++ " .set mips3 \n" ++ "1: lld %1, %2 # atomic64_sub_return \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ "2: dsub %0, %1, %3 \n" ++#else ++ " dsubu %0, %1, %3 \n" ++#endif ++ " scd %0, %2 \n" ++ " bnez %0, 4f \n" ++ " b 1b \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ " .set noreorder \n" ++ "3: b 5f \n" ++ " move %0, %1 \n" ++ " .set reorder \n" ++ _ASM_EXTABLE(2b, 3b) ++#endif ++ "4: dsubu %0, %1, %3 \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ "5: \n" ++#endif ++ " .set mips0 \n" ++ : "=&r" (result), "=&r" (temp), "=m" (v->counter) ++ : "Ir" (i), "m" (v->counter) ++ : "memory"); ++ } else { ++ unsigned long flags; ++ ++ raw_local_irq_save(flags); ++ __asm__ __volatile__( ++ " ld %0, %1 \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ /* Exception on overflow. */ ++ "1: dsub %0, %2 \n" ++#else ++ " dsubu %0, %2 \n" ++#endif ++ " sd %0, %1 \n" ++#ifdef CONFIG_PAX_REFCOUNT ++ /* Note: Dest reg is not modified on overflow */ ++ "2: \n" ++ _ASM_EXTABLE(1b, 2b) ++#endif ++ : "=&r" (result), "+m" (v->counter) : "Ir" (i)); ++ raw_local_irq_restore(flags); ++ } ++ ++ smp_llsc_mb(); ++ ++ return result; ++} ++ ++static __inline__ long atomic64_sub_return_unchecked(long i, atomic64_unchecked_t *v) + { + long result; + +@@ -605,7 +1262,7 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v) + * Atomically test @v and subtract @i if @v is greater or equal than @i. + * The function returns the old value of @v minus @i. + */ +-static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v) ++static __inline__ long atomic64_sub_if_positive(long i, atomic64_t *v) + { + long result; + +@@ -662,9 +1319,26 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v) + return result; + } + +-#define atomic64_cmpxchg(v, o, n) \ +- ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n))) +-#define atomic64_xchg(v, new) (xchg(&((v)->counter), (new))) ++static inline long atomic64_cmpxchg(atomic64_t *v, long old, long new) ++{ ++ return cmpxchg(&v->counter, old, new); ++} ++ ++static inline long atomic64_cmpxchg_unchecked(atomic64_unchecked_t *v, long old, ++ long new) ++{ ++ return cmpxchg(&(v->counter), old, new); ++} ++ ++static inline long atomic64_xchg(atomic64_t *v, long new) ++{ ++ return xchg(&v->counter, new); ++} ++ ++static inline long atomic64_xchg_unchecked(atomic64_unchecked_t *v, long new) ++{ ++ return xchg(&(v->counter), new); ++} + + /** + * atomic64_add_unless - add unless the number is a given value +@@ -694,6 +1368,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)) ++#define atomic64_inc_return_unchecked(v) atomic64_add_return_unchecked(1, (v)) + + /* + * atomic64_sub_and_test - subtract value from variable and test result +@@ -715,6 +1390,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) ++#define atomic64_inc_and_test_unchecked(v) atomic64_add_return_unchecked(1, (v)) == 0) + + /* + * atomic64_dec_and_test - decrement by 1 and test +@@ -739,6 +1415,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)) ++#define atomic64_inc_unchecked(v) atomic64_add_unchecked(1, (v)) + + /* + * atomic64_dec - decrement and test +@@ -747,6 +1424,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)) ++#define atomic64_dec_unchecked(v) atomic64_sub_unchecked(1, (v)) + + /* + * atomic64_add_negative - add and test if negative diff --git a/arch/mips/include/asm/cache.h b/arch/mips/include/asm/cache.h index b4db69f..8f3b093 100644 --- a/arch/mips/include/asm/cache.h @@ -5721,6 +6583,29 @@ index 74f485d..47d2c38 100644 LONG_L t0, TI_FLAGS($28) # syscall tracing enabled? and t0, t1, t0 bnez t0, trace_a_syscall +diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c +index a75ae40..0d0f56a 100644 +--- a/arch/mips/kernel/traps.c ++++ b/arch/mips/kernel/traps.c +@@ -675,7 +675,17 @@ asmlinkage void do_ov(struct pt_regs *regs) + { + siginfo_t info; + +- die_if_kernel("Integer overflow", regs); ++ if (unlikely(!user_mode(regs))) { ++ ++#ifdef CONFIG_PAX_REFCOUNT ++ if (fixup_exception(regs)) { ++ pax_report_refcount_overflow(regs); ++ return; ++ } ++#endif ++ ++ die("Integer overflow", regs); ++ } + + info.si_code = FPE_INTOVF; + info.si_signo = SIGFPE; diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c index 0fead53..eeb00a6 100644 --- a/arch/mips/mm/fault.c @@ -16806,15 +17691,17 @@ index a1df6e8..e002940 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 50a7fc0..7c437a7 100644 +index 50a7fc0..45844c0 100644 --- a/arch/x86/include/asm/tlbflush.h +++ b/arch/x86/include/asm/tlbflush.h -@@ -17,18 +17,40 @@ +@@ -17,18 +17,44 @@ static inline void __native_flush_tlb(void) { + if (static_cpu_has(X86_FEATURE_INVPCID)) { + unsigned long descriptor[2]; ++ ++ descriptor[0] = PCID_KERNEL; + asm volatile(__ASM_INVPCID : : "d"(&descriptor), "a"(INVPCID_ALL_MONGLOBAL) : "memory"); + return; + } @@ -16838,15 +17725,17 @@ index 50a7fc0..7c437a7 100644 - unsigned long cr4; + if (static_cpu_has(X86_FEATURE_INVPCID)) { + unsigned long descriptor[2]; -+ asm volatile(__ASM_INVPCID : : "d"(&descriptor), "a"(INVPCID_ALL_GLOBAL) : "memory"); -+ } else { -+ unsigned long cr4; - cr4 = native_read_cr4(); - /* clear PGE */ - native_write_cr4(cr4 & ~X86_CR4_PGE); - /* write old PGE again and flush TLBs */ - native_write_cr4(cr4); ++ descriptor[0] = PCID_KERNEL; ++ asm volatile(__ASM_INVPCID : : "d"(&descriptor), "a"(INVPCID_ALL_GLOBAL) : "memory"); ++ } else { ++ unsigned long cr4; ++ + cr4 = native_read_cr4(); + /* clear PGE */ + native_write_cr4(cr4 & ~X86_CR4_PGE); @@ -16856,7 +17745,7 @@ index 50a7fc0..7c437a7 100644 } static inline void __native_flush_tlb_global(void) -@@ -49,6 +71,42 @@ static inline void __native_flush_tlb_global(void) +@@ -49,6 +75,42 @@ static inline void __native_flush_tlb_global(void) static inline void __native_flush_tlb_single(unsigned long addr) { @@ -17350,7 +18239,7 @@ index 7f760a9..04b1c65 100644 } diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h -index 142810c..1f2a0a7 100644 +index 142810c..1dbe82f 100644 --- a/arch/x86/include/asm/uaccess_64.h +++ b/arch/x86/include/asm/uaccess_64.h @@ -10,6 +10,9 @@ @@ -17669,8 +18558,9 @@ index 142810c..1f2a0a7 100644 } } - static __must_check __always_inline int +-static __must_check __always_inline int -__copy_from_user_inatomic(void *dst, const void __user *src, unsigned size) ++static __must_check __always_inline unsigned long +__copy_from_user_inatomic(void *dst, const void __user *src, unsigned long size) { - return copy_user_generic(dst, (__force const void *)src, size); @@ -24734,7 +25624,7 @@ index 0000000..5877189 + return arch_get_unmapped_area(filp, addr0, len, pgoff, flags); +} diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c -index 48f8375..ace2781 100644 +index 30277e2..5664a29 100644 --- a/arch/x86/kernel/sys_x86_64.c +++ b/arch/x86/kernel/sys_x86_64.c @@ -81,8 +81,8 @@ out: @@ -24752,8 +25642,8 @@ index 48f8375..ace2781 100644 *begin = new_begin; } } else { -- *begin = mmap_legacy_base(); -+ *begin = mm->mmap_base; +- *begin = current->mm->mmap_legacy_base; ++ *begin = mm->mmap_legacy_base; *end = TASK_SIZE; } } @@ -30568,7 +31458,7 @@ index d87dd6d..bf3fa66 100644 pte = kmemcheck_pte_lookup(address); diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c -index c1af323..4758dad 100644 +index 5c1ae28..45f4ac9 100644 --- a/arch/x86/mm/mmap.c +++ b/arch/x86/mm/mmap.c @@ -52,7 +52,7 @@ static unsigned int stack_maxrandom_size(void) @@ -30608,8 +31498,8 @@ index c1af323..4758dad 100644 * Bottom-up (legacy) layout on X86_32 did not support randomization, X86_64 * does, but not when emulating X86_32 */ --unsigned long mmap_legacy_base(void) -+unsigned long mmap_legacy_base(struct mm_struct *mm) +-static unsigned long mmap_legacy_base(void) ++static unsigned long mmap_legacy_base(struct mm_struct *mm) { - if (mmap_is_ia32()) + if (mmap_is_ia32()) { @@ -30626,32 +31516,24 @@ index c1af323..4758dad 100644 return TASK_UNMAPPED_BASE + mmap_rnd(); } -@@ -113,11 +126,23 @@ unsigned long mmap_legacy_base(void) +@@ -112,8 +125,15 @@ static unsigned long mmap_legacy_base(void) + */ void arch_pick_mmap_layout(struct mm_struct *mm) { - if (mmap_is_legacy()) { -- mm->mmap_base = mmap_legacy_base(); -+ mm->mmap_base = mmap_legacy_base(mm); -+ -+#ifdef CONFIG_PAX_RANDMMAP -+ if (mm->pax_flags & MF_PAX_RANDMMAP) -+ mm->mmap_base += mm->delta_mmap; -+#endif -+ - mm->get_unmapped_area = arch_get_unmapped_area; - mm->unmap_area = arch_unmap_area; - } else { -- mm->mmap_base = mmap_base(); -+ mm->mmap_base = mmap_base(mm); +- mm->mmap_legacy_base = mmap_legacy_base(); +- mm->mmap_base = mmap_base(); ++ mm->mmap_legacy_base = mmap_legacy_base(mm); ++ mm->mmap_base = mmap_base(mm); + +#ifdef CONFIG_PAX_RANDMMAP -+ if (mm->pax_flags & MF_PAX_RANDMMAP) -+ mm->mmap_base -= mm->delta_mmap + mm->delta_stack; ++ if (mm->pax_flags & MF_PAX_RANDMMAP) { ++ mm->mmap_legacy_base += mm->delta_mmap; ++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack; ++ } +#endif -+ - mm->get_unmapped_area = arch_get_unmapped_area_topdown; - mm->unmap_area = arch_unmap_area_topdown; - } + + if (mmap_is_legacy()) { + mm->mmap_base = mm->mmap_legacy_base; diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c index dc0b727..f612039 100644 --- a/arch/x86/mm/mmio-mod.c @@ -33284,7 +34166,7 @@ index fdc3ba2..3daee39 100644 .alloc_pud = xen_alloc_pmd_init, .release_pud = xen_release_pmd_init, diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c -index d99cae8..18401e1 100644 +index a1e58e1..9392ad8 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c @@ -240,11 +240,6 @@ static void __init xen_smp_prepare_boot_cpu(void) @@ -38535,10 +39417,112 @@ index 8c04943..4370ed9 100644 err = drm_debugfs_create_files(dc->debugfs_files, ARRAY_SIZE(debugfs_files), diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c -index 402f486..f862d7e 100644 +index 402f486..5340852 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c -@@ -2275,7 +2275,7 @@ EXPORT_SYMBOL_GPL(hid_ignore); +@@ -63,6 +63,8 @@ struct hid_report *hid_register_report(struct hid_device *device, unsigned type, + struct hid_report_enum *report_enum = device->report_enum + type; + struct hid_report *report; + ++ if (id >= HID_MAX_IDS) ++ return NULL; + if (report_enum->report_id_hash[id]) + return report_enum->report_id_hash[id]; + +@@ -404,8 +406,10 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item) + + case HID_GLOBAL_ITEM_TAG_REPORT_ID: + parser->global.report_id = item_udata(item); +- if (parser->global.report_id == 0) { +- hid_err(parser->device, "report_id 0 is invalid\n"); ++ if (parser->global.report_id == 0 || ++ parser->global.report_id >= HID_MAX_IDS) { ++ hid_err(parser->device, "report_id %u is invalid\n", ++ parser->global.report_id); + return -1; + } + return 0; +@@ -575,7 +579,7 @@ static void hid_close_report(struct hid_device *device) + for (i = 0; i < HID_REPORT_TYPES; i++) { + struct hid_report_enum *report_enum = device->report_enum + i; + +- for (j = 0; j < 256; j++) { ++ for (j = 0; j < HID_MAX_IDS; j++) { + struct hid_report *report = report_enum->report_id_hash[j]; + if (report) + hid_free_report(report); +@@ -755,6 +759,56 @@ int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size) + } + EXPORT_SYMBOL_GPL(hid_parse_report); + ++static const char * const hid_report_names[] = { ++ "HID_INPUT_REPORT", ++ "HID_OUTPUT_REPORT", ++ "HID_FEATURE_REPORT", ++}; ++/** ++ * hid_validate_report - validate existing device report ++ * ++ * @device: hid device ++ * @type: which report type to examine ++ * @id: which report ID to examine (0 for first) ++ * @fields: expected number of fields ++ * @report_counts: expected number of values per field ++ * ++ * Validate the report details after parsing. ++ */ ++struct hid_report *hid_validate_report(struct hid_device *hid, ++ unsigned int type, unsigned int id, ++ unsigned int fields, ++ unsigned int report_counts) ++{ ++ struct hid_report *report; ++ unsigned int i; ++ ++ if (type > HID_FEATURE_REPORT) { ++ hid_err(hid, "invalid HID report %u\n", type); ++ return NULL; ++ } ++ ++ report = hid->report_enum[type].report_id_hash[id]; ++ if (!report) { ++ hid_err(hid, "missing %s %u\n", hid_report_names[type], id); ++ return NULL; ++ } ++ if (report->maxfield < fields) { ++ hid_err(hid, "not enough fields in %s %u\n", ++ hid_report_names[type], id); ++ return NULL; ++ } ++ for (i = 0; i < fields; i++) { ++ if (report->field[i]->report_count < report_counts) { ++ hid_err(hid, "not enough values in %s %u fields\n", ++ hid_report_names[type], id); ++ return NULL; ++ } ++ } ++ return report; ++} ++EXPORT_SYMBOL_GPL(hid_validate_report); ++ + /** + * hid_open_report - open a driver-specific device report + * +@@ -1152,7 +1206,12 @@ EXPORT_SYMBOL_GPL(hid_output_report); + + int hid_set_field(struct hid_field *field, unsigned offset, __s32 value) + { +- unsigned size = field->report_size; ++ unsigned size; ++ ++ if (!field) ++ return -1; ++ ++ size = field->report_size; + + hid_dump_input(field->report->device, field->usage + offset, value); + +@@ -2275,7 +2334,7 @@ EXPORT_SYMBOL_GPL(hid_ignore); int hid_add_device(struct hid_device *hdev) { @@ -38547,7 +39531,7 @@ index 402f486..f862d7e 100644 int ret; if (WARN_ON(hdev->status & HID_STAT_ADDED)) -@@ -2309,7 +2309,7 @@ int hid_add_device(struct hid_device *hdev) +@@ -2309,7 +2368,7 @@ int hid_add_device(struct hid_device *hdev) /* XXX hack, any other cleaner solution after the driver core * is converted to allow more than 20 bytes as the device name? */ dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus, @@ -38556,6 +39540,349 @@ index 402f486..f862d7e 100644 hid_debug_register(hdev, dev_name(&hdev->dev)); ret = device_add(&hdev->dev); +diff --git a/drivers/hid/hid-lenovo-tpkbd.c b/drivers/hid/hid-lenovo-tpkbd.c +index 07837f5..b697ada 100644 +--- a/drivers/hid/hid-lenovo-tpkbd.c ++++ b/drivers/hid/hid-lenovo-tpkbd.c +@@ -341,6 +341,11 @@ static int tpkbd_probe_tp(struct hid_device *hdev) + char *name_mute, *name_micmute; + int ret; + ++ /* Validate required reports. */ ++ if (!hid_validate_report(hdev, HID_OUTPUT_REPORT, 4, 4, 1) || ++ !hid_validate_report(hdev, HID_OUTPUT_REPORT, 3, 1, 2)) ++ return -ENODEV; ++ + if (sysfs_create_group(&hdev->dev.kobj, + &tpkbd_attr_group_pointer)) { + hid_warn(hdev, "Could not create sysfs group\n"); +diff --git a/drivers/hid/hid-lg2ff.c b/drivers/hid/hid-lg2ff.c +index b3cd150..9805197 100644 +--- a/drivers/hid/hid-lg2ff.c ++++ b/drivers/hid/hid-lg2ff.c +@@ -64,26 +64,13 @@ int lg2ff_init(struct hid_device *hid) + struct hid_report *report; + struct hid_input *hidinput = list_entry(hid->inputs.next, + struct hid_input, list); +- struct list_head *report_list = +- &hid->report_enum[HID_OUTPUT_REPORT].report_list; + struct input_dev *dev = hidinput->input; + int error; + +- if (list_empty(report_list)) { +- hid_err(hid, "no output report found\n"); ++ /* Check that the report looks ok */ ++ report = hid_validate_report(hid, HID_OUTPUT_REPORT, 0, 1, 7); ++ if (!report) + return -ENODEV; +- } +- +- report = list_entry(report_list->next, struct hid_report, list); +- +- if (report->maxfield < 1) { +- hid_err(hid, "output report is empty\n"); +- return -ENODEV; +- } +- if (report->field[0]->report_count < 7) { +- hid_err(hid, "not enough values in the field\n"); +- return -ENODEV; +- } + + lg2ff = kmalloc(sizeof(struct lg2ff_device), GFP_KERNEL); + if (!lg2ff) +diff --git a/drivers/hid/hid-lg3ff.c b/drivers/hid/hid-lg3ff.c +index e52f181..53ac79b 100644 +--- a/drivers/hid/hid-lg3ff.c ++++ b/drivers/hid/hid-lg3ff.c +@@ -66,10 +66,11 @@ static int hid_lg3ff_play(struct input_dev *dev, void *data, + int x, y; + + /* +- * Maxusage should always be 63 (maximum fields) +- * likely a better way to ensure this data is clean ++ * Available values in the field should always be 63, but we only use up to ++ * 35. Instead, clear the entire area, however big it is. + */ +- memset(report->field[0]->value, 0, sizeof(__s32)*report->field[0]->maxusage); ++ memset(report->field[0]->value, 0, ++ sizeof(__s32) * report->field[0]->report_count); + + switch (effect->type) { + case FF_CONSTANT: +@@ -129,32 +130,14 @@ static const signed short ff3_joystick_ac[] = { + int lg3ff_init(struct hid_device *hid) + { + struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); +- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; + struct input_dev *dev = hidinput->input; +- struct hid_report *report; +- struct hid_field *field; + const signed short *ff_bits = ff3_joystick_ac; + int error; + int i; + +- /* Find the report to use */ +- if (list_empty(report_list)) { +- hid_err(hid, "No output report found\n"); +- return -1; +- } +- + /* Check that the report looks ok */ +- report = list_entry(report_list->next, struct hid_report, list); +- if (!report) { +- hid_err(hid, "NULL output report\n"); +- return -1; +- } +- +- field = report->field[0]; +- if (!field) { +- hid_err(hid, "NULL field\n"); +- return -1; +- } ++ if (!hid_validate_report(hid, HID_OUTPUT_REPORT, 0, 1, 35)) ++ return -ENODEV; + + /* Assume single fixed device G940 */ + for (i = 0; ff_bits[i] >= 0; i++) +diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c +index 0ddae2a..8b89f0f 100644 +--- a/drivers/hid/hid-lg4ff.c ++++ b/drivers/hid/hid-lg4ff.c +@@ -484,34 +484,16 @@ static enum led_brightness lg4ff_led_get_brightness(struct led_classdev *led_cde + int lg4ff_init(struct hid_device *hid) + { + struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); +- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; + struct input_dev *dev = hidinput->input; +- struct hid_report *report; +- struct hid_field *field; + struct lg4ff_device_entry *entry; + struct lg_drv_data *drv_data; + struct usb_device_descriptor *udesc; + int error, i, j; + __u16 bcdDevice, rev_maj, rev_min; + +- /* Find the report to use */ +- if (list_empty(report_list)) { +- hid_err(hid, "No output report found\n"); +- return -1; +- } +- + /* Check that the report looks ok */ +- report = list_entry(report_list->next, struct hid_report, list); +- if (!report) { +- hid_err(hid, "NULL output report\n"); ++ if (!hid_validate_report(hid, HID_OUTPUT_REPORT, 0, 1, 7)) + return -1; +- } +- +- field = report->field[0]; +- if (!field) { +- hid_err(hid, "NULL field\n"); +- return -1; +- } + + /* Check what wheel has been connected */ + for (i = 0; i < ARRAY_SIZE(lg4ff_devices); i++) { +diff --git a/drivers/hid/hid-lgff.c b/drivers/hid/hid-lgff.c +index d7ea8c8..a84fb40 100644 +--- a/drivers/hid/hid-lgff.c ++++ b/drivers/hid/hid-lgff.c +@@ -128,27 +128,14 @@ static void hid_lgff_set_autocenter(struct input_dev *dev, u16 magnitude) + int lgff_init(struct hid_device* hid) + { + struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); +- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; + struct input_dev *dev = hidinput->input; +- struct hid_report *report; +- struct hid_field *field; + const signed short *ff_bits = ff_joystick; + int error; + int i; + +- /* Find the report to use */ +- if (list_empty(report_list)) { +- hid_err(hid, "No output report found\n"); +- return -1; +- } +- + /* Check that the report looks ok */ +- report = list_entry(report_list->next, struct hid_report, list); +- field = report->field[0]; +- if (!field) { +- hid_err(hid, "NULL field\n"); +- return -1; +- } ++ if (!hid_validate_report(hid, HID_OUTPUT_REPORT, 0, 1, 7)) ++ return -ENODEV; + + for (i = 0; i < ARRAY_SIZE(devices); i++) { + if (dev->id.vendor == devices[i].idVendor && +diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c +index 5207591a..6c9197f 100644 +--- a/drivers/hid/hid-logitech-dj.c ++++ b/drivers/hid/hid-logitech-dj.c +@@ -421,7 +421,7 @@ static int logi_dj_recv_send_report(struct dj_receiver_dev *djrcv_dev, + struct hid_report *report; + struct hid_report_enum *output_report_enum; + u8 *data = (u8 *)(&dj_report->device_index); +- int i; ++ unsigned int i, length; + + output_report_enum = &hdev->report_enum[HID_OUTPUT_REPORT]; + report = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT]; +@@ -431,7 +431,9 @@ static int logi_dj_recv_send_report(struct dj_receiver_dev *djrcv_dev, + return -ENODEV; + } + +- for (i = 0; i < report->field[0]->report_count; i++) ++ length = min_t(size_t, sizeof(*dj_report) - 1, ++ report->field[0]->report_count); ++ for (i = 0; i < length; i++) + report->field[0]->value[i] = data[i]; + + hid_hw_request(hdev, report, HID_REQ_SET_REPORT); +@@ -738,6 +740,12 @@ static int logi_dj_probe(struct hid_device *hdev, + goto hid_parse_fail; + } + ++ if (!hid_validate_report(hdev, HID_OUTPUT_REPORT, REPORT_ID_DJ_SHORT, ++ 1, 3)) { ++ retval = -ENODEV; ++ goto hid_parse_fail; ++ } ++ + /* Starts the usb device and connects to upper interfaces hiddev and + * hidraw */ + retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index d39a5ce..4892dfc 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -330,9 +330,18 @@ static void mt_feature_mapping(struct hid_device *hdev, + break; + } + } ++ /* Ignore if value index is out of bounds. */ ++ if (td->inputmode_index < 0 || ++ td->inputmode_index >= field->report_count) { ++ dev_err(&hdev->dev, "HID_DG_INPUTMODE out of range\n"); ++ td->inputmode = -1; ++ } + + break; + case HID_DG_CONTACTMAX: ++ /* Ignore if value count is out of bounds. */ ++ if (field->report_count < 1) ++ break; + td->maxcontact_report_id = field->report->id; + td->maxcontacts = field->value[0]; + if (!td->maxcontacts && +@@ -743,15 +752,21 @@ static void mt_touch_report(struct hid_device *hid, struct hid_report *report) + unsigned count; + int r, n; + ++ if (report->maxfield == 0) ++ return; ++ + /* + * Includes multi-packet support where subsequent + * packets are sent with zero contactcount. + */ +- if (td->cc_index >= 0) { +- struct hid_field *field = report->field[td->cc_index]; +- int value = field->value[td->cc_value_index]; +- if (value) +- td->num_expected = value; ++ if (td->cc_index >= 0 && td->cc_index < report->maxfield) { ++ field = report->field[td->cc_index]; ++ if (td->cc_value_index >= 0 && ++ td->cc_value_index < field->report_count) { ++ int value = field->value[td->cc_value_index]; ++ if (value) ++ td->num_expected = value; ++ } + } + + for (r = 0; r < report->maxfield; r++) { +diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c +index ef95102..5482156 100644 +--- a/drivers/hid/hid-ntrig.c ++++ b/drivers/hid/hid-ntrig.c +@@ -115,7 +115,8 @@ static inline int ntrig_get_mode(struct hid_device *hdev) + struct hid_report *report = hdev->report_enum[HID_FEATURE_REPORT]. + report_id_hash[0x0d]; + +- if (!report) ++ if (!report || report->maxfield < 1 || ++ report->field[0]->report_count < 1) + return -EINVAL; + + hid_hw_request(hdev, report, HID_REQ_GET_REPORT); +diff --git a/drivers/hid/hid-picolcd_core.c b/drivers/hid/hid-picolcd_core.c +index b48092d..72bba1e 100644 +--- a/drivers/hid/hid-picolcd_core.c ++++ b/drivers/hid/hid-picolcd_core.c +@@ -290,7 +290,7 @@ static ssize_t picolcd_operation_mode_store(struct device *dev, + buf += 10; + cnt -= 10; + } +- if (!report) ++ if (!report || report->maxfield < 1) + return -EINVAL; + + while (cnt > 0 && (buf[cnt-1] == '\n' || buf[cnt-1] == '\r')) +diff --git a/drivers/hid/hid-pl.c b/drivers/hid/hid-pl.c +index d29112f..2dcd7d9 100644 +--- a/drivers/hid/hid-pl.c ++++ b/drivers/hid/hid-pl.c +@@ -132,8 +132,14 @@ static int plff_init(struct hid_device *hid) + strong = &report->field[0]->value[2]; + weak = &report->field[0]->value[3]; + debug("detected single-field device"); +- } else if (report->maxfield >= 4 && report->field[0]->maxusage == 1 && +- report->field[0]->usage[0].hid == (HID_UP_LED | 0x43)) { ++ } else if (report->field[0]->maxusage == 1 && ++ report->field[0]->usage[0].hid == ++ (HID_UP_LED | 0x43) && ++ report->maxfield >= 4 && ++ report->field[0]->report_count >= 1 && ++ report->field[1]->report_count >= 1 && ++ report->field[2]->report_count >= 1 && ++ report->field[3]->report_count >= 1) { + report->field[0]->value[0] = 0x00; + report->field[1]->value[0] = 0x00; + strong = &report->field[2]->value[0]; +diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c +index ca749810..aa34755 100644 +--- a/drivers/hid/hid-sensor-hub.c ++++ b/drivers/hid/hid-sensor-hub.c +@@ -221,7 +221,8 @@ int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, + + mutex_lock(&data->mutex); + report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT); +- if (!report || (field_index >= report->maxfield)) { ++ if (!report || (field_index >= report->maxfield) || ++ report->field[field_index]->report_count < 1) { + ret = -EINVAL; + goto done_proc; + } +diff --git a/drivers/hid/hid-steelseries.c b/drivers/hid/hid-steelseries.c +index d164911..ef42e86 100644 +--- a/drivers/hid/hid-steelseries.c ++++ b/drivers/hid/hid-steelseries.c +@@ -249,6 +249,11 @@ static int steelseries_srws1_probe(struct hid_device *hdev, + goto err_free; + } + ++ if (!hid_validate_report(hdev, HID_OUTPUT_REPORT, 0, 1, 16)) { ++ ret = -ENODEV; ++ goto err_free; ++ } ++ + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); + if (ret) { + hid_err(hdev, "hw start failed\n"); diff --git a/drivers/hid/hid-wiimote-debug.c b/drivers/hid/hid-wiimote-debug.c index 90124ff..3761764 100644 --- a/drivers/hid/hid-wiimote-debug.c @@ -38569,6 +39896,66 @@ index 90124ff..3761764 100644 return -EFAULT; *off += size; +diff --git a/drivers/hid/hid-zpff.c b/drivers/hid/hid-zpff.c +index 6ec28a3..b124991 100644 +--- a/drivers/hid/hid-zpff.c ++++ b/drivers/hid/hid-zpff.c +@@ -68,22 +68,12 @@ static int zpff_init(struct hid_device *hid) + struct hid_report *report; + struct hid_input *hidinput = list_entry(hid->inputs.next, + struct hid_input, list); +- struct list_head *report_list = +- &hid->report_enum[HID_OUTPUT_REPORT].report_list; + struct input_dev *dev = hidinput->input; + int error; + +- if (list_empty(report_list)) { +- hid_err(hid, "no output report found\n"); ++ report = hid_validate_report(hid, HID_OUTPUT_REPORT, 0, 4, 1); ++ if (!report) + return -ENODEV; +- } +- +- report = list_entry(report_list->next, struct hid_report, list); +- +- if (report->maxfield < 4) { +- hid_err(hid, "not enough fields in report\n"); +- return -ENODEV; +- } + + zpff = kzalloc(sizeof(struct zpff_device), GFP_KERNEL); + if (!zpff) +diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c +index fc307e0..2b255e8 100644 +--- a/drivers/hid/uhid.c ++++ b/drivers/hid/uhid.c +@@ -47,7 +47,7 @@ struct uhid_device { + struct mutex report_lock; + wait_queue_head_t report_wait; + atomic_t report_done; +- atomic_t report_id; ++ atomic_unchecked_t report_id; + struct uhid_event report_buf; + }; + +@@ -187,7 +187,7 @@ static int uhid_hid_get_raw(struct hid_device *hid, unsigned char rnum, + + spin_lock_irqsave(&uhid->qlock, flags); + ev->type = UHID_FEATURE; +- ev->u.feature.id = atomic_inc_return(&uhid->report_id); ++ ev->u.feature.id = atomic_inc_return_unchecked(&uhid->report_id); + ev->u.feature.rnum = rnum; + ev->u.feature.rtype = report_type; + +@@ -471,7 +471,7 @@ static int uhid_dev_feature_answer(struct uhid_device *uhid, + spin_lock_irqsave(&uhid->qlock, flags); + + /* id for old report; drop it silently */ +- if (atomic_read(&uhid->report_id) != ev->u.feature_answer.id) ++ if (atomic_read_unchecked(&uhid->report_id) != ev->u.feature_answer.id) + goto unlock; + if (atomic_read(&uhid->report_done)) + goto unlock; diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 0b122f8..b1d8160 100644 --- a/drivers/hv/channel.c @@ -39908,6 +41295,19 @@ index 600c79b..3752bab 100644 tty_port_tty_set(&cs->port, NULL); mutex_unlock(&cs->mutex); +diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c +index d0a41cb..f0cdb8c 100644 +--- a/drivers/isdn/gigaset/usb-gigaset.c ++++ b/drivers/isdn/gigaset/usb-gigaset.c +@@ -547,7 +547,7 @@ static int gigaset_brkchars(struct cardstate *cs, const unsigned char buf[6]) + gigaset_dbg_buffer(DEBUG_USBREQ, "brkchars", 6, buf); + memcpy(cs->hw.usb->bchars, buf, 6); + return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x19, 0x41, +- 0, 0, &buf, 6, 2000); ++ 0, 0, buf, 6, 2000); + } + + static void gigaset_freebcshw(struct bc_state *bcs) diff --git a/drivers/isdn/hardware/avm/b1.c b/drivers/isdn/hardware/avm/b1.c index 4d9b195..455075c 100644 --- a/drivers/isdn/hardware/avm/b1.c @@ -39930,6 +41330,19 @@ index 4d9b195..455075c 100644 return -EFAULT; } else { memcpy(buf, dp, left); +diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c +index 9bb12ba..d4262f7 100644 +--- a/drivers/isdn/i4l/isdn_common.c ++++ b/drivers/isdn/i4l/isdn_common.c +@@ -1651,6 +1651,8 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg) + } else + return -EINVAL; + case IIOCDBGVAR: ++ if (!capable(CAP_SYS_RAWIO)) ++ return -EPERM; + if (arg) { + if (copy_to_user(argp, &dev, sizeof(ulong))) + return -EFAULT; diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 3c5f249..5fac4d0 100644 --- a/drivers/isdn/i4l/isdn_tty.c @@ -42959,7 +44372,7 @@ index d532948..e0d8bb1 100644 memset(buf, 0, sizeof(buf)); buf_size = min(count, sizeof(buf) - 1); diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c -index 50ba0a4..29424e7 100644 +index aeb70e1..d7b5bb5 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -1329,7 +1329,7 @@ static ssize_t iwl_dbgfs_interrupt_write(struct file *file, @@ -46639,6 +48052,29 @@ index d53547d..6a22d02 100644 if (atomic_read(&urb->reject)) wake_up(&usb_kill_urb_queue); usb_put_urb(urb); +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index da2905a..834a569 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -27,6 +27,7 @@ + #include <linux/freezer.h> + #include <linux/random.h> + #include <linux/pm_qos.h> ++#include <linux/grsecurity.h> + + #include <asm/uaccess.h> + #include <asm/byteorder.h> +@@ -4424,6 +4425,10 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, + goto done; + return; + } ++ ++ if (gr_handle_new_usb()) ++ goto done; ++ + if (hub_is_superspeed(hub->hdev)) + unit_load = 150; + else diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 444d30e..f15c850 100644 --- a/drivers/usb/core/message.c @@ -46678,6 +48114,19 @@ index b10da72..43aa0b2 100644 INIT_LIST_HEAD(&dev->ep0.urb_list); dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE; +diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c +index f77083f..f3e2e34 100644 +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -550,8 +550,6 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep, + if (!usb_endpoint_xfer_isoc(desc)) + return 0; + +- memset(&trb_link, 0, sizeof(trb_link)); +- + /* Link TRB for ISOC. The HWO bit is never reset */ + trb_st_hw = &dep->trb_pool[0]; + diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c index 5e29dde..eca992f 100644 --- a/drivers/usb/early/ehci-dbgp.c @@ -51538,10 +52987,10 @@ index d50bbe5..af3b649 100644 goto err; } diff --git a/fs/bio.c b/fs/bio.c -index 94bbc04..6fe78a4 100644 +index c5eae72..599e3cf 100644 --- a/fs/bio.c +++ b/fs/bio.c -@@ -1096,7 +1096,7 @@ struct bio *bio_copy_user_iov(struct request_queue *q, +@@ -1106,7 +1106,7 @@ struct bio *bio_copy_user_iov(struct request_queue *q, /* * Overflow, abort */ @@ -51550,7 +52999,7 @@ index 94bbc04..6fe78a4 100644 return ERR_PTR(-EINVAL); nr_pages += end - start; -@@ -1230,7 +1230,7 @@ static struct bio *__bio_map_user_iov(struct request_queue *q, +@@ -1240,7 +1240,7 @@ static struct bio *__bio_map_user_iov(struct request_queue *q, /* * Overflow, abort */ @@ -51559,7 +53008,7 @@ index 94bbc04..6fe78a4 100644 return ERR_PTR(-EINVAL); nr_pages += end - start; -@@ -1492,7 +1492,7 @@ static void bio_copy_kern_endio(struct bio *bio, int err) +@@ -1502,7 +1502,7 @@ static void bio_copy_kern_endio(struct bio *bio, int err) const int read = bio_data_dir(bio) == READ; struct bio_map_data *bmd = bio->bi_private; int i; @@ -56152,7 +57601,7 @@ index 9ed9361..2b72db1 100644 out: return len; diff --git a/fs/namespace.c b/fs/namespace.c -index 7b1ca9b..6faeccf 100644 +index a45ba4f..e7dc489 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1265,6 +1265,9 @@ static int do_umount(struct mount *mnt, int flags) @@ -56560,9 +58009,18 @@ index aa411c3..c260a84 100644 "inode 0x%lx or driver bug.", vdir->i_ino); goto err_out; diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c -index c5670b8..01a3656 100644 +index c5670b8..2b43d9b 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c +@@ -1282,7 +1282,7 @@ static inline size_t ntfs_copy_from_user(struct page **pages, + char *addr; + size_t total = 0; + unsigned len; +- int left; ++ unsigned left; + + do { + len = PAGE_CACHE_SIZE - ofs; @@ -2241,6 +2241,6 @@ const struct inode_operations ntfs_file_inode_ops = { #endif /* NTFS_RW */ }; @@ -59456,10 +60914,10 @@ index ca9ecaa..60100c7 100644 kfree(s); diff --git a/grsecurity/Kconfig b/grsecurity/Kconfig new file mode 100644 -index 0000000..712a85d +index 0000000..76e84b9 --- /dev/null +++ b/grsecurity/Kconfig -@@ -0,0 +1,1043 @@ +@@ -0,0 +1,1063 @@ +# +# grecurity configuration +# @@ -60431,6 +61889,26 @@ index 0000000..712a85d + option with name "socket_server_gid" is created. + +endmenu ++ ++menu "Physical Protections" ++depends on GRKERNSEC ++ ++config GRKERNSEC_DENYUSB ++ bool "Deny new USB connections after toggle" ++ default y if GRKERNSEC_CONFIG_AUTO ++ help ++ If you say Y here, a new sysctl option with name "deny_new_usb" ++ will be created. Setting its value to 1 will prevent any new ++ USB devices from being recognized by the OS. Any attempted USB ++ device insertion will be logged. This option is intended to be ++ used against custom USB devices designed to exploit vulnerabilities ++ in various USB device drivers. ++ ++ For greatest effectiveness, this sysctl should be set after any ++ relevant init scripts. Once set, it cannot be unset. ++ ++endmenu ++ +menu "Sysctl Support" +depends on GRKERNSEC && SYSCTL + @@ -60505,10 +61983,10 @@ index 0000000..712a85d +endmenu diff --git a/grsecurity/Makefile b/grsecurity/Makefile new file mode 100644 -index 0000000..36845aa +index 0000000..b0b77d5 --- /dev/null +++ b/grsecurity/Makefile -@@ -0,0 +1,42 @@ +@@ -0,0 +1,43 @@ +# grsecurity's ACL system was originally written in 2001 by Michael Dalton +# during 2001-2009 it has been completely redesigned by Brad Spengler +# into an RBAC system @@ -60521,7 +61999,8 @@ index 0000000..36845aa + +obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \ + grsec_mount.o grsec_sig.o grsec_sysctl.o \ -+ grsec_time.o grsec_tpe.o grsec_link.o grsec_pax.o grsec_ptrace.o ++ grsec_time.o grsec_tpe.o grsec_link.o grsec_pax.o grsec_ptrace.o \ ++ grsec_usb.o + +obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_segv.o \ + gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \ @@ -67806,10 +69285,10 @@ index 0000000..8ca18bf +} diff --git a/grsecurity/grsec_init.c b/grsecurity/grsec_init.c new file mode 100644 -index 0000000..ab2d875 +index 0000000..836f38f --- /dev/null +++ b/grsecurity/grsec_init.c -@@ -0,0 +1,279 @@ +@@ -0,0 +1,280 @@ +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/mm.h> @@ -67838,6 +69317,7 @@ index 0000000..ab2d875 +int grsec_enable_chdir; +int grsec_enable_mount; +int grsec_enable_rofs; ++int grsec_deny_new_usb; +int grsec_enable_chroot_findtask; +int grsec_enable_chroot_mount; +int grsec_enable_chroot_shmat; @@ -69205,10 +70685,10 @@ index 0000000..4030d57 +} diff --git a/grsecurity/grsec_sysctl.c b/grsecurity/grsec_sysctl.c new file mode 100644 -index 0000000..7624d1c +index 0000000..301c665 --- /dev/null +++ b/grsecurity/grsec_sysctl.c -@@ -0,0 +1,460 @@ +@@ -0,0 +1,471 @@ +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/sysctl.h> @@ -69666,6 +71146,17 @@ index 0000000..7624d1c + .extra2 = &one, + }, +#endif ++#ifdef CONFIG_GRKERNSEC_DENYUSB ++ { ++ .procname = "deny_new_usb", ++ .data = &grsec_deny_new_usb, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec_minmax, ++ .extra1 = &one, ++ .extra2 = &one, ++ }, ++#endif + { } +}; +#endif @@ -69770,6 +71261,27 @@ index 0000000..ee57dcf +#endif + return 1; +} +diff --git a/grsecurity/grsec_usb.c b/grsecurity/grsec_usb.c +new file mode 100644 +index 0000000..ae02d8e +--- /dev/null ++++ b/grsecurity/grsec_usb.c +@@ -0,0 +1,15 @@ ++#include <linux/kernel.h> ++#include <linux/grinternal.h> ++#include <linux/module.h> ++ ++int gr_handle_new_usb(void) ++{ ++#ifdef CONFIG_GRKERNSEC_DENYUSB ++ if (grsec_deny_new_usb) { ++ printk(KERN_ALERT "grsec: denied insert of new USB device\n"); ++ return 1; ++ } ++#endif ++ return 0; ++} ++EXPORT_SYMBOL_GPL(gr_handle_new_usb); diff --git a/grsecurity/grsum.c b/grsecurity/grsum.c new file mode 100644 index 0000000..9f7b1ac @@ -72156,10 +73668,10 @@ index 0000000..be66033 +#endif diff --git a/include/linux/grinternal.h b/include/linux/grinternal.h new file mode 100644 -index 0000000..fd8598b +index 0000000..e337683 --- /dev/null +++ b/include/linux/grinternal.h -@@ -0,0 +1,228 @@ +@@ -0,0 +1,229 @@ +#ifndef __GRINTERNAL_H +#define __GRINTERNAL_H + @@ -72208,6 +73720,7 @@ index 0000000..fd8598b +extern int grsec_enable_forkfail; +extern int grsec_enable_time; +extern int grsec_enable_rofs; ++extern int grsec_deny_new_usb; +extern int grsec_enable_chroot_shmat; +extern int grsec_enable_chroot_mount; +extern int grsec_enable_chroot_double; @@ -72509,10 +74022,10 @@ index 0000000..a4396b5 +#define GR_BRUTE_SUID_MSG "bruteforce prevention initiated due to crash of %.950s against uid %u, banning suid/sgid execs for %u minutes. Please investigate the crash report for " diff --git a/include/linux/grsecurity.h b/include/linux/grsecurity.h new file mode 100644 -index 0000000..3676b0b +index 0000000..d6f5a21 --- /dev/null +++ b/include/linux/grsecurity.h -@@ -0,0 +1,242 @@ +@@ -0,0 +1,244 @@ +#ifndef GR_SECURITY_H +#define GR_SECURITY_H +#include <linux/fs.h> @@ -72534,6 +74047,8 @@ index 0000000..3676b0b +#error "CONFIG_PAX enabled, but no PaX options are enabled." +#endif + ++int gr_handle_new_usb(void); ++ +void gr_handle_brute_attach(unsigned long mm_flags); +void gr_handle_brute_check(void); +void gr_handle_kernel_exploit(void); @@ -72780,6 +74295,35 @@ index 0000000..e7ffaaf + const int protocol); + +#endif +diff --git a/include/linux/hid.h b/include/linux/hid.h +index 0c48991..76e41d8 100644 +--- a/include/linux/hid.h ++++ b/include/linux/hid.h +@@ -393,10 +393,12 @@ struct hid_report { + struct hid_device *device; /* associated device */ + }; + ++#define HID_MAX_IDS 256 ++ + struct hid_report_enum { + unsigned numbered; + struct list_head report_list; +- struct hid_report *report_id_hash[256]; ++ struct hid_report *report_id_hash[HID_MAX_IDS]; + }; + + #define HID_REPORT_TYPES 3 +@@ -747,6 +749,10 @@ void hid_output_report(struct hid_report *report, __u8 *data); + struct hid_device *hid_allocate_device(void); + struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id); + int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); ++struct hid_report *hid_validate_report(struct hid_device *hid, ++ unsigned int type, unsigned int id, ++ unsigned int fields, ++ unsigned int report_counts); + int hid_open_report(struct hid_device *device); + int hid_check_keys_pressed(struct hid_device *hid); + int hid_connect(struct hid_device *hid, unsigned int connect_mask); diff --git a/include/linux/highmem.h b/include/linux/highmem.h index 7fb31da..08b5114 100644 --- a/include/linux/highmem.h @@ -73541,7 +75085,7 @@ index e0c8528..bcf0c29 100644 #endif /* __KERNEL__ */ #endif /* _LINUX_MM_H */ diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h -index ace9a5f..81bdb59 100644 +index 4a189ba..04101d6 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -289,6 +289,8 @@ struct vm_area_struct { @@ -73553,7 +75097,7 @@ index ace9a5f..81bdb59 100644 }; struct core_thread { -@@ -437,6 +439,24 @@ struct mm_struct { +@@ -438,6 +440,24 @@ struct mm_struct { int first_nid; #endif struct uprobes_state uprobes_state; @@ -74489,7 +76033,7 @@ index 6dacb93..6174423 100644 static inline void anon_vma_merge(struct vm_area_struct *vma, struct vm_area_struct *next) diff --git a/include/linux/sched.h b/include/linux/sched.h -index 3aeb14b..73816a6 100644 +index 178a8d9..918ea01 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -62,6 +62,7 @@ struct bio_list; @@ -74509,11 +76053,10 @@ index 3aeb14b..73816a6 100644 extern signed long schedule_timeout_interruptible(signed long timeout); extern signed long schedule_timeout_killable(signed long timeout); extern signed long schedule_timeout_uninterruptible(signed long timeout); -@@ -314,7 +315,19 @@ struct nsproxy; +@@ -314,6 +315,18 @@ struct nsproxy; struct user_namespace; #ifdef CONFIG_MMU --extern unsigned long mmap_legacy_base(void); + +#ifdef CONFIG_GRKERNSEC_RAND_THREADSTACK +extern unsigned long gr_rand_threadstack_offset(const struct mm_struct *mm, const struct file *filp, unsigned long flags); @@ -74526,11 +76069,10 @@ index 3aeb14b..73816a6 100644 + +extern bool check_heap_stack_gap(const struct vm_area_struct *vma, unsigned long addr, unsigned long len, unsigned long offset); +extern unsigned long skip_heap_stack_gap(const struct vm_area_struct *vma, unsigned long len, unsigned long offset); -+extern unsigned long mmap_legacy_base(struct mm_struct *mm); extern void arch_pick_mmap_layout(struct mm_struct *mm); extern unsigned long arch_get_unmapped_area(struct file *, unsigned long, unsigned long, -@@ -592,6 +605,17 @@ struct signal_struct { +@@ -591,6 +604,17 @@ struct signal_struct { #ifdef CONFIG_TASKSTATS struct taskstats *stats; #endif @@ -74548,7 +76090,7 @@ index 3aeb14b..73816a6 100644 #ifdef CONFIG_AUDIT unsigned audit_tty; unsigned audit_tty_log_passwd; -@@ -672,6 +696,14 @@ struct user_struct { +@@ -671,6 +695,14 @@ struct user_struct { struct key *session_keyring; /* UID's default session keyring */ #endif @@ -74563,7 +76105,7 @@ index 3aeb14b..73816a6 100644 /* Hash table maintenance information */ struct hlist_node uidhash_node; kuid_t uid; -@@ -1159,8 +1191,8 @@ struct task_struct { +@@ -1158,8 +1190,8 @@ struct task_struct { struct list_head thread_group; struct completion *vfork_done; /* for vfork() */ @@ -74574,7 +76116,7 @@ index 3aeb14b..73816a6 100644 cputime_t utime, stime, utimescaled, stimescaled; cputime_t gtime; -@@ -1185,11 +1217,6 @@ struct task_struct { +@@ -1184,11 +1216,6 @@ struct task_struct { struct task_cputime cputime_expires; struct list_head cpu_timers[3]; @@ -74586,7 +76128,7 @@ index 3aeb14b..73816a6 100644 char comm[TASK_COMM_LEN]; /* executable name excluding path - access with [gs]et_task_comm (which lock it with task_lock()) -@@ -1206,6 +1233,10 @@ struct task_struct { +@@ -1205,6 +1232,10 @@ struct task_struct { #endif /* CPU-specific state of this task */ struct thread_struct thread; @@ -74597,7 +76139,7 @@ index 3aeb14b..73816a6 100644 /* filesystem information */ struct fs_struct *fs; /* open file information */ -@@ -1279,6 +1310,10 @@ struct task_struct { +@@ -1278,6 +1309,10 @@ struct task_struct { gfp_t lockdep_reclaim_gfp; #endif @@ -74608,7 +76150,7 @@ index 3aeb14b..73816a6 100644 /* journalling filesystem info */ void *journal_info; -@@ -1317,6 +1352,10 @@ struct task_struct { +@@ -1316,6 +1351,10 @@ struct task_struct { /* cg_list protected by css_set_lock and tsk->alloc_lock */ struct list_head cg_list; #endif @@ -74619,7 +76161,7 @@ index 3aeb14b..73816a6 100644 #ifdef CONFIG_FUTEX struct robust_list_head __user *robust_list; #ifdef CONFIG_COMPAT -@@ -1417,8 +1456,76 @@ struct task_struct { +@@ -1416,8 +1455,76 @@ struct task_struct { unsigned int sequential_io; unsigned int sequential_io_avg; #endif @@ -74696,7 +76238,7 @@ index 3aeb14b..73816a6 100644 /* Future-safe accessor for struct task_struct's cpus_allowed. */ #define tsk_cpus_allowed(tsk) (&(tsk)->cpus_allowed) -@@ -1477,7 +1584,7 @@ struct pid_namespace; +@@ -1476,7 +1583,7 @@ struct pid_namespace; pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type, struct pid_namespace *ns); @@ -74705,7 +76247,7 @@ index 3aeb14b..73816a6 100644 { return tsk->pid; } -@@ -1920,7 +2027,9 @@ void yield(void); +@@ -1919,7 +2026,9 @@ void yield(void); extern struct exec_domain default_exec_domain; union thread_union { @@ -74715,7 +76257,7 @@ index 3aeb14b..73816a6 100644 unsigned long stack[THREAD_SIZE/sizeof(long)]; }; -@@ -1953,6 +2062,7 @@ extern struct pid_namespace init_pid_ns; +@@ -1952,6 +2061,7 @@ extern struct pid_namespace init_pid_ns; */ extern struct task_struct *find_task_by_vpid(pid_t nr); @@ -74723,7 +76265,7 @@ index 3aeb14b..73816a6 100644 extern struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns); -@@ -2119,7 +2229,7 @@ extern void __cleanup_sighand(struct sighand_struct *); +@@ -2118,7 +2228,7 @@ extern void __cleanup_sighand(struct sighand_struct *); extern void exit_itimers(struct signal_struct *); extern void flush_itimer_signals(void); @@ -74732,7 +76274,7 @@ index 3aeb14b..73816a6 100644 extern int allow_signal(int); extern int disallow_signal(int); -@@ -2310,9 +2420,9 @@ static inline unsigned long *end_of_stack(struct task_struct *p) +@@ -2309,9 +2419,9 @@ static inline unsigned long *end_of_stack(struct task_struct *p) #endif @@ -78484,7 +80026,7 @@ index e76e495..cbfe63a 100644 /* diff --git a/kernel/events/internal.h b/kernel/events/internal.h -index ca65997..cc8cee4 100644 +index ca65997..60df03d 100644 --- a/kernel/events/internal.h +++ b/kernel/events/internal.h @@ -81,10 +81,10 @@ static inline unsigned long perf_data_size(struct ring_buffer *rb) @@ -78492,11 +80034,12 @@ index ca65997..cc8cee4 100644 } -#define DEFINE_OUTPUT_COPY(func_name, memcpy_func) \ +-static inline unsigned int \ +#define DEFINE_OUTPUT_COPY(func_name, memcpy_func, user) \ - static inline unsigned int \ ++static inline unsigned long \ func_name(struct perf_output_handle *handle, \ - const void *buf, unsigned int len) \ -+ const void user *buf, unsigned int len) \ ++ const void user *buf, unsigned long len) \ { \ unsigned long size, written; \ \ @@ -78521,6 +80064,19 @@ index ca65997..cc8cee4 100644 /* Callchain handling */ extern struct perf_callchain_entry * +diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c +index f356974..cb8c570 100644 +--- a/kernel/events/uprobes.c ++++ b/kernel/events/uprobes.c +@@ -1556,7 +1556,7 @@ static int is_trap_at_addr(struct mm_struct *mm, unsigned long vaddr) + { + struct page *page; + uprobe_opcode_t opcode; +- int result; ++ long result; + + pagefault_disable(); + result = __copy_from_user_inatomic(&opcode, (void __user*)vaddr, diff --git a/kernel/exit.c b/kernel/exit.c index 7bb73f9..d7978ed 100644 --- a/kernel/exit.c @@ -78906,7 +80462,7 @@ index ffbc090..08ceeee 100644 else new_fs = fs; diff --git a/kernel/futex.c b/kernel/futex.c -index 49dacfb..5c6b450 100644 +index 49dacfb..2ac4526 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -54,6 +54,7 @@ @@ -78929,6 +80485,15 @@ index 49dacfb..5c6b450 100644 /* * The futex address must be "naturally" aligned. */ +@@ -440,7 +446,7 @@ static int cmpxchg_futex_value_locked(u32 *curval, u32 __user *uaddr, + + static int get_futex_value_locked(u32 *dest, u32 __user *from) + { +- int ret; ++ unsigned long ret; + + pagefault_disable(); + ret = __copy_from_user_inatomic(dest, from, sizeof(u32)); @@ -2733,6 +2739,7 @@ static int __init futex_init(void) { u32 curval; @@ -82923,10 +84488,10 @@ index b8b8560..75b1a09 100644 ret = -EIO; bt->dropped_file = debugfs_create_file("dropped", 0444, dir, bt, diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c -index 6c508ff..ee55a13 100644 +index f23449d..b8cc3a1 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c -@@ -1915,12 +1915,17 @@ ftrace_code_disable(struct module *mod, struct dyn_ftrace *rec) +@@ -1925,12 +1925,17 @@ ftrace_code_disable(struct module *mod, struct dyn_ftrace *rec) if (unlikely(ftrace_disabled)) return 0; @@ -82946,7 +84511,7 @@ index 6c508ff..ee55a13 100644 } /* -@@ -3931,8 +3936,10 @@ static int ftrace_process_locs(struct module *mod, +@@ -3994,8 +3999,10 @@ static int ftrace_process_locs(struct module *mod, if (!count) return 0; @@ -82957,7 +84522,7 @@ index 6c508ff..ee55a13 100644 start_pg = ftrace_allocate_pages(count); if (!start_pg) -@@ -4655,8 +4662,6 @@ ftrace_enable_sysctl(struct ctl_table *table, int write, +@@ -4718,8 +4725,6 @@ ftrace_enable_sysctl(struct ctl_table *table, int write, #ifdef CONFIG_FUNCTION_GRAPH_TRACER static int ftrace_graph_active; @@ -82966,7 +84531,7 @@ index 6c508ff..ee55a13 100644 int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace) { return 0; -@@ -4800,6 +4805,10 @@ ftrace_suspend_notifier_call(struct notifier_block *bl, unsigned long state, +@@ -4863,6 +4868,10 @@ ftrace_suspend_notifier_call(struct notifier_block *bl, unsigned long state, return NOTIFY_DONE; } @@ -82977,7 +84542,7 @@ index 6c508ff..ee55a13 100644 int register_ftrace_graph(trace_func_graph_ret_t retfunc, trace_func_graph_ent_t entryfunc) { -@@ -4813,7 +4822,6 @@ int register_ftrace_graph(trace_func_graph_ret_t retfunc, +@@ -4876,7 +4885,6 @@ int register_ftrace_graph(trace_func_graph_ret_t retfunc, goto out; } @@ -83264,10 +84829,10 @@ index e444ff8..438b8f4 100644 *data_page = bpage; diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c -index 06a5bce..53ad6e7 100644 +index 0582a01..310bed1 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c -@@ -3347,7 +3347,7 @@ int trace_keep_overwrite(struct tracer *tracer, u32 mask, int set) +@@ -3327,7 +3327,7 @@ int trace_keep_overwrite(struct tracer *tracer, u32 mask, int set) return 0; } @@ -83290,10 +84855,10 @@ index 51b4448..7be601f 100644 /* * Normal trace_printk() and friends allocates special buffers diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c -index 6953263..2004e16 100644 +index 3d18aad..d1be0eb 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c -@@ -1748,10 +1748,6 @@ static LIST_HEAD(ftrace_module_file_list); +@@ -1794,10 +1794,6 @@ static LIST_HEAD(ftrace_module_file_list); struct ftrace_module_file_ops { struct list_head list; struct module *mod; @@ -83304,7 +84869,7 @@ index 6953263..2004e16 100644 }; static struct ftrace_module_file_ops * -@@ -1792,17 +1788,12 @@ trace_create_file_ops(struct module *mod) +@@ -1838,17 +1834,12 @@ trace_create_file_ops(struct module *mod) file_ops->mod = mod; @@ -83328,7 +84893,7 @@ index 6953263..2004e16 100644 list_add(&file_ops->list, &ftrace_module_file_list); -@@ -1895,8 +1886,8 @@ __trace_add_new_mod_event(struct ftrace_event_call *call, +@@ -1941,8 +1932,8 @@ __trace_add_new_mod_event(struct ftrace_event_call *call, struct ftrace_module_file_ops *file_ops) { return __trace_add_new_event(call, tr, @@ -84210,7 +85775,7 @@ index 5025174..9d67dcd 100644 bdi_destroy(bdi); return err; diff --git a/mm/filemap.c b/mm/filemap.c -index 7905fe7..e60faa8 100644 +index 7905fe7..f59502b 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1766,7 +1766,7 @@ int generic_file_mmap(struct file * file, struct vm_area_struct * vma) @@ -84222,6 +85787,42 @@ index 7905fe7..e60faa8 100644 file_accessed(file); vma->vm_ops = &generic_file_vm_ops; return 0; +@@ -1948,7 +1948,7 @@ static size_t __iovec_copy_from_user_inatomic(char *vaddr, + + while (bytes) { + char __user *buf = iov->iov_base + base; +- int copy = min(bytes, iov->iov_len - base); ++ size_t copy = min(bytes, iov->iov_len - base); + + base = 0; + left = __copy_from_user_inatomic(vaddr, buf, copy); +@@ -1977,7 +1977,7 @@ size_t iov_iter_copy_from_user_atomic(struct page *page, + BUG_ON(!in_atomic()); + kaddr = kmap_atomic(page); + if (likely(i->nr_segs == 1)) { +- int left; ++ size_t left; + char __user *buf = i->iov->iov_base + i->iov_offset; + left = __copy_from_user_inatomic(kaddr + offset, buf, bytes); + copied = bytes - left; +@@ -2005,7 +2005,7 @@ size_t iov_iter_copy_from_user(struct page *page, + + kaddr = kmap(page); + if (likely(i->nr_segs == 1)) { +- int left; ++ size_t left; + char __user *buf = i->iov->iov_base + i->iov_offset; + left = __copy_from_user(kaddr + offset, buf, bytes); + copied = bytes - left; +@@ -2035,7 +2035,7 @@ void iov_iter_advance(struct iov_iter *i, size_t bytes) + * zero-length segments (without overruning the iovec). + */ + while (bytes || unlikely(i->count && !iov->iov_len)) { +- int copy; ++ size_t copy; + + copy = min(bytes, iov->iov_len - base); + BUG_ON(!i->count || i->count < copy); @@ -2106,6 +2106,7 @@ inline int generic_write_checks(struct file *file, loff_t *pos, size_t *count, i *pos = i_size_read(inode); @@ -90212,9 +91813,18 @@ index a08bd2b..c59bd7c 100644 if (extfilt) filter_mask = nla_get_u32(extfilt); diff --git a/net/core/scm.c b/net/core/scm.c -index 03795d0..eaf7368 100644 +index 03795d0..98d6bdb 100644 --- a/net/core/scm.c +++ b/net/core/scm.c +@@ -54,7 +54,7 @@ static __inline__ int scm_check_creds(struct ucred *creds) + return -EINVAL; + + if ((creds->pid == task_tgid_vnr(current) || +- ns_capable(current->nsproxy->pid_ns->user_ns, CAP_SYS_ADMIN)) && ++ ns_capable(task_active_pid_ns(current)->user_ns, CAP_SYS_ADMIN)) && + ((uid_eq(uid, cred->uid) || uid_eq(uid, cred->euid) || + uid_eq(uid, cred->suid)) || nsown_capable(CAP_SETUID)) && + ((gid_eq(gid, cred->gid) || gid_eq(gid, cred->egid) || @@ -210,7 +210,7 @@ EXPORT_SYMBOL(__scm_send); int put_cmsg(struct msghdr * msg, int level, int type, int len, void *data) { @@ -90526,6 +92136,19 @@ index a55eecc..dd8428c 100644 return -EFAULT; *lenp = len; +diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c +index 55e1fd5..fd602b8 100644 +--- a/net/ieee802154/6lowpan.c ++++ b/net/ieee802154/6lowpan.c +@@ -459,7 +459,7 @@ static int lowpan_header_create(struct sk_buff *skb, + hc06_ptr += 3; + } else { + /* compress nothing */ +- memcpy(hc06_ptr, &hdr, 4); ++ memcpy(hc06_ptr, hdr, 4); + /* replace the top byte with new ECN | DSCP format */ + *hc06_ptr = tmp; + hc06_ptr += 4; diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index d01be2a..8976537 100644 --- a/net/ipv4/af_inet.c @@ -91688,7 +93311,7 @@ index 9a459be..086b866 100644 return -ENOMEM; } diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c -index fb8c94c..fb18024 100644 +index fb8c94c..80a31d8 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -621,7 +621,7 @@ static int inet6_netconf_dump_devconf(struct sk_buff *skb, @@ -91700,7 +93323,24 @@ index fb8c94c..fb18024 100644 net->dev_base_seq; hlist_for_each_entry_rcu(dev, head, index_hlist) { if (idx < s_idx) -@@ -2380,7 +2380,7 @@ int addrconf_set_dstaddr(struct net *net, void __user *arg) +@@ -1124,12 +1124,10 @@ retry: + if (ifp->flags & IFA_F_OPTIMISTIC) + addr_flags |= IFA_F_OPTIMISTIC; + +- ift = !max_addresses || +- ipv6_count_addresses(idev) < max_addresses ? +- ipv6_add_addr(idev, &addr, tmp_plen, +- ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, +- addr_flags) : NULL; +- if (IS_ERR_OR_NULL(ift)) { ++ ift = ipv6_add_addr(idev, &addr, tmp_plen, ++ ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, ++ addr_flags); ++ if (IS_ERR(ift)) { + in6_ifa_put(ifp); + in6_dev_put(idev); + pr_info("%s: retry temporary address regeneration\n", __func__); +@@ -2380,7 +2378,7 @@ int addrconf_set_dstaddr(struct net *net, void __user *arg) p.iph.ihl = 5; p.iph.protocol = IPPROTO_IPV6; p.iph.ttl = 64; @@ -91709,7 +93349,7 @@ index fb8c94c..fb18024 100644 if (ops->ndo_do_ioctl) { mm_segment_t oldfs = get_fs(); -@@ -4002,7 +4002,7 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, +@@ -4002,7 +4000,7 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, s_ip_idx = ip_idx = cb->args[2]; rcu_read_lock(); @@ -91718,7 +93358,7 @@ index fb8c94c..fb18024 100644 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { idx = 0; head = &net->dev_index_head[h]; -@@ -4587,7 +4587,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) +@@ -4587,7 +4585,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) dst_free(&ifp->rt->dst); break; } @@ -91727,7 +93367,7 @@ index fb8c94c..fb18024 100644 } static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) -@@ -4607,7 +4607,7 @@ int addrconf_sysctl_forward(ctl_table *ctl, int write, +@@ -4607,7 +4605,7 @@ int addrconf_sysctl_forward(ctl_table *ctl, int write, int *valp = ctl->data; int val = *valp; loff_t pos = *ppos; @@ -91736,7 +93376,7 @@ index fb8c94c..fb18024 100644 int ret; /* -@@ -4689,7 +4689,7 @@ int addrconf_sysctl_disable(ctl_table *ctl, int write, +@@ -4689,7 +4687,7 @@ int addrconf_sysctl_disable(ctl_table *ctl, int write, int *valp = ctl->data; int val = *valp; loff_t pos = *ppos; @@ -91938,9 +93578,18 @@ index dffdc1a..ccc6678 100644 return -ENOMEM; } diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c -index eedff8c..6e13a47 100644 +index eedff8c..7d7e24a 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c +@@ -108,7 +108,7 @@ found: + */ + static int icmpv6_filter(const struct sock *sk, const struct sk_buff *skb) + { +- struct icmp6hdr *_hdr; ++ struct icmp6hdr _hdr; + const struct icmp6hdr *hdr; + + hdr = skb_header_pointer(skb, skb_transport_offset(skb), @@ -378,7 +378,7 @@ static inline int rawv6_rcv_skb(struct sock *sk, struct sk_buff *skb) { if ((raw6_sk(sk)->checksum || rcu_access_pointer(sk->sk_filter)) && @@ -92939,9 +94588,18 @@ index 0ab9636..cea3c6a 100644 { if (users > 0) diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c -index a99b6c3..3841268 100644 +index a99b6c3..cb372f9 100644 --- a/net/netfilter/nf_conntrack_proto_dccp.c +++ b/net/netfilter/nf_conntrack_proto_dccp.c +@@ -428,7 +428,7 @@ static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb, + const char *msg; + u_int8_t state; + +- dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &dh); ++ dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh); + BUG_ON(dh == NULL); + + state = dccp_state_table[CT_DCCP_ROLE_CLIENT][dh->dccph_type][CT_DCCP_NONE]; @@ -457,7 +457,7 @@ static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb, out_invalid: if (LOG_INVALID(net, IPPROTO_DCCP)) @@ -92951,6 +94609,24 @@ index a99b6c3..3841268 100644 return false; } +@@ -486,7 +486,7 @@ static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb, + u_int8_t type, old_state, new_state; + enum ct_dccp_roles role; + +- dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &dh); ++ dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh); + BUG_ON(dh == NULL); + type = dh->dccph_type; + +@@ -577,7 +577,7 @@ static int dccp_error(struct net *net, struct nf_conn *tmpl, + unsigned int cscov; + const char *msg; + +- dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &dh); ++ dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh); + if (dh == NULL) { + msg = "nf_ct_dccp: short packet "; + goto out_invalid; @@ -614,7 +614,7 @@ static int dccp_error(struct net *net, struct nf_conn *tmpl, out_invalid: @@ -95557,7 +97233,7 @@ index f5eb43d..1814de8 100644 shdr = (Elf_Shdr *)((char *)ehdr + _r(&ehdr->e_shoff)); shstrtab_sec = shdr + r2(&ehdr->e_shstrndx); diff --git a/security/Kconfig b/security/Kconfig -index e9c6ac7..3e3f362 100644 +index e9c6ac7..c5d45c8 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -4,6 +4,959 @@ @@ -96396,7 +98072,7 @@ index e9c6ac7..3e3f362 100644 +config PAX_REFCOUNT + bool "Prevent various kernel object reference counter overflows" + default y if GRKERNSEC_CONFIG_AUTO -+ depends on GRKERNSEC && ((ARM && (CPU_V6 || CPU_V6K || CPU_V7)) || SPARC64 || X86) ++ depends on GRKERNSEC && ((ARM && (CPU_V6 || CPU_V6K || CPU_V7)) || MIPS || SPARC64 || X86) + help + By saying Y here the kernel will detect and prevent overflowing + various (but not all) kinds of object reference counters. Such @@ -99033,10 +100709,10 @@ index 0000000..568b360 +} diff --git a/tools/gcc/kernexec_plugin.c b/tools/gcc/kernexec_plugin.c new file mode 100644 -index 0000000..0408e06 +index 0000000..257529f --- /dev/null +++ b/tools/gcc/kernexec_plugin.c -@@ -0,0 +1,465 @@ +@@ -0,0 +1,471 @@ +/* + * Copyright 2011-2013 by the PaX Team <pageexec@freemail.hu> + * Licensed under the GPL v2 @@ -99088,7 +100764,7 @@ index 0000000..0408e06 +int plugin_is_GPL_compatible; + +static struct plugin_info kernexec_plugin_info = { -+ .version = "201302112000", ++ .version = "201308230150", + .help = "method=[bts|or]\tinstrumentation method\n" +}; + @@ -99239,7 +100915,7 @@ index 0000000..0408e06 +static void kernexec_instrument_fptr_bts(gimple_stmt_iterator *gsi) +{ + gimple assign_intptr, assign_new_fptr, call_stmt; -+ tree intptr, old_fptr, new_fptr, kernexec_mask; ++ tree intptr, orptr, old_fptr, new_fptr, kernexec_mask; + + call_stmt = gsi_stmt(*gsi); + old_fptr = gimple_call_fn(call_stmt); @@ -99248,16 +100924,20 @@ index 0000000..0408e06 + intptr = create_tmp_var(long_unsigned_type_node, "kernexec_bts"); +#if BUILDING_GCC_VERSION <= 4007 + add_referenced_var(intptr); -+ mark_sym_for_renaming(intptr); +#endif ++ intptr = make_ssa_name(intptr, NULL); + assign_intptr = gimple_build_assign(intptr, fold_convert(long_unsigned_type_node, old_fptr)); ++ SSA_NAME_DEF_STMT(intptr) = assign_intptr; + gsi_insert_before(gsi, assign_intptr, GSI_SAME_STMT); + update_stmt(assign_intptr); + + // apply logical or to temporary unsigned long and bitmask + kernexec_mask = build_int_cstu(long_long_unsigned_type_node, 0x8000000000000000LL); +// kernexec_mask = build_int_cstu(long_long_unsigned_type_node, 0xffffffff80000000LL); -+ assign_intptr = gimple_build_assign(intptr, fold_build2(BIT_IOR_EXPR, long_long_unsigned_type_node, intptr, kernexec_mask)); ++ orptr = fold_build2(BIT_IOR_EXPR, long_long_unsigned_type_node, intptr, kernexec_mask); ++ intptr = make_ssa_name(SSA_NAME_VAR(intptr), NULL); ++ assign_intptr = gimple_build_assign(intptr, orptr); ++ SSA_NAME_DEF_STMT(intptr) = assign_intptr; + gsi_insert_before(gsi, assign_intptr, GSI_SAME_STMT); + update_stmt(assign_intptr); + @@ -99265,9 +100945,10 @@ index 0000000..0408e06 + new_fptr = create_tmp_var(TREE_TYPE(old_fptr), "kernexec_fptr"); +#if BUILDING_GCC_VERSION <= 4007 + add_referenced_var(new_fptr); -+ mark_sym_for_renaming(new_fptr); +#endif ++ new_fptr = make_ssa_name(new_fptr, NULL); + assign_new_fptr = gimple_build_assign(new_fptr, fold_convert(TREE_TYPE(old_fptr), intptr)); ++ SSA_NAME_DEF_STMT(new_fptr) = assign_new_fptr; + gsi_insert_before(gsi, assign_new_fptr, GSI_SAME_STMT); + update_stmt(assign_new_fptr); + @@ -99295,8 +100976,8 @@ index 0000000..0408e06 + new_fptr = create_tmp_var(TREE_TYPE(old_fptr), "kernexec_or"); +#if BUILDING_GCC_VERSION <= 4007 + add_referenced_var(new_fptr); -+ mark_sym_for_renaming(new_fptr); +#endif ++ new_fptr = make_ssa_name(new_fptr, NULL); + + // build asm volatile("orq %%r10, %0\n\t" : "=r"(new_fptr) : "0"(old_fptr)); + input = build_tree_list(NULL_TREE, build_string(2, "0")); @@ -99311,6 +100992,7 @@ index 0000000..0408e06 + vec_safe_push(outputs, output); +#endif + asm_or_stmt = gimple_build_asm_vec("orq %%r10, %0\n\t", inputs, outputs, NULL, NULL); ++ SSA_NAME_DEF_STMT(new_fptr) = asm_or_stmt; + gimple_asm_set_volatile(asm_or_stmt, true); + gsi_insert_before(gsi, asm_or_stmt, GSI_SAME_STMT); + update_stmt(asm_or_stmt); @@ -99504,10 +101186,10 @@ index 0000000..0408e06 +} diff --git a/tools/gcc/latent_entropy_plugin.c b/tools/gcc/latent_entropy_plugin.c new file mode 100644 -index 0000000..b5395ba +index 0000000..2ef6fd9 --- /dev/null +++ b/tools/gcc/latent_entropy_plugin.c -@@ -0,0 +1,327 @@ +@@ -0,0 +1,321 @@ +/* + * Copyright 2012-2013 by the PaX Team <pageexec@freemail.hu> + * Licensed under the GPL v2 @@ -99559,7 +101241,7 @@ index 0000000..b5395ba +static tree latent_entropy_decl; + +static struct plugin_info latent_entropy_plugin_info = { -+ .version = "201303102320", ++ .version = "201308230230", + .help = NULL +}; + @@ -99668,13 +101350,10 @@ index 0000000..b5395ba + op = get_op(&rhs); + addxorrol = fold_build2_loc(UNKNOWN_LOCATION, op, unsigned_intDI_type_node, local_entropy, rhs); + assign = gimple_build_assign(local_entropy, addxorrol); -+#if BUILDING_GCC_VERSION <= 4007 -+ find_referenced_vars_in(assign); -+#endif -+//debug_bb(bb); + gsi = gsi_after_labels(bb); + gsi_insert_before(&gsi, assign, GSI_NEW_STMT); + update_stmt(assign); ++//debug_bb(bb); +} + +static void perturb_latent_entropy(basic_block bb, tree rhs) @@ -99687,13 +101366,14 @@ index 0000000..b5395ba + temp = create_tmp_var(unsigned_intDI_type_node, "temp_latent_entropy"); +#if BUILDING_GCC_VERSION <= 4007 + add_referenced_var(temp); -+ mark_sym_for_renaming(temp); +#endif + + // 2. read... ++ temp = make_ssa_name(temp, NULL); + assign = gimple_build_assign(temp, latent_entropy_decl); ++ SSA_NAME_DEF_STMT(temp) = assign; +#if BUILDING_GCC_VERSION <= 4007 -+ find_referenced_vars_in(assign); ++ add_referenced_var(latent_entropy_decl); +#endif + gsi = gsi_after_labels(bb); + gsi_insert_after(&gsi, assign, GSI_NEW_STMT); @@ -99701,18 +101381,14 @@ index 0000000..b5395ba + + // 3. ...modify... + addxorrol = fold_build2_loc(UNKNOWN_LOCATION, get_op(NULL), unsigned_intDI_type_node, temp, rhs); ++ temp = make_ssa_name(SSA_NAME_VAR(temp), NULL); + assign = gimple_build_assign(temp, addxorrol); -+#if BUILDING_GCC_VERSION <= 4007 -+ find_referenced_vars_in(assign); -+#endif ++ SSA_NAME_DEF_STMT(temp) = assign; + gsi_insert_after(&gsi, assign, GSI_NEW_STMT); + update_stmt(assign); + + // 4. ...write latent_entropy + assign = gimple_build_assign(latent_entropy_decl, temp); -+#if BUILDING_GCC_VERSION <= 4007 -+ find_referenced_vars_in(assign); -+#endif + gsi_insert_after(&gsi, assign, GSI_NEW_STMT); + update_stmt(assign); +} @@ -99763,21 +101439,21 @@ index 0000000..b5395ba + + assign = gimple_build_assign(local_entropy, build_int_cstu(unsigned_intDI_type_node, get_random_const())); +// gimple_set_location(assign, loc); -+#if BUILDING_GCC_VERSION <= 4007 -+ find_referenced_vars_in(assign); -+#endif + gsi_insert_after(&gsi, assign, GSI_NEW_STMT); + update_stmt(assign); ++//debug_bb(bb); + bb = bb->next_bb; + + // 3. instrument each BB with an operation on the local entropy variable + while (bb != EXIT_BLOCK_PTR) { + perturb_local_entropy(bb, local_entropy); ++//debug_bb(bb); + bb = bb->next_bb; + }; + + // 4. mix local entropy into the global entropy variable + perturb_latent_entropy(EXIT_BLOCK_PTR->prev_bb, local_entropy); ++//debug_bb(EXIT_BLOCK_PTR->prev_bb); + return 0; +} + @@ -106193,10 +107869,10 @@ index 0000000..b04803b +alloc_dr_65495 alloc_dr 2 65495 NULL diff --git a/tools/gcc/size_overflow_plugin.c b/tools/gcc/size_overflow_plugin.c new file mode 100644 -index 0000000..9db0d0e +index 0000000..03d0c84 --- /dev/null +++ b/tools/gcc/size_overflow_plugin.c -@@ -0,0 +1,2114 @@ +@@ -0,0 +1,2113 @@ +/* + * Copyright 2011, 2012, 2013 by Emese Revfy <re.emese@gmail.com> + * Licensed under the GPL v2, or (at your option) v3 @@ -106286,7 +107962,7 @@ index 0000000..9db0d0e +static void print_missing_msg(tree func, unsigned int argnum); + +static struct plugin_info size_overflow_plugin_info = { -+ .version = "20130410beta", ++ .version = "20130822beta", + .help = "no-size-overflow\tturn off size overflow checking\n", +}; + @@ -106666,7 +108342,6 @@ index 0000000..9db0d0e + +#if BUILDING_GCC_VERSION <= 4007 + add_referenced_var(new_var); -+ mark_sym_for_renaming(new_var); +#endif + return new_var; +} diff --git a/main/linux-grsec/kernelconfig.x86 b/main/linux-grsec/kernelconfig.x86 index 36a0fef5af..5af34f6110 100644 --- a/main/linux-grsec/kernelconfig.x86 +++ b/main/linux-grsec/kernelconfig.x86 @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/x86 3.10.4 Kernel Configuration +# Linux/x86 3.10.10 Kernel Configuration # # CONFIG_64BIT is not set CONFIG_X86_32=y @@ -5634,6 +5634,11 @@ CONFIG_GRKERNSEC_NO_SIMULT_CONNECT=y # CONFIG_GRKERNSEC_SOCKET is not set # +# Physical Protections +# +# CONFIG_GRKERNSEC_DENYUSB is not set + +# # Sysctl Support # CONFIG_GRKERNSEC_SYSCTL=y diff --git a/main/linux-grsec/kernelconfig.x86_64 b/main/linux-grsec/kernelconfig.x86_64 index 3e48639202..9732d747e8 100644 --- a/main/linux-grsec/kernelconfig.x86_64 +++ b/main/linux-grsec/kernelconfig.x86_64 @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/x86 3.10.4 Kernel Configuration +# Linux/x86 3.10.10 Kernel Configuration # CONFIG_64BIT=y CONFIG_X86_64=y @@ -5571,6 +5571,11 @@ CONFIG_GRKERNSEC_NO_SIMULT_CONNECT=y # CONFIG_GRKERNSEC_SOCKET is not set # +# Physical Protections +# +# CONFIG_GRKERNSEC_DENYUSB is not set + +# # Sysctl Support # CONFIG_GRKERNSEC_SYSCTL=y |