summaryrefslogtreecommitdiff
path: root/sys-kernel/linux-image-redcore-lts-legacy/files/4.19-linux-hardened.patch
diff options
context:
space:
mode:
authorV3n3RiX <venerix@redcorelinux.org>2020-12-19 13:38:08 +0000
committerV3n3RiX <venerix@redcorelinux.org>2020-12-19 13:38:08 +0000
commit05f78d9ab50a90099057de93015e0b89161081b5 (patch)
tree586330f17a1222ef2c81f156d0ca345a9209825d /sys-kernel/linux-image-redcore-lts-legacy/files/4.19-linux-hardened.patch
parentbe4205ac29a871c8c8d740868d5437fc25adcfbb (diff)
sys-kernel : drop kernel 4.19
Diffstat (limited to 'sys-kernel/linux-image-redcore-lts-legacy/files/4.19-linux-hardened.patch')
-rw-r--r--sys-kernel/linux-image-redcore-lts-legacy/files/4.19-linux-hardened.patch3846
1 files changed, 0 insertions, 3846 deletions
diff --git a/sys-kernel/linux-image-redcore-lts-legacy/files/4.19-linux-hardened.patch b/sys-kernel/linux-image-redcore-lts-legacy/files/4.19-linux-hardened.patch
deleted file mode 100644
index fa3e9758..00000000
--- a/sys-kernel/linux-image-redcore-lts-legacy/files/4.19-linux-hardened.patch
+++ /dev/null
@@ -1,3846 +0,0 @@
-diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
-index 30752db57587..77f250bbcba7 100644
---- a/Documentation/admin-guide/kernel-parameters.txt
-+++ b/Documentation/admin-guide/kernel-parameters.txt
-@@ -500,16 +500,6 @@
- nosocket -- Disable socket memory accounting.
- nokmem -- Disable kernel memory accounting.
-
-- checkreqprot [SELINUX] Set initial checkreqprot flag value.
-- Format: { "0" | "1" }
-- See security/selinux/Kconfig help text.
-- 0 -- check protection applied by kernel (includes
-- any implied execute protection).
-- 1 -- check protection requested by application.
-- Default value is set via a kernel config option.
-- Value can be changed at runtime via
-- /selinux/checkreqprot.
--
- cio_ignore= [S390]
- See Documentation/s390/CommonIO for details.
- clk_ignore_unused
-@@ -3211,6 +3201,11 @@
- the specified number of seconds. This is to be used if
- your oopses keep scrolling off the screen.
-
-+ extra_latent_entropy
-+ Enable a very simple form of latent entropy extraction
-+ from the first 4GB of memory as the bootmem allocator
-+ passes the memory pages to the buddy allocator.
-+
- pcbit= [HW,ISDN]
-
- pcd. [PARIDE]
-diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt
-index 37a679501ddc..59b747920f4d 100644
---- a/Documentation/sysctl/kernel.txt
-+++ b/Documentation/sysctl/kernel.txt
-@@ -94,6 +94,7 @@ show up in /proc/sys/kernel:
- - sysctl_writes_strict
- - tainted
- - threads-max
-+- tiocsti_restrict
- - unknown_nmi_panic
- - watchdog
- - watchdog_thresh
-@@ -1041,6 +1042,26 @@ available RAM pages threads-max is reduced accordingly.
-
- ==============================================================
-
-+tiocsti_restrict:
-+
-+This toggle indicates whether unprivileged users are prevented
-+from using the TIOCSTI ioctl to inject commands into other processes
-+which share a tty session.
-+
-+When tiocsti_restrict is set to (0) there are no restrictions(accept
-+the default restriction of only being able to injection commands into
-+one's own tty). When tiocsti_restrict is set to (1), users must
-+have CAP_SYS_ADMIN to use the TIOCSTI ioctl.
-+
-+When user namespaces are in use, the check for the capability
-+CAP_SYS_ADMIN is done against the user namespace that originally
-+opened the tty.
-+
-+The kernel config option CONFIG_SECURITY_TIOCSTI_RESTRICT sets the
-+default value of tiocsti_restrict.
-+
-+==============================================================
-+
- unknown_nmi_panic:
-
- The value in this file affects behavior of handling NMI. When the
-diff --git a/Makefile b/Makefile
-index 605a6a2e03dc..2359c3d46cd4 100644
---- a/Makefile
-+++ b/Makefile
-@@ -686,6 +686,9 @@ stackp-flags-$(CONFIG_STACKPROTECTOR_STRONG) := -fstack-protector-strong
- KBUILD_CFLAGS += $(stackp-flags-y)
-
- ifeq ($(cc-name),clang)
-+ifdef CONFIG_LOCAL_INIT
-+KBUILD_CFLAGS += -fsanitize=local-init
-+endif
- KBUILD_CPPFLAGS += $(call cc-option,-Qunused-arguments,)
- KBUILD_CFLAGS += $(call cc-disable-warning, format-invalid-specifier)
- KBUILD_CFLAGS += $(call cc-disable-warning, gnu)
-diff --git a/arch/Kconfig b/arch/Kconfig
-index a336548487e6..bbe821420e7a 100644
---- a/arch/Kconfig
-+++ b/arch/Kconfig
-@@ -599,7 +599,7 @@ config ARCH_MMAP_RND_BITS
- int "Number of bits to use for ASLR of mmap base address" if EXPERT
- range ARCH_MMAP_RND_BITS_MIN ARCH_MMAP_RND_BITS_MAX
- default ARCH_MMAP_RND_BITS_DEFAULT if ARCH_MMAP_RND_BITS_DEFAULT
-- default ARCH_MMAP_RND_BITS_MIN
-+ default ARCH_MMAP_RND_BITS_MAX
- depends on HAVE_ARCH_MMAP_RND_BITS
- help
- This value can be used to select the number of bits to use to
-@@ -633,7 +633,7 @@ config ARCH_MMAP_RND_COMPAT_BITS
- int "Number of bits to use for ASLR of mmap base address for compatible applications" if EXPERT
- range ARCH_MMAP_RND_COMPAT_BITS_MIN ARCH_MMAP_RND_COMPAT_BITS_MAX
- default ARCH_MMAP_RND_COMPAT_BITS_DEFAULT if ARCH_MMAP_RND_COMPAT_BITS_DEFAULT
-- default ARCH_MMAP_RND_COMPAT_BITS_MIN
-+ default ARCH_MMAP_RND_COMPAT_BITS_MAX
- depends on HAVE_ARCH_MMAP_RND_COMPAT_BITS
- help
- This value can be used to select the number of bits to use to
-@@ -838,6 +838,7 @@ config ARCH_HAS_REFCOUNT
-
- config REFCOUNT_FULL
- bool "Perform full reference count validation at the expense of speed"
-+ default y
- help
- Enabling this switches the refcounting infrastructure from a fast
- unchecked atomic_t implementation to a fully state checked
-diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
-index 1fe3e5cb2927..7683d9c7d0dc 100644
---- a/arch/arm64/Kconfig
-+++ b/arch/arm64/Kconfig
-@@ -1049,6 +1049,7 @@ endif
-
- config ARM64_SW_TTBR0_PAN
- bool "Emulate Privileged Access Never using TTBR0_EL1 switching"
-+ default y
- help
- Enabling this option prevents the kernel from accessing
- user-space memory directly by pointing TTBR0_EL1 to a reserved
-@@ -1224,6 +1225,7 @@ config RANDOMIZE_BASE
- bool "Randomize the address of the kernel image"
- select ARM64_MODULE_PLTS if MODULES
- select RELOCATABLE
-+ default y
- help
- Randomizes the virtual address at which the kernel image is
- loaded, as a security feature that deters exploit attempts
-diff --git a/arch/arm64/Kconfig.debug b/arch/arm64/Kconfig.debug
-index 69c9170bdd24..a786227db0e3 100644
---- a/arch/arm64/Kconfig.debug
-+++ b/arch/arm64/Kconfig.debug
-@@ -42,6 +42,7 @@ config ARM64_RANDOMIZE_TEXT_OFFSET
- config DEBUG_WX
- bool "Warn on W+X mappings at boot"
- select ARM64_PTDUMP_CORE
-+ default y
- ---help---
- Generate a warning if any W+X mappings are found at boot.
-
-diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
-index 1a4f8b67bbe8..85273063eb56 100644
---- a/arch/arm64/configs/defconfig
-+++ b/arch/arm64/configs/defconfig
-@@ -1,4 +1,3 @@
--CONFIG_SYSVIPC=y
- CONFIG_POSIX_MQUEUE=y
- CONFIG_AUDIT=y
- CONFIG_NO_HZ_IDLE=y
-diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
-index 433b9554c6a1..1f4b06317c9f 100644
---- a/arch/arm64/include/asm/elf.h
-+++ b/arch/arm64/include/asm/elf.h
-@@ -114,10 +114,10 @@
-
- /*
- * This is the base location for PIE (ET_DYN with INTERP) loads. On
-- * 64-bit, this is above 4GB to leave the entire 32-bit address
-+ * 64-bit, this is raised to 4GB to leave the entire 32-bit address
- * space open for things that want to use the area for 32-bit pointers.
- */
--#define ELF_ET_DYN_BASE (2 * TASK_SIZE_64 / 3)
-+#define ELF_ET_DYN_BASE 0x100000000UL
-
- #ifndef __ASSEMBLY__
-
-@@ -171,10 +171,10 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
- /* 1GB of VA */
- #ifdef CONFIG_COMPAT
- #define STACK_RND_MASK (test_thread_flag(TIF_32BIT) ? \
-- 0x7ff >> (PAGE_SHIFT - 12) : \
-- 0x3ffff >> (PAGE_SHIFT - 12))
-+ ((1UL << mmap_rnd_compat_bits) - 1) >> (PAGE_SHIFT - 12) : \
-+ ((1UL << mmap_rnd_bits) - 1) >> (PAGE_SHIFT - 12))
- #else
--#define STACK_RND_MASK (0x3ffff >> (PAGE_SHIFT - 12))
-+#define STACK_RND_MASK (((1UL << mmap_rnd_bits) - 1) >> (PAGE_SHIFT - 12))
- #endif
-
- #ifdef __AARCH64EB__
-diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
-index d6a49bb07a5f..16e4214c2305 100644
---- a/arch/arm64/kernel/process.c
-+++ b/arch/arm64/kernel/process.c
-@@ -517,9 +517,9 @@ unsigned long arch_align_stack(unsigned long sp)
- unsigned long arch_randomize_brk(struct mm_struct *mm)
- {
- if (is_compat_task())
-- return randomize_page(mm->brk, SZ_32M);
-+ return mm->brk + get_random_long() % SZ_32M + PAGE_SIZE;
- else
-- return randomize_page(mm->brk, SZ_1G);
-+ return mm->brk + get_random_long() % SZ_1G + PAGE_SIZE;
- }
-
- /*
-diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
-index af35f5caadbe..34e88af114bd 100644
---- a/arch/x86/Kconfig
-+++ b/arch/x86/Kconfig
-@@ -1189,8 +1189,7 @@ config VM86
- default X86_LEGACY_VM86
-
- config X86_16BIT
-- bool "Enable support for 16-bit segments" if EXPERT
-- default y
-+ bool "Enable support for 16-bit segments"
- depends on MODIFY_LDT_SYSCALL
- ---help---
- This option is required by programs like Wine to run 16-bit
-@@ -2319,7 +2318,7 @@ config COMPAT_VDSO
- choice
- prompt "vsyscall table for legacy applications"
- depends on X86_64
-- default LEGACY_VSYSCALL_EMULATE
-+ default LEGACY_VSYSCALL_NONE
- help
- Legacy user code that does not know how to find the vDSO expects
- to be able to issue three syscalls by calling fixed addresses in
-@@ -2400,8 +2399,7 @@ config CMDLINE_OVERRIDE
- be set to 'N' under normal conditions.
-
- config MODIFY_LDT_SYSCALL
-- bool "Enable the LDT (local descriptor table)" if EXPERT
-- default y
-+ bool "Enable the LDT (local descriptor table)"
- ---help---
- Linux can allow user programs to install a per-process x86
- Local Descriptor Table (LDT) using the modify_ldt(2) system
-diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
-index 687cd1a213d5..29075c2bc51f 100644
---- a/arch/x86/Kconfig.debug
-+++ b/arch/x86/Kconfig.debug
-@@ -101,6 +101,7 @@ config EFI_PGT_DUMP
- config DEBUG_WX
- bool "Warn on W+X mappings at boot"
- select X86_PTDUMP_CORE
-+ default y
- ---help---
- Generate a warning if any W+X mappings are found at boot.
-
-diff --git a/arch/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig
-index e32fc1f274d8..d08acc76502a 100644
---- a/arch/x86/configs/x86_64_defconfig
-+++ b/arch/x86/configs/x86_64_defconfig
-@@ -1,5 +1,4 @@
- # CONFIG_LOCALVERSION_AUTO is not set
--CONFIG_SYSVIPC=y
- CONFIG_POSIX_MQUEUE=y
- CONFIG_BSD_PROCESS_ACCT=y
- CONFIG_TASKSTATS=y
-diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c
-index 5b8b556dbb12..a569f08b4478 100644
---- a/arch/x86/entry/vdso/vma.c
-+++ b/arch/x86/entry/vdso/vma.c
-@@ -204,55 +204,9 @@ static int map_vdso(const struct vdso_image *image, unsigned long addr)
- }
-
- #ifdef CONFIG_X86_64
--/*
-- * Put the vdso above the (randomized) stack with another randomized
-- * offset. This way there is no hole in the middle of address space.
-- * To save memory make sure it is still in the same PTE as the stack
-- * top. This doesn't give that many random bits.
-- *
-- * Note that this algorithm is imperfect: the distribution of the vdso
-- * start address within a PMD is biased toward the end.
-- *
-- * Only used for the 64-bit and x32 vdsos.
-- */
--static unsigned long vdso_addr(unsigned long start, unsigned len)
--{
-- unsigned long addr, end;
-- unsigned offset;
--
-- /*
-- * Round up the start address. It can start out unaligned as a result
-- * of stack start randomization.
-- */
-- start = PAGE_ALIGN(start);
--
-- /* Round the lowest possible end address up to a PMD boundary. */
-- end = (start + len + PMD_SIZE - 1) & PMD_MASK;
-- if (end >= TASK_SIZE_MAX)
-- end = TASK_SIZE_MAX;
-- end -= len;
--
-- if (end > start) {
-- offset = get_random_int() % (((end - start) >> PAGE_SHIFT) + 1);
-- addr = start + (offset << PAGE_SHIFT);
-- } else {
-- addr = start;
-- }
--
-- /*
-- * Forcibly align the final address in case we have a hardware
-- * issue that requires alignment for performance reasons.
-- */
-- addr = align_vdso_addr(addr);
--
-- return addr;
--}
--
- static int map_vdso_randomized(const struct vdso_image *image)
- {
-- unsigned long addr = vdso_addr(current->mm->start_stack, image->size-image->sym_vvar_start);
--
-- return map_vdso(image, addr);
-+ return map_vdso(image, 0);
- }
- #endif
-
-diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
-index 0d157d2a1e2a..770c8ae97f92 100644
---- a/arch/x86/include/asm/elf.h
-+++ b/arch/x86/include/asm/elf.h
-@@ -249,11 +249,11 @@ extern int force_personality32;
-
- /*
- * This is the base location for PIE (ET_DYN with INTERP) loads. On
-- * 64-bit, this is above 4GB to leave the entire 32-bit address
-+ * 64-bit, this is raised to 4GB to leave the entire 32-bit address
- * space open for things that want to use the area for 32-bit pointers.
- */
- #define ELF_ET_DYN_BASE (mmap_is_ia32() ? 0x000400000UL : \
-- (DEFAULT_MAP_WINDOW / 3 * 2))
-+ 0x100000000UL)
-
- /* This yields a mask that user programs can use to figure out what
- instruction set this CPU supports. This could be done in user space,
-@@ -313,8 +313,8 @@ extern bool mmap_address_hint_valid(unsigned long addr, unsigned long len);
-
- #ifdef CONFIG_X86_32
-
--#define __STACK_RND_MASK(is32bit) (0x7ff)
--#define STACK_RND_MASK (0x7ff)
-+#define __STACK_RND_MASK(is32bit) ((1UL << mmap_rnd_bits) - 1)
-+#define STACK_RND_MASK ((1UL << mmap_rnd_bits) - 1)
-
- #define ARCH_DLINFO ARCH_DLINFO_IA32
-
-@@ -323,7 +323,11 @@ extern bool mmap_address_hint_valid(unsigned long addr, unsigned long len);
- #else /* CONFIG_X86_32 */
-
- /* 1GB for 64bit, 8MB for 32bit */
--#define __STACK_RND_MASK(is32bit) ((is32bit) ? 0x7ff : 0x3fffff)
-+#ifdef CONFIG_COMPAT
-+#define __STACK_RND_MASK(is32bit) ((is32bit) ? (1UL << mmap_rnd_compat_bits) - 1 : (1UL << mmap_rnd_bits) - 1)
-+#else
-+#define __STACK_RND_MASK(is32bit) ((1UL << mmap_rnd_bits) - 1)
-+#endif
- #define STACK_RND_MASK __STACK_RND_MASK(mmap_is_ia32())
-
- #define ARCH_DLINFO \
-@@ -381,5 +385,4 @@ struct va_alignment {
- } ____cacheline_aligned;
-
- extern struct va_alignment va_align;
--extern unsigned long align_vdso_addr(unsigned long);
- #endif /* _ASM_X86_ELF_H */
-diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
-index 79ec7add5f98..2950448e00ac 100644
---- a/arch/x86/include/asm/tlbflush.h
-+++ b/arch/x86/include/asm/tlbflush.h
-@@ -310,6 +310,7 @@ static inline void cr4_set_bits(unsigned long mask)
-
- local_irq_save(flags);
- cr4 = this_cpu_read(cpu_tlbstate.cr4);
-+ BUG_ON(cr4 != __read_cr4());
- if ((cr4 | mask) != cr4)
- __cr4_set(cr4 | mask);
- local_irq_restore(flags);
-@@ -322,6 +323,7 @@ static inline void cr4_clear_bits(unsigned long mask)
-
- local_irq_save(flags);
- cr4 = this_cpu_read(cpu_tlbstate.cr4);
-+ BUG_ON(cr4 != __read_cr4());
- if ((cr4 & ~mask) != cr4)
- __cr4_set(cr4 & ~mask);
- local_irq_restore(flags);
-@@ -332,6 +334,7 @@ static inline void cr4_toggle_bits_irqsoff(unsigned long mask)
- unsigned long cr4;
-
- cr4 = this_cpu_read(cpu_tlbstate.cr4);
-+ BUG_ON(cr4 != __read_cr4());
- __cr4_set(cr4 ^ mask);
- }
-
-@@ -438,6 +441,7 @@ static inline void __native_flush_tlb_global(void)
- raw_local_irq_save(flags);
-
- cr4 = this_cpu_read(cpu_tlbstate.cr4);
-+ BUG_ON(cr4 != __read_cr4());
- /* toggle PGE */
- native_write_cr4(cr4 ^ X86_CR4_PGE);
- /* write old PGE again and flush TLBs */
-diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
-index 2058e8c0e61d..820f8508aebb 100644
---- a/arch/x86/kernel/cpu/common.c
-+++ b/arch/x86/kernel/cpu/common.c
-@@ -1824,7 +1824,6 @@ void cpu_init(void)
- wrmsrl(MSR_KERNEL_GS_BASE, 0);
- barrier();
-
-- x86_configure_nx();
- x2apic_setup();
-
- /*
-diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
-index cd138bfd926c..2a6d5617d55c 100644
---- a/arch/x86/kernel/process.c
-+++ b/arch/x86/kernel/process.c
-@@ -39,6 +39,8 @@
- #include <asm/desc.h>
- #include <asm/prctl.h>
- #include <asm/spec-ctrl.h>
-+#include <asm/elf.h>
-+#include <linux/sizes.h>
-
- #include "process.h"
-
-@@ -775,7 +777,10 @@ unsigned long arch_align_stack(unsigned long sp)
-
- unsigned long arch_randomize_brk(struct mm_struct *mm)
- {
-- return randomize_page(mm->brk, 0x02000000);
-+ if (mmap_is_ia32())
-+ return mm->brk + get_random_long() % SZ_32M + PAGE_SIZE;
-+ else
-+ return mm->brk + get_random_long() % SZ_1G + PAGE_SIZE;
- }
-
- /*
-diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
-index 6a78d4b36a79..715009f7a96c 100644
---- a/arch/x86/kernel/sys_x86_64.c
-+++ b/arch/x86/kernel/sys_x86_64.c
-@@ -54,13 +54,6 @@ static unsigned long get_align_bits(void)
- return va_align.bits & get_align_mask();
- }
-
--unsigned long align_vdso_addr(unsigned long addr)
--{
-- unsigned long align_mask = get_align_mask();
-- addr = (addr + align_mask) & ~align_mask;
-- return addr | get_align_bits();
--}
--
- static int __init control_va_addr_alignment(char *str)
- {
- /* guard against enabling this on other CPU families */
-@@ -122,10 +115,7 @@ static void find_start_end(unsigned long addr, unsigned long flags,
- }
-
- *begin = get_mmap_base(1);
-- if (in_compat_syscall())
-- *end = task_size_32bit();
-- else
-- *end = task_size_64bit(addr > DEFAULT_MAP_WINDOW);
-+ *end = get_mmap_base(0);
- }
-
- unsigned long
-@@ -210,7 +200,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
-
- info.flags = VM_UNMAPPED_AREA_TOPDOWN;
- info.length = len;
-- info.low_limit = PAGE_SIZE;
-+ info.low_limit = get_mmap_base(1);
- info.high_limit = get_mmap_base(0);
-
- /*
-diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
-index 79b95910fd9f..fcda13aa03d0 100644
---- a/arch/x86/mm/init_32.c
-+++ b/arch/x86/mm/init_32.c
-@@ -560,9 +560,9 @@ static void __init pagetable_init(void)
-
- #define DEFAULT_PTE_MASK ~(_PAGE_NX | _PAGE_GLOBAL)
- /* Bits supported by the hardware: */
--pteval_t __supported_pte_mask __read_mostly = DEFAULT_PTE_MASK;
-+pteval_t __supported_pte_mask __ro_after_init = DEFAULT_PTE_MASK;
- /* Bits allowed in normal kernel mappings: */
--pteval_t __default_kernel_pte_mask __read_mostly = DEFAULT_PTE_MASK;
-+pteval_t __default_kernel_pte_mask __ro_after_init = DEFAULT_PTE_MASK;
- EXPORT_SYMBOL_GPL(__supported_pte_mask);
- /* Used in PAGE_KERNEL_* macros which are reasonably used out-of-tree: */
- EXPORT_SYMBOL(__default_kernel_pte_mask);
-@@ -870,7 +870,7 @@ void arch_remove_memory(int nid, u64 start, u64 size,
- }
- #endif
-
--int kernel_set_to_readonly __read_mostly;
-+int kernel_set_to_readonly __ro_after_init;
-
- void set_kernel_text_rw(void)
- {
-@@ -922,12 +922,11 @@ void mark_rodata_ro(void)
- unsigned long start = PFN_ALIGN(_text);
- unsigned long size = PFN_ALIGN(_etext) - start;
-
-+ kernel_set_to_readonly = 1;
- set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT);
- printk(KERN_INFO "Write protecting the kernel text: %luk\n",
- size >> 10);
-
-- kernel_set_to_readonly = 1;
--
- #ifdef CONFIG_CPA_DEBUG
- printk(KERN_INFO "Testing CPA: Reverting %lx-%lx\n",
- start, start+size);
-diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
-index 81e85a8dd300..f0403d1ba1b0 100644
---- a/arch/x86/mm/init_64.c
-+++ b/arch/x86/mm/init_64.c
-@@ -66,9 +66,9 @@
- */
-
- /* Bits supported by the hardware: */
--pteval_t __supported_pte_mask __read_mostly = ~0;
-+pteval_t __supported_pte_mask __ro_after_init = ~0;
- /* Bits allowed in normal kernel mappings: */
--pteval_t __default_kernel_pte_mask __read_mostly = ~0;
-+pteval_t __default_kernel_pte_mask __ro_after_init = ~0;
- EXPORT_SYMBOL_GPL(__supported_pte_mask);
- /* Used in PAGE_KERNEL_* macros which are reasonably used out-of-tree: */
- EXPORT_SYMBOL(__default_kernel_pte_mask);
-@@ -1190,7 +1190,7 @@ void __init mem_init(void)
- mem_init_print_info(NULL);
- }
-
--int kernel_set_to_readonly;
-+int kernel_set_to_readonly __ro_after_init;
-
- void set_kernel_text_rw(void)
- {
-@@ -1239,9 +1239,8 @@ void mark_rodata_ro(void)
-
- printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n",
- (end - start) >> 10);
-- set_memory_ro(start, (end - start) >> PAGE_SHIFT);
--
- kernel_set_to_readonly = 1;
-+ set_memory_ro(start, (end - start) >> PAGE_SHIFT);
-
- /*
- * The rodata/data/bss/brk section (but not the kernel text!)
-diff --git a/block/blk-softirq.c b/block/blk-softirq.c
-index 15c1f5e12eb8..ff72cccec5b8 100644
---- a/block/blk-softirq.c
-+++ b/block/blk-softirq.c
-@@ -20,7 +20,7 @@ static DEFINE_PER_CPU(struct list_head, blk_cpu_done);
- * Softirq action handler - move entries to local list and loop over them
- * while passing them to the queue registered handler.
- */
--static __latent_entropy void blk_done_softirq(struct softirq_action *h)
-+static __latent_entropy void blk_done_softirq(void)
- {
- struct list_head *cpu_list, local_list;
-
-diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
-index 6b372fa58382..68c4f17e027f 100644
---- a/drivers/ata/libata-core.c
-+++ b/drivers/ata/libata-core.c
-@@ -5160,7 +5160,7 @@ void ata_qc_free(struct ata_queued_cmd *qc)
- struct ata_port *ap;
- unsigned int tag;
-
-- WARN_ON_ONCE(qc == NULL); /* ata_qc_from_tag _might_ return NULL */
-+ BUG_ON(qc == NULL); /* ata_qc_from_tag _might_ return NULL */
- ap = qc->ap;
-
- qc->flags = 0;
-@@ -5177,7 +5177,7 @@ void __ata_qc_complete(struct ata_queued_cmd *qc)
- struct ata_port *ap;
- struct ata_link *link;
-
-- WARN_ON_ONCE(qc == NULL); /* ata_qc_from_tag _might_ return NULL */
-+ BUG_ON(qc == NULL); /* ata_qc_from_tag _might_ return NULL */
- WARN_ON_ONCE(!(qc->flags & ATA_QCFLAG_ACTIVE));
- ap = qc->ap;
- link = qc->dev->link;
-diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
-index 1df9cb8e659e..eb71148a4a69 100644
---- a/drivers/char/Kconfig
-+++ b/drivers/char/Kconfig
-@@ -9,7 +9,6 @@ source "drivers/tty/Kconfig"
-
- config DEVMEM
- bool "/dev/mem virtual device support"
-- default y
- help
- Say Y here if you want to support the /dev/mem device.
- The /dev/mem device is used to access areas of physical
-@@ -531,7 +530,6 @@ config TELCLOCK
- config DEVPORT
- bool "/dev/port character device"
- depends on ISA || PCI
-- default y
- help
- Say Y here if you want to support the /dev/port device. The /dev/port
- device is similar to /dev/mem, but for I/O ports.
-diff --git a/drivers/char/random.c b/drivers/char/random.c
-index d5f970d039bb..38f184022af7 100644
---- a/drivers/char/random.c
-+++ b/drivers/char/random.c
-@@ -281,11 +281,20 @@
- /*
- * Configuration information
- */
-+#ifdef CONFIG_HARDENED_RANDOM
-+#define INPUT_POOL_SHIFT 18
-+#define OUTPUT_POOL_SHIFT 16
-+#else
- #define INPUT_POOL_SHIFT 12
--#define INPUT_POOL_WORDS (1 << (INPUT_POOL_SHIFT-5))
- #define OUTPUT_POOL_SHIFT 10
-+#endif
-+#define INPUT_POOL_WORDS (1 << (INPUT_POOL_SHIFT-5))
- #define OUTPUT_POOL_WORDS (1 << (OUTPUT_POOL_SHIFT-5))
-+#ifdef CONFIG_HARDENED_RANDOM
-+#define SEC_XFER_SIZE 32768
-+#else
- #define SEC_XFER_SIZE 512
-+#endif
- #define EXTRACT_SIZE 10
-
-
-@@ -294,9 +303,6 @@
- /*
- * To allow fractional bits to be tracked, the entropy_count field is
- * denominated in units of 1/8th bits.
-- *
-- * 2*(ENTROPY_SHIFT + log2(poolbits)) must <= 31, or the multiply in
-- * credit_entropy_bits() needs to be 64 bits wide.
- */
- #define ENTROPY_SHIFT 3
- #define ENTROPY_BITS(r) ((r)->entropy_count >> ENTROPY_SHIFT)
-@@ -361,15 +367,27 @@ static int random_write_wakeup_bits = 28 * OUTPUT_POOL_WORDS;
- */
- static struct poolinfo {
- int poolbitshift, poolwords, poolbytes, poolbits, poolfracbits;
--#define S(x) ilog2(x)+5, (x), (x)*4, (x)*32, (x) << (ENTROPY_SHIFT+5)
-- int tap1, tap2, tap3, tap4, tap5;
--} poolinfo_table[] = {
-+#define S(x) \
-+ .poolbitshift = ilog2(x)+5, \
-+ .poolwords = (x), \
-+ .poolbytes = (x)*4, \
-+ .poolbits = (x)*32, \
-+ .poolfracbits = (x) << (ENTROPY_SHIFT+5)
-+ int tap[5];
-+} __randomize_layout poolinfo_table[] = {
-+#ifdef CONFIG_HARDENED_RANDOM
-+ /* x^8192 + x^104 + x^76 + x^51 +x^25 + x + 1 */
-+ { S(8192), .tap = { 104, 76, 51, 25, 1 } },
-+ /* x^2048 + x^26 + x^19 + x^14 + x^7 + x + 1 */
-+ { S(2048), .tap = { 26, 19, 14, 7, 1 } }
-+#else
- /* was: x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 */
- /* x^128 + x^104 + x^76 + x^51 +x^25 + x + 1 */
-- { S(128), 104, 76, 51, 25, 1 },
-+ { S(128), .tap = { 104, 76, 51, 25, 1 } },
- /* was: x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 */
- /* x^32 + x^26 + x^19 + x^14 + x^7 + x + 1 */
-- { S(32), 26, 19, 14, 7, 1 },
-+ { S(32), .tap = { 26, 19, 14, 7, 1 } },
-+#endif
- #if 0
- /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */
- { S(2048), 1638, 1231, 819, 411, 1 },
-@@ -413,7 +431,7 @@ struct crng_state {
- __u32 state[16];
- unsigned long init_time;
- spinlock_t lock;
--};
-+} __randomize_layout;
-
- struct crng_state primary_crng = {
- .lock = __SPIN_LOCK_UNLOCKED(primary_crng.lock),
-@@ -475,7 +493,7 @@ struct entropy_store {
- unsigned int initialized:1;
- unsigned int last_data_init:1;
- __u8 last_data[EXTRACT_SIZE];
--};
-+} __randomize_layout;
-
- static ssize_t extract_entropy(struct entropy_store *r, void *buf,
- size_t nbytes, int min, int rsvd);
-@@ -486,6 +504,8 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r);
- static void push_to_pool(struct work_struct *work);
- static __u32 input_pool_data[INPUT_POOL_WORDS] __latent_entropy;
- static __u32 blocking_pool_data[OUTPUT_POOL_WORDS] __latent_entropy;
-+/* this actually doesn't need latent entropy */
-+static __u32 secondary_xfer_buffer[OUTPUT_POOL_WORDS];
-
- static struct entropy_store input_pool = {
- .poolinfo = &poolinfo_table[0],
-@@ -504,9 +524,78 @@ static struct entropy_store blocking_pool = {
- push_to_pool),
- };
-
-+#ifdef CONFIG_HARDENED_RANDOM
-+static __u32 const twist_table[64][4] = {
-+ { 0x6a09e668, 0xbb67ae86, 0x3c6ef373, 0xa54ff53a },
-+ { 0x510e5280, 0x9b05688c, 0x1f83d9ac, 0x5be0cd19 },
-+ { 0xcbbb9d5e, 0x629a292a, 0x9159015a, 0x152fecd9 },
-+ { 0x67332668, 0x8eb44a87, 0xdb0c2e0d, 0x47b5481e },
-+ { 0xae5f9157, 0xcf6c85d4, 0x2f73477d, 0x6d1826cb },
-+ { 0x8b43d457, 0xe360b597, 0x1c456003, 0x6f196331 },
-+ { 0xd94ebeb2, 0x0cc4a612, 0x261dc1f3, 0x5815a7be },
-+ { 0x70b7ed68, 0xa1513c69, 0x44f93636, 0x720dcdfe },
-+ { 0xb467369e, 0xca320b76, 0x34e0d42e, 0x49c7d9be },
-+ { 0x87abb9f2, 0xc463a2fc, 0xec3fc3f4, 0x27277f6d },
-+ { 0x610bebf3, 0x7420b49f, 0xd1fd8a34, 0xe4773594 },
-+ { 0x092197f6, 0x1b530c96, 0x869d6343, 0xeee52e50 },
-+ { 0x1107668a, 0x21fba37c, 0x43ab9fb6, 0x75a9f91d },
-+ { 0x8630501a, 0xd7cd8174, 0x007fe010, 0x0379f514 },
-+ { 0x066b651b, 0x0764ab84, 0x0a4b06be, 0x0c3578c1 },
-+ { 0x0d2962a5, 0x11e039f4, 0x1857b7bf, 0x1a29bf2e },
-+ { 0x1b11a32f, 0x1cdf34e8, 0x23183042, 0x25b89093 },
-+ { 0x2a0c06a1, 0x2ae79843, 0x2c9cda69, 0x2f281f24 },
-+ { 0x32841259, 0x3502e64e, 0x377c9c21, 0x39204cda },
-+ { 0x3b91bf66, 0x3ecc38ca, 0x40665609, 0x43947938 },
-+ { 0x47830769, 0x484ae4b8, 0x4c2b2b75, 0x4cf03d21 },
-+ { 0x4f3cbb11, 0x50c2d3b5, 0x5308af16, 0x560a7a9a },
-+ { 0x5788d981, 0x584769b4, 0x59c34f06, 0x5e2d564c },
-+ { 0x6116d760, 0x62894c10, 0x6569b58c, 0x66d7b394 },
-+ { 0x68f9f8dc, 0x6d34f03d, 0x6de8372f, 0x742687a4 },
-+ { 0x76356021, 0x799d1235, 0x7ba455f4, 0x7da8d73b },
-+ { 0x7e546743, 0x80554bdc, 0x83a63a3c, 0x85a01e39 },
-+ { 0x879774ac, 0x883eac9f, 0x8a32aae0, 0x8c243210 },
-+ { 0x8d6e8781, 0x8e134b6f, 0x91ea5892, 0x95166fe4 },
-+ { 0x95b817e6, 0x96faa747, 0x98dca135, 0x9abc6593 },
-+ { 0x9b5bd55a, 0x9f136df7, 0xa04ebd79, 0xa225f6ed },
-+ { 0xa4970e49, 0xa79f5a6b, 0xaa0869af, 0xad06dcbd },
-+ { 0xaf68312e, 0xb12efe0b, 0xb2f3ef5b, 0xb420e03a },
-+ { 0xb6785656, 0xb837d738, 0xb9613115, 0xbbb18efb },
-+ { 0xbcd89621, 0xc0db3814, 0xc3b2f2a3, 0xc71638d9 },
-+ { 0xc7a6240f, 0xca73166e, 0xcb01f3ba, 0xcc1f293d },
-+ { 0xccad81c8, 0xcf72acaf, 0xd34c7258, 0xd4649b7a },
-+ { 0xd4f07147, 0xd607a013, 0xd9d3b47b, 0xdae803b5 },
-+ { 0xdb71ef1a, 0xdc854e24, 0xe1dcf0ea, 0xe2eca719 },
-+ { 0xe50a4ad8, 0xe7ac0990, 0xe9c46d3a, 0xeacfc33c },
-+ { 0xec5fb417, 0xedee611c, 0xf18bc533, 0xf292ef77 },
-+ { 0xf41cab36, 0xf5a531ec, 0xf7aeb45d, 0xf93474e9 },
-+ { 0xfc3c7559, 0xfd3e1962, 0xfebf9bc1, 0xff3fdbf2 },
-+ { 0x01bf3cab, 0x023ebd6b, 0x03bc8288, 0x06365a0f },
-+ { 0x06b4c1d2, 0x092afcc1, 0x09a8ad2c, 0x0b21093c },
-+ { 0x0f83d25e, 0x107c1074, 0x10f803d0, 0x11ef938d },
-+ { 0x136212e8, 0x14d390a4, 0x16beab25, 0x182dd7d5 },
-+ { 0x199c09bf, 0x1ed27f46, 0x1f4b2d3e, 0x21a502bc },
-+ { 0x23849e06, 0x25d9d3da, 0x273ef0ca, 0x28a326f6 },
-+ { 0x2a7cb5e4, 0x2d4019ba, 0x2e2b1e73, 0x2f8aec73 },
-+ { 0x30e9ddcc, 0x315ea828, 0x32bc75cf, 0x357587f0 },
-+ { 0x37b7de93, 0x3bc31ec6, 0x3c35b24a, 0x3d1a949b },
-+ { 0x3e713d15, 0x3ee347da, 0x4038e0bf, 0x411c2bae },
-+ { 0x418daf9a, 0x4270749e, 0x4516b0b0, 0x45876dcb },
-+ { 0x46d92246, 0x4e448a56, 0x4f9141c0, 0x50dd3e71 },
-+ { 0x5296c45b, 0x56738aac, 0x58961d02, 0x5b9010c1 },
-+ { 0x5c6913ae, 0x5cd577f2, 0x5dae0649, 0x5ef24aeb },
-+ { 0x60a199af, 0x6178ce9b, 0x61e44c97, 0x6326551c },
-+ { 0x65a86b29, 0x67bd7e12, 0x6827e41c, 0x68fc7925 },
-+ { 0x6966a836, 0x6a3acfa3, 0x6b78828a, 0x6df2017d },
-+ { 0x7068fdbb, 0x720c4495, 0x747f226b, 0x75b7a753 },
-+ { 0x7687a9e0, 0x77bf2d48, 0x795d98d4, 0x7a2c690b },
-+ { 0x7bc93fa8, 0x7c974690, 0x7f6653f3, 0x80333127 },
-+ { 0x81660244, 0x81cc2760, 0x829840e3, 0x83c9edd4 }
-+};
-+#else
- static __u32 const twist_table[8] = {
- 0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158,
- 0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 };
-+#endif
-
- /*
- * This function adds bytes into the entropy "pool". It does not
-@@ -521,17 +610,14 @@ static __u32 const twist_table[8] = {
- static void _mix_pool_bytes(struct entropy_store *r, const void *in,
- int nbytes)
- {
-- unsigned long i, tap1, tap2, tap3, tap4, tap5;
-+ unsigned long i, n, t1, t2, tap[5];
- int input_rotate;
- int wordmask = r->poolinfo->poolwords - 1;
- const char *bytes = in;
- __u32 w;
-
-- tap1 = r->poolinfo->tap1;
-- tap2 = r->poolinfo->tap2;
-- tap3 = r->poolinfo->tap3;
-- tap4 = r->poolinfo->tap4;
-- tap5 = r->poolinfo->tap5;
-+ for (n = 0; n < 5; n++)
-+ tap[n] = r->poolinfo->tap[n];
-
- input_rotate = r->input_rotate;
- i = r->add_ptr;
-@@ -543,14 +629,17 @@ static void _mix_pool_bytes(struct entropy_store *r, const void *in,
-
- /* XOR in the various taps */
- w ^= r->pool[i];
-- w ^= r->pool[(i + tap1) & wordmask];
-- w ^= r->pool[(i + tap2) & wordmask];
-- w ^= r->pool[(i + tap3) & wordmask];
-- w ^= r->pool[(i + tap4) & wordmask];
-- w ^= r->pool[(i + tap5) & wordmask];
-+ for (n = 0; n < 5; n++)
-+ w ^= r->pool[(i + tap[n]) & wordmask];
-
- /* Mix the result back in with a twist */
-+#ifdef CONFIG_HARDENED_RANDOM
-+ t1 = rol32(w, 14) & 0x1FFF; // 0-63, 1111111111111
-+ t2 = rol32(w, t1) & 0x3; // 0-3, 11
-+ r->pool[i] = (w >> 3) ^ twist_table[t1][t2];
-+#else
- r->pool[i] = (w >> 3) ^ twist_table[w & 7];
-+#endif
-
- /*
- * Normally, we add 7 bits of rotation to the pool.
-@@ -588,7 +677,7 @@ struct fast_pool {
- unsigned long last;
- unsigned short reg_idx;
- unsigned char count;
--};
-+} __randomize_layout;
-
- /*
- * This is a fast mixing routine used by the interrupt randomness
-@@ -683,7 +772,7 @@ static void credit_entropy_bits(struct entropy_store *r, int nbits)
- /* The +2 corresponds to the /4 in the denominator */
-
- do {
-- unsigned int anfrac = min(pnfrac, pool_size/2);
-+ __u64 anfrac = min(pnfrac, pool_size/2);
- unsigned int add =
- ((pool_size - entropy_count)*anfrac*3) >> s;
-
-@@ -1061,7 +1150,7 @@ static ssize_t extract_crng_user(void __user *buf, size_t nbytes)
-
- extract_crng(tmp);
- i = min_t(int, nbytes, CHACHA20_BLOCK_SIZE);
-- if (copy_to_user(buf, tmp, i)) {
-+ if (i > sizeof(tmp) || copy_to_user(buf, tmp, i)) {
- ret = -EFAULT;
- break;
- }
-@@ -1089,9 +1178,9 @@ static ssize_t extract_crng_user(void __user *buf, size_t nbytes)
- struct timer_rand_state {
- cycles_t last_time;
- long last_delta, last_delta2;
--};
-+} __randomize_layout;
-
--#define INIT_TIMER_RAND_STATE { INITIAL_JIFFIES, };
-+#define INIT_TIMER_RAND_STATE { .last_time = INITIAL_JIFFIES };
-
- /*
- * Add device- or boot-specific data to the input pool to help
-@@ -1334,20 +1423,18 @@ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
-
- static void _xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
- {
-- __u32 tmp[OUTPUT_POOL_WORDS];
--
- int bytes = nbytes;
-
- /* pull at least as much as a wakeup */
- bytes = max_t(int, bytes, random_read_wakeup_bits / 8);
- /* but never more than the buffer size */
-- bytes = min_t(int, bytes, sizeof(tmp));
-+ bytes = min_t(int, bytes, sizeof(secondary_xfer_buffer));
-
- trace_xfer_secondary_pool(r->name, bytes * 8, nbytes * 8,
- ENTROPY_BITS(r), ENTROPY_BITS(r->pull));
-- bytes = extract_entropy(r->pull, tmp, bytes,
-+ bytes = extract_entropy(r->pull, secondary_xfer_buffer, bytes,
- random_read_wakeup_bits / 8, 0);
-- mix_pool_bytes(r, tmp, bytes);
-+ mix_pool_bytes(r, secondary_xfer_buffer, bytes);
- credit_entropy_bits(r, bytes*8);
- }
-
-@@ -1572,7 +1659,7 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
-
- extract_buf(r, tmp);
- i = min_t(int, nbytes, EXTRACT_SIZE);
-- if (copy_to_user(buf, tmp, i)) {
-+ if (i > sizeof(tmp) || copy_to_user(buf, tmp, i)) {
- ret = -EFAULT;
- break;
- }
-@@ -2276,7 +2363,7 @@ struct batched_entropy {
- };
- unsigned int position;
- spinlock_t batch_lock;
--};
-+} __randomize_layout;
-
- /*
- * Get a random word for internal kernel use only. The quality of the random
-diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig
-index e0a04bfc873e..ec93f827c599 100644
---- a/drivers/tty/Kconfig
-+++ b/drivers/tty/Kconfig
-@@ -122,7 +122,6 @@ config UNIX98_PTYS
-
- config LEGACY_PTYS
- bool "Legacy (BSD) PTY support"
-- default y
- ---help---
- A pseudo terminal (PTY) is a software device consisting of two
- halves: a master and a slave. The slave device behaves identical to
-diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
-index ac8025cd4a1f..a89e48f53fba 100644
---- a/drivers/tty/tty_io.c
-+++ b/drivers/tty/tty_io.c
-@@ -172,6 +172,7 @@ static void free_tty_struct(struct tty_struct *tty)
- put_device(tty->dev);
- kfree(tty->write_buf);
- tty->magic = 0xDEADDEAD;
-+ put_user_ns(tty->owner_user_ns);
- kfree(tty);
- }
-
-@@ -2177,11 +2178,19 @@ static int tty_fasync(int fd, struct file *filp, int on)
- * FIXME: may race normal receive processing
- */
-
-+int tiocsti_restrict = IS_ENABLED(CONFIG_SECURITY_TIOCSTI_RESTRICT);
-+
- static int tiocsti(struct tty_struct *tty, char __user *p)
- {
- char ch, mbz = 0;
- struct tty_ldisc *ld;
-
-+ if (tiocsti_restrict &&
-+ !ns_capable(tty->owner_user_ns, CAP_SYS_ADMIN)) {
-+ dev_warn_ratelimited(tty->dev,
-+ "Denied TIOCSTI ioctl for non-privileged process\n");
-+ return -EPERM;
-+ }
- if ((current->signal->tty != tty) && !capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (get_user(ch, p))
-@@ -2865,6 +2874,7 @@ struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx)
- tty->index = idx;
- tty_line_name(driver, idx, tty->name);
- tty->dev = tty_get_device(tty);
-+ tty->owner_user_ns = get_user_ns(current_user_ns());
-
- return tty;
- }
-diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
-index fa28f23a4a33..8a6c833ceefc 100644
---- a/drivers/usb/core/hub.c
-+++ b/drivers/usb/core/hub.c
-@@ -44,6 +44,8 @@
- #define USB_TP_TRANSMISSION_DELAY 40 /* ns */
- #define USB_TP_TRANSMISSION_DELAY_MAX 65535 /* ns */
-
-+extern int deny_new_usb;
-+
- /* Protect struct usb_device->state and ->children members
- * Note: Both are also protected by ->dev.sem, except that ->state can
- * change to USB_STATE_NOTATTACHED even when the semaphore isn't held. */
-@@ -4980,6 +4982,12 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
- goto done;
- return;
- }
-+
-+ if (deny_new_usb) {
-+ dev_err(&port_dev->dev, "denied insert of USB device on port %d\n", port1);
-+ goto done;
-+ }
-+
- if (hub_is_superspeed(hub->hdev))
- unit_load = 150;
- else
-diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
-index e5126fad57c5..2a59499ba24d 100644
---- a/fs/debugfs/inode.c
-+++ b/fs/debugfs/inode.c
-@@ -32,6 +32,10 @@ static struct vfsmount *debugfs_mount;
- static int debugfs_mount_count;
- static bool debugfs_registered;
-
-+#ifdef CONFIG_HARDENED_SYSFS_RESTRICT
-+extern int sysfs_restricted;
-+#endif
-+
- static struct inode *debugfs_get_inode(struct super_block *sb)
- {
- struct inode *inode = new_inode(sb);
-@@ -517,6 +521,11 @@ struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)
- if (unlikely(!inode))
- return failed_creating(dentry);
-
-+#ifdef CONFIG_HARDENED_SYSFS_RESTRICT
-+ if (sysfs_restricted)
-+ inode->i_mode = S_IFDIR | S_IRWXU;
-+ else
-+#endif
- inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
- inode->i_op = &simple_dir_inode_operations;
- inode->i_fop = &simple_dir_operations;
-diff --git a/fs/exec.c b/fs/exec.c
-index cece8c14f377..6ba41b1f3a3f 100644
---- a/fs/exec.c
-+++ b/fs/exec.c
-@@ -62,6 +62,7 @@
- #include <linux/oom.h>
- #include <linux/compat.h>
- #include <linux/vmalloc.h>
-+#include <linux/random.h>
-
- #include <linux/uaccess.h>
- #include <asm/mmu_context.h>
-@@ -320,6 +321,8 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
- arch_bprm_mm_init(mm, vma);
- up_write(&mm->mmap_sem);
- bprm->p = vma->vm_end - sizeof(void *);
-+ if (randomize_va_space)
-+ bprm->p ^= get_random_int() & ~PAGE_MASK;
- return 0;
- err:
- up_write(&mm->mmap_sem);
-diff --git a/fs/namei.c b/fs/namei.c
-index 327844fedf3d..c1b2eafa3b30 100644
---- a/fs/namei.c
-+++ b/fs/namei.c
-@@ -125,6 +125,10 @@
-
- #define EMBEDDED_NAME_MAX (PATH_MAX - offsetof(struct filename, iname))
-
-+#ifdef CONFIG_HARDENED_FIFO
-+extern int fifo_restrictions;
-+#endif
-+
- struct filename *
- getname_flags(const char __user *filename, int flags, int *empty)
- {
-@@ -885,10 +889,10 @@ static inline void put_link(struct nameidata *nd)
- path_put(&last->link);
- }
-
--int sysctl_protected_symlinks __read_mostly = 0;
--int sysctl_protected_hardlinks __read_mostly = 0;
--int sysctl_protected_fifos __read_mostly;
--int sysctl_protected_regular __read_mostly;
-+int sysctl_protected_symlinks __read_mostly = 1;
-+int sysctl_protected_hardlinks __read_mostly = 1;
-+int sysctl_protected_fifos __read_mostly = 2;
-+int sysctl_protected_regular __read_mostly = 2;
-
- /**
- * may_follow_link - Check symlink following for unsafe situations
-@@ -3252,6 +3256,32 @@ static int lookup_open(struct nameidata *nd, struct path *path,
- return error;
- }
-
-+/*
-+ * Handles possibly restricted FIFO operations
-+ * if the user doesn't own this directory.
-+ */
-+static int fifo_restricted(const struct dentry *dentry,
-+ const struct vfsmount *mnt,
-+ const struct dentry *dir,
-+ const int flag,
-+ const int acc_mode) {
-+#ifdef CONFIG_HARDENED_FIFO
-+ const struct cred *cred;
-+ struct inode *inode, *dir_inode;
-+
-+ cred = current_cred();
-+ inode = d_backing_inode(dentry);
-+ dir_inode = d_backing_inode(dir);
-+
-+ if (fifo_restrictions && S_ISFIFO(inode->i_mode) &&
-+ !(flag & O_EXCL) && (dir_inode->i_mode & S_ISVTX) &&
-+ !uid_eq(inode->i_uid, dir_inode->i_uid) &&
-+ !uid_eq(cred->fsuid, inode->i_uid))
-+ return -EACCES;
-+#endif
-+ return 0;
-+}
-+
- /*
- * Handle the last step of open()
- */
-@@ -3370,6 +3400,15 @@ static int do_last(struct nameidata *nd,
- return -ENOENT;
- }
-
-+ /*
-+ * Only check if O_CREAT is specified, all other checks need to go
-+ * into may_open().
-+ */
-+ if (fifo_restricted(path.dentry, path.mnt, dir, open_flag, acc_mode)) {
-+ path_to_nameidata(&path, nd);
-+ return -EACCES;
-+ }
-+
- /*
- * create/update audit record if it already exists.
- */
-diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig
-index ac3e06367cb6..06a2e4cf4cc1 100644
---- a/fs/nfs/Kconfig
-+++ b/fs/nfs/Kconfig
-@@ -195,4 +195,3 @@ config NFS_DEBUG
- bool
- depends on NFS_FS && SUNRPC_DEBUG
- select CRC32
-- default y
-diff --git a/fs/proc/Kconfig b/fs/proc/Kconfig
-index 817c02b13b1d..b8cd62b5cbc3 100644
---- a/fs/proc/Kconfig
-+++ b/fs/proc/Kconfig
-@@ -40,7 +40,6 @@ config PROC_KCORE
- config PROC_VMCORE
- bool "/proc/vmcore support"
- depends on PROC_FS && CRASH_DUMP
-- default y
- help
- Exports the dump image of crashed kernel in ELF format.
-
-diff --git a/fs/stat.c b/fs/stat.c
-index f8e6fb2c3657..240c1432e18f 100644
---- a/fs/stat.c
-+++ b/fs/stat.c
-@@ -40,8 +40,13 @@ void generic_fillattr(struct inode *inode, struct kstat *stat)
- stat->gid = inode->i_gid;
- stat->rdev = inode->i_rdev;
- stat->size = i_size_read(inode);
-- stat->atime = inode->i_atime;
-- stat->mtime = inode->i_mtime;
-+ if (is_sidechannel_device(inode) && !capable_noaudit(CAP_MKNOD)) {
-+ stat->atime = inode->i_ctime;
-+ stat->mtime = inode->i_ctime;
-+ } else {
-+ stat->atime = inode->i_atime;
-+ stat->mtime = inode->i_mtime;
-+ }
- stat->ctime = inode->i_ctime;
- stat->blksize = i_blocksize(inode);
- stat->blocks = inode->i_blocks;
-@@ -75,9 +80,14 @@ int vfs_getattr_nosec(const struct path *path, struct kstat *stat,
- stat->result_mask |= STATX_BASIC_STATS;
- request_mask &= STATX_ALL;
- query_flags &= KSTAT_QUERY_FLAGS;
-- if (inode->i_op->getattr)
-- return inode->i_op->getattr(path, stat, request_mask,
-- query_flags);
-+ if (inode->i_op->getattr) {
-+ int retval = inode->i_op->getattr(path, stat, request_mask, query_flags);
-+ if (!retval && is_sidechannel_device(inode) && !capable_noaudit(CAP_MKNOD)) {
-+ stat->atime = stat->ctime;
-+ stat->mtime = stat->ctime;
-+ }
-+ return retval;
-+ }
-
- generic_fillattr(inode, stat);
- return 0;
-diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
-index feeae8081c22..a507113bbd3b 100644
---- a/fs/sysfs/dir.c
-+++ b/fs/sysfs/dir.c
-@@ -18,6 +18,10 @@
-
- DEFINE_SPINLOCK(sysfs_symlink_target_lock);
-
-+#ifdef CONFIG_HARDENED_SYSFS_RESTRICT
-+extern int sysfs_restricted;
-+#endif
-+
- void sysfs_warn_dup(struct kernfs_node *parent, const char *name)
- {
- char *buf;
-@@ -40,11 +44,19 @@ void sysfs_warn_dup(struct kernfs_node *parent, const char *name)
- int sysfs_create_dir_ns(struct kobject *kobj, const void *ns)
- {
- struct kernfs_node *parent, *kn;
-+ const char* name;
-+ umode_t mode;
- kuid_t uid;
- kgid_t gid;
-
-+#ifdef CONFIG_HARDENED_SYSFS_RESTRICT
-+ const char *parent_name;
-+#endif
-+
- BUG_ON(!kobj);
-
-+ name = kobject_name(kobj);
-+
- if (kobj->parent)
- parent = kobj->parent->sd;
- else
-@@ -55,12 +67,30 @@ int sysfs_create_dir_ns(struct kobject *kobj, const void *ns)
-
- kobject_get_ownership(kobj, &uid, &gid);
-
-- kn = kernfs_create_dir_ns(parent, kobject_name(kobj),
-- S_IRWXU | S_IRUGO | S_IXUGO, uid, gid,
-- kobj, ns);
-+#ifdef CONFIG_HARDENED_SYSFS_RESTRICT
-+ if (sysfs_restricted) {
-+ parent_name = parent->name;
-+ mode = S_IRWXU;
-+
-+ if ((!strcmp(parent_name, "") && (!strcmp(name, "devices") ||
-+ !strcmp(name, "fs"))) ||
-+ (!strcmp(parent_name, "devices") && !strcmp(name, "system")) ||
-+ (!strcmp(parent_name, "fs") && (!strcmp(name, "selinux") ||
-+ !strcmp(name, "fuse") || !strcmp(name, "ecryptfs"))) ||
-+ (!strcmp(parent_name, "system") && !strcmp(name, "cpu")))
-+ mode |= S_IRUGO | S_IXUGO;
-+ }
-+ else
-+ mode = S_IRWXU | S_IRUGO | S_IXUGO;
-+#else
-+ mode = S_IRWXU | S_IRUGO | S_IXUGO;
-+#endif
-+
-+ kn = kernfs_create_dir_ns(parent, name, mode, uid, gid, kobj, ns);
-+
- if (IS_ERR(kn)) {
- if (PTR_ERR(kn) == -EEXIST)
-- sysfs_warn_dup(parent, kobject_name(kobj));
-+ sysfs_warn_dup(parent, name);
- return PTR_ERR(kn);
- }
-
-diff --git a/include/linux/cache.h b/include/linux/cache.h
-index 750621e41d1c..e7157c18c62c 100644
---- a/include/linux/cache.h
-+++ b/include/linux/cache.h
-@@ -31,6 +31,8 @@
- #define __ro_after_init __attribute__((__section__(".data..ro_after_init")))
- #endif
-
-+#define __read_only __ro_after_init
-+
- #ifndef ____cacheline_aligned
- #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
- #endif
-diff --git a/include/linux/capability.h b/include/linux/capability.h
-index f640dcbc880c..2b4f5d651f19 100644
---- a/include/linux/capability.h
-+++ b/include/linux/capability.h
-@@ -207,6 +207,7 @@ extern bool has_capability_noaudit(struct task_struct *t, int cap);
- extern bool has_ns_capability_noaudit(struct task_struct *t,
- struct user_namespace *ns, int cap);
- extern bool capable(int cap);
-+extern bool capable_noaudit(int cap);
- extern bool ns_capable(struct user_namespace *ns, int cap);
- extern bool ns_capable_noaudit(struct user_namespace *ns, int cap);
- #else
-@@ -232,6 +233,10 @@ static inline bool capable(int cap)
- {
- return true;
- }
-+static inline bool capable_noaudit(int cap)
-+{
-+ return true;
-+}
- static inline bool ns_capable(struct user_namespace *ns, int cap)
- {
- return true;
-diff --git a/include/linux/fs.h b/include/linux/fs.h
-index 8d568b51778b..d2ad90ecbf0c 100644
---- a/include/linux/fs.h
-+++ b/include/linux/fs.h
-@@ -3469,4 +3469,15 @@ extern void inode_nohighmem(struct inode *inode);
- extern int vfs_fadvise(struct file *file, loff_t offset, loff_t len,
- int advice);
-
-+extern int device_sidechannel_restrict;
-+
-+static inline bool is_sidechannel_device(const struct inode *inode)
-+{
-+ umode_t mode;
-+ if (!device_sidechannel_restrict)
-+ return false;
-+ mode = inode->i_mode;
-+ return ((S_ISCHR(mode) || S_ISBLK(mode)) && (mode & (S_IROTH | S_IWOTH)));
-+}
-+
- #endif /* _LINUX_FS_H */
-diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h
-index fd1ce10553bf..1905d2476d32 100644
---- a/include/linux/fsnotify.h
-+++ b/include/linux/fsnotify.h
-@@ -177,6 +177,9 @@ static inline void fsnotify_access(struct file *file)
- struct inode *inode = file_inode(file);
- __u32 mask = FS_ACCESS;
-
-+ if (is_sidechannel_device(inode))
-+ return;
-+
- if (S_ISDIR(inode->i_mode))
- mask |= FS_ISDIR;
-
-@@ -195,6 +198,9 @@ static inline void fsnotify_modify(struct file *file)
- struct inode *inode = file_inode(file);
- __u32 mask = FS_MODIFY;
-
-+ if (is_sidechannel_device(inode))
-+ return;
-+
- if (S_ISDIR(inode->i_mode))
- mask |= FS_ISDIR;
-
-diff --git a/include/linux/gfp.h b/include/linux/gfp.h
-index f78d1e89593f..ff139ff8d3d2 100644
---- a/include/linux/gfp.h
-+++ b/include/linux/gfp.h
-@@ -553,9 +553,9 @@ extern struct page *alloc_pages_vma(gfp_t gfp_mask, int order,
- extern unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order);
- extern unsigned long get_zeroed_page(gfp_t gfp_mask);
-
--void *alloc_pages_exact(size_t size, gfp_t gfp_mask);
-+void *alloc_pages_exact(size_t size, gfp_t gfp_mask) __attribute__((alloc_size(1)));
- void free_pages_exact(void *virt, size_t size);
--void * __meminit alloc_pages_exact_nid(int nid, size_t size, gfp_t gfp_mask);
-+void * __meminit alloc_pages_exact_nid(int nid, size_t size, gfp_t gfp_mask) __attribute__((alloc_size(2)));
-
- #define __get_free_page(gfp_mask) \
- __get_free_pages((gfp_mask), 0)
-diff --git a/include/linux/highmem.h b/include/linux/highmem.h
-index 0690679832d4..b9394bc86fad 100644
---- a/include/linux/highmem.h
-+++ b/include/linux/highmem.h
-@@ -191,6 +191,13 @@ static inline void clear_highpage(struct page *page)
- kunmap_atomic(kaddr);
- }
-
-+static inline void verify_zero_highpage(struct page *page)
-+{
-+ void *kaddr = kmap_atomic(page);
-+ BUG_ON(memchr_inv(kaddr, 0, PAGE_SIZE));
-+ kunmap_atomic(kaddr);
-+}
-+
- static inline void zero_user_segments(struct page *page,
- unsigned start1, unsigned end1,
- unsigned start2, unsigned end2)
-diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
-index eeceac3376fc..78ad558bce5f 100644
---- a/include/linux/interrupt.h
-+++ b/include/linux/interrupt.h
-@@ -490,7 +490,7 @@ extern const char * const softirq_to_name[NR_SOFTIRQS];
-
- struct softirq_action
- {
-- void (*action)(struct softirq_action *);
-+ void (*action)(void);
- };
-
- asmlinkage void do_softirq(void);
-@@ -505,7 +505,7 @@ static inline void do_softirq_own_stack(void)
- }
- #endif
-
--extern void open_softirq(int nr, void (*action)(struct softirq_action *));
-+extern void __init open_softirq(int nr, void (*action)(void));
- extern void softirq_init(void);
- extern void __raise_softirq_irqoff(unsigned int nr);
-
-diff --git a/include/linux/kobject_ns.h b/include/linux/kobject_ns.h
-index 069aa2ebef90..cb9e3637a620 100644
---- a/include/linux/kobject_ns.h
-+++ b/include/linux/kobject_ns.h
-@@ -45,7 +45,7 @@ struct kobj_ns_type_operations {
- void (*drop_ns)(void *);
- };
-
--int kobj_ns_type_register(const struct kobj_ns_type_operations *ops);
-+int __init kobj_ns_type_register(const struct kobj_ns_type_operations *ops);
- int kobj_ns_type_registered(enum kobj_ns_type type);
- const struct kobj_ns_type_operations *kobj_child_ns_ops(struct kobject *parent);
- const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj);
-diff --git a/include/linux/mm.h b/include/linux/mm.h
-index 05bc5f25ab85..dc590f056192 100644
---- a/include/linux/mm.h
-+++ b/include/linux/mm.h
-@@ -571,7 +571,7 @@ static inline int is_vmalloc_or_module_addr(const void *x)
- }
- #endif
-
--extern void *kvmalloc_node(size_t size, gfp_t flags, int node);
-+extern void *kvmalloc_node(size_t size, gfp_t flags, int node) __attribute__((alloc_size(1)));
- static inline void *kvmalloc(size_t size, gfp_t flags)
- {
- return kvmalloc_node(size, flags, NUMA_NO_NODE);
-diff --git a/include/linux/percpu.h b/include/linux/percpu.h
-index 70b7123f38c7..09f3019489b2 100644
---- a/include/linux/percpu.h
-+++ b/include/linux/percpu.h
-@@ -129,7 +129,7 @@ extern int __init pcpu_page_first_chunk(size_t reserved_size,
- pcpu_fc_populate_pte_fn_t populate_pte_fn);
- #endif
-
--extern void __percpu *__alloc_reserved_percpu(size_t size, size_t align);
-+extern void __percpu *__alloc_reserved_percpu(size_t size, size_t align) __attribute__((alloc_size(1)));
- extern bool __is_kernel_percpu_address(unsigned long addr, unsigned long *can_addr);
- extern bool is_kernel_percpu_address(unsigned long addr);
-
-@@ -137,8 +137,8 @@ extern bool is_kernel_percpu_address(unsigned long addr);
- extern void __init setup_per_cpu_areas(void);
- #endif
-
--extern void __percpu *__alloc_percpu_gfp(size_t size, size_t align, gfp_t gfp);
--extern void __percpu *__alloc_percpu(size_t size, size_t align);
-+extern void __percpu *__alloc_percpu_gfp(size_t size, size_t align, gfp_t gfp) __attribute__((alloc_size(1)));
-+extern void __percpu *__alloc_percpu(size_t size, size_t align) __attribute__((alloc_size(1)));
- extern void free_percpu(void __percpu *__pdata);
- extern phys_addr_t per_cpu_ptr_to_phys(void *addr);
-
-diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
-index d8b4d31acd18..205c79491de3 100644
---- a/include/linux/perf_event.h
-+++ b/include/linux/perf_event.h
-@@ -1194,6 +1194,11 @@ extern int perf_cpu_time_max_percent_handler(struct ctl_table *table, int write,
- int perf_event_max_stack_handler(struct ctl_table *table, int write,
- void __user *buffer, size_t *lenp, loff_t *ppos);
-
-+static inline bool perf_paranoid_any(void)
-+{
-+ return sysctl_perf_event_paranoid > 2;
-+}
-+
- static inline bool perf_paranoid_tracepoint_raw(void)
- {
- return sysctl_perf_event_paranoid > -1;
-diff --git a/include/linux/slab.h b/include/linux/slab.h
-index d6393413ef09..f11e06e87a29 100644
---- a/include/linux/slab.h
-+++ b/include/linux/slab.h
-@@ -180,8 +180,8 @@ void memcg_destroy_kmem_caches(struct mem_cgroup *);
- /*
- * Common kmalloc functions provided by all allocators
- */
--void * __must_check __krealloc(const void *, size_t, gfp_t);
--void * __must_check krealloc(const void *, size_t, gfp_t);
-+void * __must_check __krealloc(const void *, size_t, gfp_t) __attribute__((alloc_size(2)));
-+void * __must_check krealloc(const void *, size_t, gfp_t) __attribute((alloc_size(2)));
- void kfree(const void *);
- void kzfree(const void *);
- size_t ksize(const void *);
-@@ -354,7 +354,7 @@ static __always_inline unsigned int kmalloc_index(size_t size)
- }
- #endif /* !CONFIG_SLOB */
-
--void *__kmalloc(size_t size, gfp_t flags) __assume_kmalloc_alignment __malloc;
-+void *__kmalloc(size_t size, gfp_t flags) __assume_kmalloc_alignment __malloc __attribute__((alloc_size(1)));
- void *kmem_cache_alloc(struct kmem_cache *, gfp_t flags) __assume_slab_alignment __malloc;
- void kmem_cache_free(struct kmem_cache *, void *);
-
-@@ -378,7 +378,7 @@ static __always_inline void kfree_bulk(size_t size, void **p)
- }
-
- #ifdef CONFIG_NUMA
--void *__kmalloc_node(size_t size, gfp_t flags, int node) __assume_kmalloc_alignment __malloc;
-+void *__kmalloc_node(size_t size, gfp_t flags, int node) __assume_kmalloc_alignment __malloc __attribute__((alloc_size(1)));
- void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node) __assume_slab_alignment __malloc;
- #else
- static __always_inline void *__kmalloc_node(size_t size, gfp_t flags, int node)
-@@ -500,7 +500,7 @@ static __always_inline void *kmalloc_large(size_t size, gfp_t flags)
- * for general use, and so are not documented here. For a full list of
- * potential flags, always refer to linux/gfp.h.
- */
--static __always_inline void *kmalloc(size_t size, gfp_t flags)
-+static __always_inline __attribute__((alloc_size(1))) void *kmalloc(size_t size, gfp_t flags)
- {
- if (__builtin_constant_p(size)) {
- if (size > KMALLOC_MAX_CACHE_SIZE)
-@@ -540,7 +540,7 @@ static __always_inline unsigned int kmalloc_size(unsigned int n)
- return 0;
- }
-
--static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node)
-+static __always_inline __attribute__((alloc_size(1))) void *kmalloc_node(size_t size, gfp_t flags, int node)
- {
- #ifndef CONFIG_SLOB
- if (__builtin_constant_p(size) &&
-diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h
-index 3a1a1dbc6f49..ff38fec9eb76 100644
---- a/include/linux/slub_def.h
-+++ b/include/linux/slub_def.h
-@@ -121,6 +121,11 @@ struct kmem_cache {
- unsigned long random;
- #endif
-
-+#ifdef CONFIG_SLAB_CANARY
-+ unsigned long random_active;
-+ unsigned long random_inactive;
-+#endif
-+
- #ifdef CONFIG_NUMA
- /*
- * Defragmentation by allocating from a remote node.
-diff --git a/include/linux/string.h b/include/linux/string.h
-index 4db285b83f44..a479f93d59a4 100644
---- a/include/linux/string.h
-+++ b/include/linux/string.h
-@@ -238,6 +238,12 @@ void __read_overflow2(void) __compiletime_error("detected read beyond size of ob
- void __read_overflow3(void) __compiletime_error("detected read beyond size of object passed as 3rd parameter");
- void __write_overflow(void) __compiletime_error("detected write beyond size of object passed as 1st parameter");
-
-+#ifdef CONFIG_FORTIFY_SOURCE_STRICT_STRING
-+#define __string_size(p) __builtin_object_size(p, 1)
-+#else
-+#define __string_size(p) __builtin_object_size(p, 0)
-+#endif
-+
- #if !defined(__NO_FORTIFY) && defined(__OPTIMIZE__) && defined(CONFIG_FORTIFY_SOURCE)
-
- #ifdef CONFIG_KASAN
-@@ -266,7 +272,7 @@ extern char *__underlying_strncpy(char *p, const char *q, __kernel_size_t size)
-
- __FORTIFY_INLINE char *strncpy(char *p, const char *q, __kernel_size_t size)
- {
-- size_t p_size = __builtin_object_size(p, 0);
-+ size_t p_size = __string_size(p);
- if (__builtin_constant_p(size) && p_size < size)
- __write_overflow();
- if (p_size < size)
-@@ -276,7 +282,7 @@ __FORTIFY_INLINE char *strncpy(char *p, const char *q, __kernel_size_t size)
-
- __FORTIFY_INLINE char *strcat(char *p, const char *q)
- {
-- size_t p_size = __builtin_object_size(p, 0);
-+ size_t p_size = __string_size(p);
- if (p_size == (size_t)-1)
- return __underlying_strcat(p, q);
- if (strlcat(p, q, p_size) >= p_size)
-@@ -287,7 +293,7 @@ __FORTIFY_INLINE char *strcat(char *p, const char *q)
- __FORTIFY_INLINE __kernel_size_t strlen(const char *p)
- {
- __kernel_size_t ret;
-- size_t p_size = __builtin_object_size(p, 0);
-+ size_t p_size = __string_size(p);
-
- /* Work around gcc excess stack consumption issue */
- if (p_size == (size_t)-1 ||
-@@ -302,7 +308,7 @@ __FORTIFY_INLINE __kernel_size_t strlen(const char *p)
- extern __kernel_size_t __real_strnlen(const char *, __kernel_size_t) __RENAME(strnlen);
- __FORTIFY_INLINE __kernel_size_t strnlen(const char *p, __kernel_size_t maxlen)
- {
-- size_t p_size = __builtin_object_size(p, 0);
-+ size_t p_size = __string_size(p);
- __kernel_size_t ret = __real_strnlen(p, maxlen < p_size ? maxlen : p_size);
- if (p_size <= ret && maxlen != ret)
- fortify_panic(__func__);
-@@ -314,8 +320,8 @@ extern size_t __real_strlcpy(char *, const char *, size_t) __RENAME(strlcpy);
- __FORTIFY_INLINE size_t strlcpy(char *p, const char *q, size_t size)
- {
- size_t ret;
-- size_t p_size = __builtin_object_size(p, 0);
-- size_t q_size = __builtin_object_size(q, 0);
-+ size_t p_size = __string_size(p);
-+ size_t q_size = __string_size(q);
- if (p_size == (size_t)-1 && q_size == (size_t)-1)
- return __real_strlcpy(p, q, size);
- ret = strlen(q);
-@@ -335,8 +341,8 @@ __FORTIFY_INLINE size_t strlcpy(char *p, const char *q, size_t size)
- __FORTIFY_INLINE char *strncat(char *p, const char *q, __kernel_size_t count)
- {
- size_t p_len, copy_len;
-- size_t p_size = __builtin_object_size(p, 0);
-- size_t q_size = __builtin_object_size(q, 0);
-+ size_t p_size = __string_size(p);
-+ size_t q_size = __string_size(q);
- if (p_size == (size_t)-1 && q_size == (size_t)-1)
- return __underlying_strncat(p, q, count);
- p_len = strlen(p);
-@@ -449,8 +455,8 @@ __FORTIFY_INLINE void *kmemdup(const void *p, size_t size, gfp_t gfp)
- /* defined after fortified strlen and memcpy to reuse them */
- __FORTIFY_INLINE char *strcpy(char *p, const char *q)
- {
-- size_t p_size = __builtin_object_size(p, 0);
-- size_t q_size = __builtin_object_size(q, 0);
-+ size_t p_size = __string_size(p);
-+ size_t q_size = __string_size(q);
- if (p_size == (size_t)-1 && q_size == (size_t)-1)
- return __underlying_strcpy(p, q);
- memcpy(p, q, strlen(q) + 1);
-diff --git a/include/linux/tty.h b/include/linux/tty.h
-index 74226a8f919c..a4280e6a318d 100644
---- a/include/linux/tty.h
-+++ b/include/linux/tty.h
-@@ -14,6 +14,7 @@
- #include <uapi/linux/tty.h>
- #include <linux/rwsem.h>
- #include <linux/llist.h>
-+#include <linux/user_namespace.h>
-
-
- /*
-@@ -338,6 +339,7 @@ struct tty_struct {
- /* If the tty has a pending do_SAK, queue it here - akpm */
- struct work_struct SAK_work;
- struct tty_port *port;
-+ struct user_namespace *owner_user_ns;
- } __randomize_layout;
-
- /* Each of a tty's open files has private_data pointing to tty_file_private */
-@@ -347,6 +349,8 @@ struct tty_file_private {
- struct list_head list;
- };
-
-+extern int tiocsti_restrict;
-+
- /* tty magic number */
- #define TTY_MAGIC 0x5401
-
-diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
-index 206957b1b54d..17ec0860416b 100644
---- a/include/linux/vmalloc.h
-+++ b/include/linux/vmalloc.h
-@@ -69,19 +69,19 @@ static inline void vmalloc_init(void)
- }
- #endif
-
--extern void *vmalloc(unsigned long size);
--extern void *vzalloc(unsigned long size);
--extern void *vmalloc_user(unsigned long size);
--extern void *vmalloc_node(unsigned long size, int node);
--extern void *vzalloc_node(unsigned long size, int node);
--extern void *vmalloc_exec(unsigned long size);
--extern void *vmalloc_32(unsigned long size);
--extern void *vmalloc_32_user(unsigned long size);
--extern void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot);
-+extern void *vmalloc(unsigned long size) __attribute__((alloc_size(1)));
-+extern void *vzalloc(unsigned long size) __attribute__((alloc_size(1)));
-+extern void *vmalloc_user(unsigned long size) __attribute__((alloc_size(1)));
-+extern void *vmalloc_node(unsigned long size, int node) __attribute__((alloc_size(1)));
-+extern void *vzalloc_node(unsigned long size, int node) __attribute__((alloc_size(1)));
-+extern void *vmalloc_exec(unsigned long size) __attribute__((alloc_size(1)));
-+extern void *vmalloc_32(unsigned long size) __attribute__((alloc_size(1)));
-+extern void *vmalloc_32_user(unsigned long size) __attribute__((alloc_size(1)));
-+extern void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot) __attribute__((alloc_size(1)));
- extern void *__vmalloc_node_range(unsigned long size, unsigned long align,
- unsigned long start, unsigned long end, gfp_t gfp_mask,
- pgprot_t prot, unsigned long vm_flags, int node,
-- const void *caller);
-+ const void *caller) __attribute__((alloc_size(1)));
- #ifndef CONFIG_MMU
- extern void *__vmalloc_node_flags(unsigned long size, int node, gfp_t flags);
- static inline void *__vmalloc_node_flags_caller(unsigned long size, int node,
-diff --git a/include/uapi/linux/ip.h b/include/uapi/linux/ip.h
-index e42d13b55cf3..3228bcfe7599 100644
---- a/include/uapi/linux/ip.h
-+++ b/include/uapi/linux/ip.h
-@@ -66,7 +66,11 @@
-
- #define IPVERSION 4
- #define MAXTTL 255
-+#ifdef CONFIG_HARDENED_STEALTH_NETWORKING
-+#define IPDEFTTL 128
-+#else
- #define IPDEFTTL 64
-+#endif
-
- #define IPOPT_OPTVAL 0
- #define IPOPT_OLEN 1
-diff --git a/init/Kconfig b/init/Kconfig
-index 47035b5a46f6..efbd3ac00d92 100644
---- a/init/Kconfig
-+++ b/init/Kconfig
-@@ -326,6 +326,7 @@ config USELIB
- config AUDIT
- bool "Auditing support"
- depends on NET
-+ default y
- help
- Enable auditing infrastructure that can be used with another
- kernel subsystem, such as SELinux (which requires this for
-@@ -957,6 +958,22 @@ config USER_NS
-
- If unsure, say N.
-
-+config USER_NS_UNPRIVILEGED
-+ bool "Allow unprivileged users to create namespaces"
-+ depends on USER_NS
-+ default n
-+ help
-+ When disabled, unprivileged users will not be able to create
-+ new namespaces. Allowing users to create their own namespaces
-+ has been part of several recent local privilege escalation
-+ exploits, so if you need user namespaces but are
-+ paranoid^Wsecurity-conscious you want to disable this.
-+
-+ This setting can be overridden at runtime via the
-+ kernel.unprivileged_userns_clone sysctl.
-+
-+ If unsure, say N.
-+
- config PID_NS
- bool "PID Namespaces"
- default y
-@@ -1091,6 +1108,12 @@ config CC_OPTIMIZE_FOR_SIZE
-
- endchoice
-
-+config LOCAL_INIT
-+ bool "Zero uninitialized locals"
-+ help
-+ Zero-fill uninitialized local variables, other than variable-length
-+ arrays. Requires compiler support.
-+
- config HAVE_LD_DEAD_CODE_DATA_ELIMINATION
- bool
- help
-@@ -1377,8 +1400,7 @@ config SHMEM
- which may be appropriate on small systems without swap.
-
- config AIO
-- bool "Enable AIO support" if EXPERT
-- default y
-+ bool "Enable AIO support"
- help
- This option enables POSIX asynchronous I/O which may by used
- by some high performance threaded applications. Disabling
-@@ -1595,7 +1617,7 @@ config VM_EVENT_COUNTERS
-
- config SLUB_DEBUG
- default y
-- bool "Enable SLUB debugging support" if EXPERT
-+ bool "Enable SLUB debugging support"
- depends on SLUB && SYSFS
- help
- SLUB has extensive debug support features. Disabling these can
-@@ -1619,7 +1641,6 @@ config SLUB_MEMCG_SYSFS_ON
-
- config COMPAT_BRK
- bool "Disable heap randomization"
-- default y
- help
- Randomizing heap placement makes heap exploits harder, but it
- also breaks ancient binaries (including anything libc5 based).
-@@ -1666,7 +1687,6 @@ endchoice
-
- config SLAB_MERGE_DEFAULT
- bool "Allow slab caches to be merged"
-- default y
- help
- For reduced kernel memory fragmentation, slab caches can be
- merged when they share the same size and other characteristics.
-@@ -1679,9 +1699,9 @@ config SLAB_MERGE_DEFAULT
- command line.
-
- config SLAB_FREELIST_RANDOM
-- default n
- depends on SLAB || SLUB
- bool "SLAB freelist randomization"
-+ default y
- help
- Randomizes the freelist order used on creating new pages. This
- security feature reduces the predictability of the kernel slab
-@@ -1690,12 +1710,56 @@ config SLAB_FREELIST_RANDOM
- config SLAB_FREELIST_HARDENED
- bool "Harden slab freelist metadata"
- depends on SLUB
-+ default y
- help
- Many kernel heap attacks try to target slab cache metadata and
- other infrastructure. This options makes minor performance
- sacrifies to harden the kernel slab allocator against common
- freelist exploit methods.
-
-+config SLAB_HARDENED
-+ default y
-+ depends on SLUB
-+ bool "Hardened SLAB infrastructure"
-+ help
-+ Make minor performance sacrifices to harden the kernel slab
-+ allocator.
-+
-+config SLAB_CANARY
-+ depends on SLUB
-+ depends on !SLAB_MERGE_DEFAULT
-+ bool "SLAB canaries"
-+ default y
-+ help
-+ Place canaries at the end of kernel slab allocations, sacrificing
-+ some performance and memory usage for security.
-+
-+ Canaries can detect some forms of heap corruption when allocations
-+ are freed and as part of the HARDENED_USERCOPY feature. It provides
-+ basic use-after-free detection for HARDENED_USERCOPY.
-+
-+ Canaries absorb small overflows (rendering them harmless), mitigate
-+ non-NUL terminated C string overflows on 64-bit via a guaranteed zero
-+ byte and provide basic double-free detection.
-+
-+config SLAB_SANITIZE
-+ bool "Sanitize SLAB allocations"
-+ depends on SLUB
-+ default y
-+ help
-+ Zero fill slab allocations on free, reducing the lifetime of
-+ sensitive data and helping to mitigate use-after-free bugs.
-+
-+ For slabs with debug poisoning enabling, this has no impact.
-+
-+config SLAB_SANITIZE_VERIFY
-+ depends on SLAB_SANITIZE && PAGE_SANITIZE
-+ default y
-+ bool "Verify sanitized SLAB allocations"
-+ help
-+ Verify that newly allocated slab allocations are zeroed to detect
-+ write-after-free bugs.
-+
- config SLUB_CPU_PARTIAL
- default y
- depends on SLUB && SMP
-diff --git a/kernel/audit.c b/kernel/audit.c
-index 45741c3c48a4..a2de0700ecd5 100644
---- a/kernel/audit.c
-+++ b/kernel/audit.c
-@@ -1641,6 +1641,9 @@ static int __init audit_enable(char *str)
-
- if (audit_default == AUDIT_OFF)
- audit_initialized = AUDIT_DISABLED;
-+ else if (!audit_ever_enabled)
-+ audit_initialized = AUDIT_UNINITIALIZED;
-+
- if (audit_set_enabled(audit_default))
- pr_err("audit: error setting audit state (%d)\n",
- audit_default);
-diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
-index 36be400c3e65..50fa38718408 100644
---- a/kernel/bpf/core.c
-+++ b/kernel/bpf/core.c
-@@ -368,7 +368,7 @@ void bpf_prog_kallsyms_del_all(struct bpf_prog *fp)
- #ifdef CONFIG_BPF_JIT
- /* All BPF JIT sysctl knobs here. */
- int bpf_jit_enable __read_mostly = IS_BUILTIN(CONFIG_BPF_JIT_ALWAYS_ON);
--int bpf_jit_harden __read_mostly;
-+int bpf_jit_harden __read_mostly = 2;
- int bpf_jit_kallsyms __read_mostly;
- long bpf_jit_limit __read_mostly;
-
-diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
-index b766265cf37d..5b6af308d584 100644
---- a/kernel/bpf/syscall.c
-+++ b/kernel/bpf/syscall.c
-@@ -48,7 +48,7 @@ static DEFINE_SPINLOCK(prog_idr_lock);
- static DEFINE_IDR(map_idr);
- static DEFINE_SPINLOCK(map_idr_lock);
-
--int sysctl_unprivileged_bpf_disabled __read_mostly;
-+int sysctl_unprivileged_bpf_disabled __read_mostly = 1;
-
- static const struct bpf_map_ops * const bpf_map_types[] = {
- #define BPF_PROG_TYPE(_id, _ops)
-diff --git a/kernel/capability.c b/kernel/capability.c
-index 7718d7dcadc7..8a4ce459da0a 100644
---- a/kernel/capability.c
-+++ b/kernel/capability.c
-@@ -432,6 +432,12 @@ bool capable(int cap)
- return ns_capable(&init_user_ns, cap);
- }
- EXPORT_SYMBOL(capable);
-+
-+bool capable_noaudit(int cap)
-+{
-+ return ns_capable_noaudit(&init_user_ns, cap);
-+}
-+EXPORT_SYMBOL(capable_noaudit);
- #endif /* CONFIG_MULTIUSER */
-
- /**
-diff --git a/kernel/events/core.c b/kernel/events/core.c
-index a17e6302ded5..df052b42d1f0 100644
---- a/kernel/events/core.c
-+++ b/kernel/events/core.c
-@@ -402,8 +402,13 @@ static cpumask_var_t perf_online_mask;
- * 0 - disallow raw tracepoint access for unpriv
- * 1 - disallow cpu events for unpriv
- * 2 - disallow kernel profiling for unpriv
-+ * 3 - disallow all unpriv perf event use
- */
-+#ifdef CONFIG_SECURITY_PERF_EVENTS_RESTRICT
-+int sysctl_perf_event_paranoid __read_mostly = 3;
-+#else
- int sysctl_perf_event_paranoid __read_mostly = 2;
-+#endif
-
- /* Minimum for 512 kiB + 1 user control page */
- int sysctl_perf_event_mlock __read_mostly = 512 + (PAGE_SIZE / 1024); /* 'free' kiB per user */
-@@ -10544,6 +10549,9 @@ SYSCALL_DEFINE5(perf_event_open,
- if (flags & ~PERF_FLAG_ALL)
- return -EINVAL;
-
-+ if (perf_paranoid_any() && !capable(CAP_SYS_ADMIN))
-+ return -EACCES;
-+
- err = perf_copy_attr(attr_uptr, &attr);
- if (err)
- return err;
-diff --git a/kernel/fork.c b/kernel/fork.c
-index 1a2d18e98bf9..f3a8e3df2e12 100644
---- a/kernel/fork.c
-+++ b/kernel/fork.c
-@@ -103,6 +103,11 @@
-
- #define CREATE_TRACE_POINTS
- #include <trace/events/task.h>
-+#ifdef CONFIG_USER_NS
-+extern int unprivileged_userns_clone;
-+#else
-+#define unprivileged_userns_clone 0
-+#endif
-
- /*
- * Minimum number of threads to boot the kernel
-@@ -1679,6 +1684,10 @@ static __latent_entropy struct task_struct *copy_process(
- if ((clone_flags & (CLONE_NEWUSER|CLONE_FS)) == (CLONE_NEWUSER|CLONE_FS))
- return ERR_PTR(-EINVAL);
-
-+ if ((clone_flags & CLONE_NEWUSER) && !unprivileged_userns_clone)
-+ if (!capable(CAP_SYS_ADMIN))
-+ return ERR_PTR(-EPERM);
-+
- /*
- * Thread groups must share signals as well, and detached threads
- * can only be started up within the thread group.
-@@ -2508,6 +2517,12 @@ int ksys_unshare(unsigned long unshare_flags)
- if (unshare_flags & CLONE_NEWNS)
- unshare_flags |= CLONE_FS;
-
-+ if ((unshare_flags & CLONE_NEWUSER) && !unprivileged_userns_clone) {
-+ err = -EPERM;
-+ if (!capable(CAP_SYS_ADMIN))
-+ goto bad_unshare_out;
-+ }
-+
- err = check_unshare_flags(unshare_flags);
- if (err)
- goto bad_unshare_out;
-diff --git a/kernel/kmod.c b/kernel/kmod.c
-index a2de58de6ab6..6dbfe38a1d7f 100644
---- a/kernel/kmod.c
-+++ b/kernel/kmod.c
-@@ -149,6 +149,13 @@ int __request_module(bool wait, const char *fmt, ...)
- if (ret)
- return ret;
-
-+#ifdef CONFIG_HARDENED_MODULE_LOAD
-+ if (uid_eq(current_uid(), GLOBAL_ROOT_UID)) {
-+ printk(KERN_ALERT "denied attempt to auto-load module %.64s\n", module_name);
-+ return -EPERM;
-+ }
-+#endif
-+
- if (atomic_dec_if_positive(&kmod_concurrent_max) < 0) {
- pr_warn_ratelimited("request_module: kmod_concurrent_max (%u) close to 0 (max_modprobes: %u), for module %s, throttling...",
- atomic_read(&kmod_concurrent_max),
-diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
-index f2635fc751d9..a4c445bf7f24 100644
---- a/kernel/power/snapshot.c
-+++ b/kernel/power/snapshot.c
-@@ -1145,7 +1145,7 @@ void free_basic_memory_bitmaps(void)
-
- void clear_free_pages(void)
- {
--#ifdef CONFIG_PAGE_POISONING_ZERO
-+#if defined(CONFIG_PAGE_POISONING_ZERO) || defined(CONFIG_PAGE_SANITIZE)
- struct memory_bitmap *bm = free_pages_map;
- unsigned long pfn;
-
-@@ -1162,7 +1162,7 @@ void clear_free_pages(void)
- }
- memory_bm_position_reset(bm);
- pr_info("free pages cleared after restore\n");
--#endif /* PAGE_POISONING_ZERO */
-+#endif /* PAGE_POISONING_ZERO || PAGE_SANITIZE */
- }
-
- /**
-diff --git a/kernel/rcu/tiny.c b/kernel/rcu/tiny.c
-index befc9321a89c..61e19256560c 100644
---- a/kernel/rcu/tiny.c
-+++ b/kernel/rcu/tiny.c
-@@ -162,7 +162,7 @@ static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp)
- }
- }
-
--static __latent_entropy void rcu_process_callbacks(struct softirq_action *unused)
-+static __latent_entropy void rcu_process_callbacks(void)
- {
- __rcu_process_callbacks(&rcu_sched_ctrlblk);
- __rcu_process_callbacks(&rcu_bh_ctrlblk);
-diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
-index f7e89c989df7..527c170810fc 100644
---- a/kernel/rcu/tree.c
-+++ b/kernel/rcu/tree.c
-@@ -2870,7 +2870,7 @@ __rcu_process_callbacks(struct rcu_state *rsp)
- /*
- * Do RCU core processing for the current CPU.
- */
--static __latent_entropy void rcu_process_callbacks(struct softirq_action *unused)
-+static __latent_entropy void rcu_process_callbacks(void)
- {
- struct rcu_state *rsp;
-
-diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
-index 92b1e71f13c8..c385bc7b0cec 100644
---- a/kernel/sched/fair.c
-+++ b/kernel/sched/fair.c
-@@ -9719,7 +9719,7 @@ static int idle_balance(struct rq *this_rq, struct rq_flags *rf)
- * run_rebalance_domains is triggered when needed from the scheduler tick.
- * Also triggered for nohz idle balancing (with nohz_balancing_kick set).
- */
--static __latent_entropy void run_rebalance_domains(struct softirq_action *h)
-+static __latent_entropy void run_rebalance_domains(void)
- {
- struct rq *this_rq = this_rq();
- enum cpu_idle_type idle = this_rq->idle_balance ?
-diff --git a/kernel/softirq.c b/kernel/softirq.c
-index 6f584861d329..1943fe60f3b9 100644
---- a/kernel/softirq.c
-+++ b/kernel/softirq.c
-@@ -53,7 +53,7 @@ DEFINE_PER_CPU_ALIGNED(irq_cpustat_t, irq_stat);
- EXPORT_PER_CPU_SYMBOL(irq_stat);
- #endif
-
--static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp;
-+static struct softirq_action softirq_vec[NR_SOFTIRQS] __ro_after_init __aligned(PAGE_SIZE);
-
- DEFINE_PER_CPU(struct task_struct *, ksoftirqd);
-
-@@ -289,7 +289,7 @@ asmlinkage __visible void __softirq_entry __do_softirq(void)
- kstat_incr_softirqs_this_cpu(vec_nr);
-
- trace_softirq_entry(vec_nr);
-- h->action(h);
-+ h->action();
- trace_softirq_exit(vec_nr);
- if (unlikely(prev_count != preempt_count())) {
- pr_err("huh, entered softirq %u %s %p with preempt_count %08x, exited with %08x?\n",
-@@ -451,7 +451,7 @@ void __raise_softirq_irqoff(unsigned int nr)
- or_softirq_pending(1UL << nr);
- }
-
--void open_softirq(int nr, void (*action)(struct softirq_action *))
-+void __init open_softirq(int nr, void (*action)(void))
- {
- softirq_vec[nr].action = action;
- }
-@@ -497,8 +497,7 @@ void __tasklet_hi_schedule(struct tasklet_struct *t)
- }
- EXPORT_SYMBOL(__tasklet_hi_schedule);
-
--static void tasklet_action_common(struct softirq_action *a,
-- struct tasklet_head *tl_head,
-+static void tasklet_action_common(struct tasklet_head *tl_head,
- unsigned int softirq_nr)
- {
- struct tasklet_struct *list;
-@@ -535,14 +534,14 @@ static void tasklet_action_common(struct softirq_action *a,
- }
- }
-
--static __latent_entropy void tasklet_action(struct softirq_action *a)
-+static __latent_entropy void tasklet_action(void)
- {
-- tasklet_action_common(a, this_cpu_ptr(&tasklet_vec), TASKLET_SOFTIRQ);
-+ tasklet_action_common(this_cpu_ptr(&tasklet_vec), TASKLET_SOFTIRQ);
- }
-
--static __latent_entropy void tasklet_hi_action(struct softirq_action *a)
-+static __latent_entropy void tasklet_hi_action(void)
- {
-- tasklet_action_common(a, this_cpu_ptr(&tasklet_hi_vec), HI_SOFTIRQ);
-+ tasklet_action_common(this_cpu_ptr(&tasklet_hi_vec), HI_SOFTIRQ);
- }
-
- void tasklet_init(struct tasklet_struct *t,
-diff --git a/kernel/sysctl.c b/kernel/sysctl.c
-index 4c4fd4339d33..10f5b0ecf5a4 100644
---- a/kernel/sysctl.c
-+++ b/kernel/sysctl.c
-@@ -67,6 +67,7 @@
- #include <linux/bpf.h>
- #include <linux/mount.h>
- #include <linux/pipe_fs_i.h>
-+#include <linux/tty.h>
-
- #include <linux/uaccess.h>
- #include <asm/processor.h>
-@@ -99,12 +100,25 @@
- #if defined(CONFIG_SYSCTL)
-
- /* External variables not in a header file. */
-+#if IS_ENABLED(CONFIG_USB)
-+int deny_new_usb __read_mostly = 0;
-+EXPORT_SYMBOL(deny_new_usb);
-+#endif
-+#ifdef CONFIG_HARDENED_SYSFS_RESTRICT
-+int __read_mostly sysfs_restricted = 1;
-+#endif
-+#ifdef CONFIG_HARDENED_FIFO
-+int __read_mostly fifo_restrictions = 1;
-+#endif
- extern int suid_dumpable;
- #ifdef CONFIG_COREDUMP
- extern int core_uses_pid;
- extern char core_pattern[];
- extern unsigned int core_pipe_limit;
- #endif
-+#ifdef CONFIG_USER_NS
-+extern int unprivileged_userns_clone;
-+#endif
- extern int pid_max;
- extern int pid_max_min, pid_max_max;
- extern int percpu_pagelist_fraction;
-@@ -116,35 +130,35 @@ extern int sysctl_nr_trim_pages;
-
- /* Constants used for minimum and maximum */
- #ifdef CONFIG_LOCKUP_DETECTOR
--static int sixty = 60;
-+static int sixty __read_only = 60;
- #endif
-
--static int __maybe_unused neg_one = -1;
-+static int __maybe_unused neg_one __read_only = -1;
-
- static int zero;
--static int __maybe_unused one = 1;
--static int __maybe_unused two = 2;
--static int __maybe_unused four = 4;
--static unsigned long zero_ul;
--static unsigned long one_ul = 1;
--static unsigned long long_max = LONG_MAX;
--static int one_hundred = 100;
--static int one_thousand = 1000;
-+static int __maybe_unused one __read_only = 1;
-+static int __maybe_unused two __read_only = 2;
-+static int __maybe_unused four __read_only = 4;
-+static unsigned long zero_ul __read_only;
-+static unsigned long one_ul __read_only = 1;
-+static unsigned long long_max __read_only = LONG_MAX;
-+static int one_hundred __read_only = 100;
-+static int one_thousand __read_only = 1000;
- #ifdef CONFIG_PRINTK
--static int ten_thousand = 10000;
-+static int ten_thousand __read_only = 10000;
- #endif
- #ifdef CONFIG_PERF_EVENTS
--static int six_hundred_forty_kb = 640 * 1024;
-+static int six_hundred_forty_kb __read_only = 640 * 1024;
- #endif
-
- /* this is needed for the proc_doulongvec_minmax of vm_dirty_bytes */
--static unsigned long dirty_bytes_min = 2 * PAGE_SIZE;
-+static unsigned long dirty_bytes_min __read_only = 2 * PAGE_SIZE;
-
- /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
--static int maxolduid = 65535;
--static int minolduid;
-+static int maxolduid __read_only = 65535;
-+static int minolduid __read_only;
-
--static int ngroups_max = NGROUPS_MAX;
-+static int ngroups_max __read_only = NGROUPS_MAX;
- static const int cap_last_cap = CAP_LAST_CAP;
-
- /*
-@@ -152,9 +166,12 @@ static const int cap_last_cap = CAP_LAST_CAP;
- * and hung_task_check_interval_secs
- */
- #ifdef CONFIG_DETECT_HUNG_TASK
--static unsigned long hung_task_timeout_max = (LONG_MAX/HZ);
-+static unsigned long hung_task_timeout_max __read_only = (LONG_MAX/HZ);
- #endif
-
-+int device_sidechannel_restrict __read_mostly = 1;
-+EXPORT_SYMBOL(device_sidechannel_restrict);
-+
- #ifdef CONFIG_INOTIFY_USER
- #include <linux/inotify.h>
- #endif
-@@ -298,19 +315,19 @@ static struct ctl_table sysctl_base_table[] = {
- };
-
- #ifdef CONFIG_SCHED_DEBUG
--static int min_sched_granularity_ns = 100000; /* 100 usecs */
--static int max_sched_granularity_ns = NSEC_PER_SEC; /* 1 second */
--static int min_wakeup_granularity_ns; /* 0 usecs */
--static int max_wakeup_granularity_ns = NSEC_PER_SEC; /* 1 second */
-+static int min_sched_granularity_ns __read_only = 100000; /* 100 usecs */
-+static int max_sched_granularity_ns __read_only = NSEC_PER_SEC; /* 1 second */
-+static int min_wakeup_granularity_ns __read_only; /* 0 usecs */
-+static int max_wakeup_granularity_ns __read_only = NSEC_PER_SEC; /* 1 second */
- #ifdef CONFIG_SMP
--static int min_sched_tunable_scaling = SCHED_TUNABLESCALING_NONE;
--static int max_sched_tunable_scaling = SCHED_TUNABLESCALING_END-1;
-+static int min_sched_tunable_scaling __read_only = SCHED_TUNABLESCALING_NONE;
-+static int max_sched_tunable_scaling __read_only = SCHED_TUNABLESCALING_END-1;
- #endif /* CONFIG_SMP */
- #endif /* CONFIG_SCHED_DEBUG */
-
- #ifdef CONFIG_COMPACTION
--static int min_extfrag_threshold;
--static int max_extfrag_threshold = 1000;
-+static int min_extfrag_threshold __read_only;
-+static int max_extfrag_threshold __read_only = 1000;
- #endif
-
- static struct ctl_table kern_table[] = {
-@@ -516,6 +533,15 @@ static struct ctl_table kern_table[] = {
- .proc_handler = proc_dointvec,
- },
- #endif
-+#ifdef CONFIG_USER_NS
-+ {
-+ .procname = "unprivileged_userns_clone",
-+ .data = &unprivileged_userns_clone,
-+ .maxlen = sizeof(int),
-+ .mode = 0644,
-+ .proc_handler = proc_dointvec,
-+ },
-+#endif
- #ifdef CONFIG_PROC_SYSCTL
- {
- .procname = "tainted",
-@@ -864,6 +890,59 @@ static struct ctl_table kern_table[] = {
- .extra1 = &zero,
- .extra2 = &two,
- },
-+#endif
-+#if defined CONFIG_TTY
-+ {
-+ .procname = "tiocsti_restrict",
-+ .data = &tiocsti_restrict,
-+ .maxlen = sizeof(int),
-+ .mode = 0644,
-+ .proc_handler = proc_dointvec_minmax_sysadmin,
-+ .extra1 = &zero,
-+ .extra2 = &one,
-+ },
-+#endif
-+ {
-+ .procname = "device_sidechannel_restrict",
-+ .data = &device_sidechannel_restrict,
-+ .maxlen = sizeof(int),
-+ .mode = 0644,
-+ .proc_handler = proc_dointvec_minmax_sysadmin,
-+ .extra1 = &zero,
-+ .extra2 = &one,
-+ },
-+#if IS_ENABLED(CONFIG_USB)
-+ {
-+ .procname = "deny_new_usb",
-+ .data = &deny_new_usb,
-+ .maxlen = sizeof(int),
-+ .mode = 0644,
-+ .proc_handler = proc_dointvec_minmax_sysadmin,
-+ .extra1 = &zero,
-+ .extra2 = &one,
-+ },
-+#endif
-+#ifdef CONFIG_HARDENED_SYSFS_RESTRICT
-+ {
-+ .procname = "sysfs_restricted",
-+ .data = &sysfs_restricted,
-+ .maxlen = sizeof(int),
-+ .mode = 0644,
-+ .proc_handler = proc_dointvec_minmax_sysadmin,
-+ .extra1 = &zero,
-+ .extra2 = &one,
-+ },
-+#endif
-+#ifdef CONFIG_HARDENED_FIFO
-+ {
-+ .procname = "fifo_restrictions",
-+ .data = &fifo_restrictions,
-+ .maxlen = sizeof(int),
-+ .mode = 0644,
-+ .proc_handler = proc_dointvec_minmax_sysadmin,
-+ .extra1 = &zero,
-+ .extra2 = &one,
-+ },
- #endif
- {
- .procname = "ngroups_max",
-diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
-index 7362554416fd..fb8902236deb 100644
---- a/kernel/time/hrtimer.c
-+++ b/kernel/time/hrtimer.c
-@@ -1465,7 +1465,7 @@ static void __hrtimer_run_queues(struct hrtimer_cpu_base *cpu_base, ktime_t now,
- }
- }
-
--static __latent_entropy void hrtimer_run_softirq(struct softirq_action *h)
-+static __latent_entropy void hrtimer_run_softirq(void)
- {
- struct hrtimer_cpu_base *cpu_base = this_cpu_ptr(&hrtimer_bases);
- unsigned long flags;
-diff --git a/kernel/time/timer.c b/kernel/time/timer.c
-index ae64cb819a9a..52f5a5dcd09d 100644
---- a/kernel/time/timer.c
-+++ b/kernel/time/timer.c
-@@ -1690,7 +1690,7 @@ static inline void __run_timers(struct timer_base *base)
- /*
- * This function runs timers and the timer-tq in bottom half context.
- */
--static __latent_entropy void run_timer_softirq(struct softirq_action *h)
-+static __latent_entropy void run_timer_softirq(void)
- {
- struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]);
-
-diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
-index 923414a246e9..107b17f0d528 100644
---- a/kernel/user_namespace.c
-+++ b/kernel/user_namespace.c
-@@ -26,6 +26,13 @@
- #include <linux/bsearch.h>
- #include <linux/sort.h>
-
-+/* sysctl */
-+#ifdef CONFIG_USER_NS_UNPRIVILEGED
-+int unprivileged_userns_clone = 1;
-+#else
-+int unprivileged_userns_clone;
-+#endif
-+
- static struct kmem_cache *user_ns_cachep __read_mostly;
- static DEFINE_MUTEX(userns_state_mutex);
-
-diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
-index 46a910acce3f..5b60c663ac69 100644
---- a/lib/Kconfig.debug
-+++ b/lib/Kconfig.debug
-@@ -950,6 +950,7 @@ endmenu # "Debug lockups and hangs"
-
- config PANIC_ON_OOPS
- bool "Panic on Oops"
-+ default y
- help
- Say Y here to enable the kernel to panic when it oopses. This
- has the same effect as setting oops=panic on the kernel command
-@@ -959,7 +960,7 @@ config PANIC_ON_OOPS
- anything erroneous after an oops which could result in data
- corruption or other issues.
-
-- Say N if unsure.
-+ Say Y if unsure.
-
- config PANIC_ON_OOPS_VALUE
- int
-@@ -1328,6 +1329,7 @@ config DEBUG_BUGVERBOSE
- config DEBUG_LIST
- bool "Debug linked list manipulation"
- depends on DEBUG_KERNEL || BUG_ON_DATA_CORRUPTION
-+ default y
- help
- Enable this to turn on extended checks in the linked-list
- walking routines.
-@@ -1983,6 +1985,7 @@ config MEMTEST
- config BUG_ON_DATA_CORRUPTION
- bool "Trigger a BUG when data corruption is detected"
- select DEBUG_LIST
-+ default y
- help
- Select this option if the kernel should BUG when it encounters
- data corruption in kernel memory structures when they get checked
-@@ -2022,6 +2025,7 @@ config STRICT_DEVMEM
- config IO_STRICT_DEVMEM
- bool "Filter I/O access to /dev/mem"
- depends on STRICT_DEVMEM
-+ default y
- ---help---
- If this option is disabled, you allow userspace (root) access to all
- io-memory regardless of whether a driver is actively using that
-diff --git a/lib/irq_poll.c b/lib/irq_poll.c
-index 86a709954f5a..6f15787fcb1b 100644
---- a/lib/irq_poll.c
-+++ b/lib/irq_poll.c
-@@ -75,7 +75,7 @@ void irq_poll_complete(struct irq_poll *iop)
- }
- EXPORT_SYMBOL(irq_poll_complete);
-
--static void __latent_entropy irq_poll_softirq(struct softirq_action *h)
-+static void __latent_entropy irq_poll_softirq(void)
- {
- struct list_head *list = this_cpu_ptr(&blk_cpu_iopoll);
- int rearm = 0, budget = irq_poll_budget;
-diff --git a/lib/kobject.c b/lib/kobject.c
-index 97d86dc17c42..388257c2878b 100644
---- a/lib/kobject.c
-+++ b/lib/kobject.c
-@@ -978,9 +978,9 @@ EXPORT_SYMBOL_GPL(kset_create_and_add);
-
-
- static DEFINE_SPINLOCK(kobj_ns_type_lock);
--static const struct kobj_ns_type_operations *kobj_ns_ops_tbl[KOBJ_NS_TYPES];
-+static const struct kobj_ns_type_operations *kobj_ns_ops_tbl[KOBJ_NS_TYPES] __ro_after_init;
-
--int kobj_ns_type_register(const struct kobj_ns_type_operations *ops)
-+int __init kobj_ns_type_register(const struct kobj_ns_type_operations *ops)
- {
- enum kobj_ns_type type = ops->type;
- int error;
-diff --git a/lib/nlattr.c b/lib/nlattr.c
-index e335bcafa9e4..f6334f882b1f 100644
---- a/lib/nlattr.c
-+++ b/lib/nlattr.c
-@@ -364,6 +364,8 @@ int nla_memcpy(void *dest, const struct nlattr *src, int count)
- {
- int minlen = min_t(int, count, nla_len(src));
-
-+ BUG_ON(minlen < 0);
-+
- memcpy(dest, nla_data(src), minlen);
- if (count > minlen)
- memset(dest + minlen, 0, count - minlen);
-diff --git a/lib/vsprintf.c b/lib/vsprintf.c
-index 812e59e13fe6..2c2104884c81 100644
---- a/lib/vsprintf.c
-+++ b/lib/vsprintf.c
-@@ -1371,7 +1371,7 @@ char *pointer_string(char *buf, char *end, const void *ptr,
- return number(buf, end, (unsigned long int)ptr, spec);
- }
-
--int kptr_restrict __read_mostly;
-+int kptr_restrict __read_mostly = 2;
-
- static noinline_for_stack
- char *restricted_pointer(char *buf, char *end, const void *ptr,
-diff --git a/mm/Kconfig b/mm/Kconfig
-index b457e94ae618..ec2440e66c72 100644
---- a/mm/Kconfig
-+++ b/mm/Kconfig
-@@ -311,7 +311,8 @@ config KSM
- config DEFAULT_MMAP_MIN_ADDR
- int "Low address space to protect from user allocation"
- depends on MMU
-- default 4096
-+ default 32768 if ARM || (ARM64 && COMPAT)
-+ default 65536
- help
- This is the portion of low virtual memory which should be protected
- from userspace allocation. Keeping a user from writing to low pages
-diff --git a/mm/mmap.c b/mm/mmap.c
-index a98f09b83019..d1695e475b37 100644
---- a/mm/mmap.c
-+++ b/mm/mmap.c
-@@ -224,6 +224,13 @@ SYSCALL_DEFINE1(brk, unsigned long, brk)
-
- newbrk = PAGE_ALIGN(brk);
- oldbrk = PAGE_ALIGN(mm->brk);
-+ /* properly handle unaligned min_brk as an empty heap */
-+ if (min_brk & ~PAGE_MASK) {
-+ if (brk == min_brk)
-+ newbrk -= PAGE_SIZE;
-+ if (mm->brk == min_brk)
-+ oldbrk -= PAGE_SIZE;
-+ }
- if (oldbrk == newbrk)
- goto set_brk;
-
-diff --git a/mm/page_alloc.c b/mm/page_alloc.c
-index 7181dfe76440..12e186c11c9a 100644
---- a/mm/page_alloc.c
-+++ b/mm/page_alloc.c
-@@ -66,6 +66,7 @@
- #include <linux/ftrace.h>
- #include <linux/lockdep.h>
- #include <linux/nmi.h>
-+#include <linux/random.h>
-
- #include <asm/sections.h>
- #include <asm/tlbflush.h>
-@@ -99,6 +100,15 @@ int _node_numa_mem_[MAX_NUMNODES];
- DEFINE_MUTEX(pcpu_drain_mutex);
- DEFINE_PER_CPU(struct work_struct, pcpu_drain);
-
-+bool __meminitdata extra_latent_entropy;
-+
-+static int __init setup_extra_latent_entropy(char *str)
-+{
-+ extra_latent_entropy = true;
-+ return 0;
-+}
-+early_param("extra_latent_entropy", setup_extra_latent_entropy);
-+
- #ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY
- volatile unsigned long latent_entropy __latent_entropy;
- EXPORT_SYMBOL(latent_entropy);
-@@ -1055,6 +1065,13 @@ static __always_inline bool free_pages_prepare(struct page *page,
- debug_check_no_obj_freed(page_address(page),
- PAGE_SIZE << order);
- }
-+
-+ if (IS_ENABLED(CONFIG_PAGE_SANITIZE)) {
-+ int i;
-+ for (i = 0; i < (1 << order); i++)
-+ clear_highpage(page + i);
-+ }
-+
- arch_free_page(page, order);
- kernel_poison_pages(page, 1 << order, 0);
- kernel_map_pages(page, 1 << order, 0);
-@@ -1295,6 +1312,21 @@ static void __init __free_pages_boot_core(struct page *page, unsigned int order)
- __ClearPageReserved(p);
- set_page_count(p, 0);
-
-+ if (extra_latent_entropy && !PageHighMem(page) && page_to_pfn(page) < 0x100000) {
-+ unsigned long hash = 0;
-+ size_t index, end = PAGE_SIZE * nr_pages / sizeof hash;
-+ const unsigned long *data = lowmem_page_address(page);
-+
-+ for (index = 0; index < end; index++)
-+ hash ^= hash + data[index];
-+#ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY
-+ latent_entropy ^= hash;
-+ add_device_randomness((const void *)&latent_entropy, sizeof(latent_entropy));
-+#else
-+ add_device_randomness((const void *)&hash, sizeof(hash));
-+#endif
-+ }
-+
- page_zone(page)->managed_pages += nr_pages;
- set_page_refcounted(page);
- __free_pages(page, order);
-@@ -1880,8 +1912,8 @@ static inline int check_new_page(struct page *page)
-
- static inline bool free_pages_prezeroed(void)
- {
-- return IS_ENABLED(CONFIG_PAGE_POISONING_ZERO) &&
-- page_poisoning_enabled();
-+ return IS_ENABLED(CONFIG_PAGE_SANITIZE) ||
-+ (IS_ENABLED(CONFIG_PAGE_POISONING_ZERO) && page_poisoning_enabled());
- }
-
- #ifdef CONFIG_DEBUG_VM
-@@ -1938,6 +1970,11 @@ static void prep_new_page(struct page *page, unsigned int order, gfp_t gfp_flags
-
- post_alloc_hook(page, order, gfp_flags);
-
-+ if (IS_ENABLED(CONFIG_PAGE_SANITIZE_VERIFY)) {
-+ for (i = 0; i < (1 << order); i++)
-+ verify_zero_highpage(page + i);
-+ }
-+
- if (!free_pages_prezeroed() && (gfp_flags & __GFP_ZERO))
- for (i = 0; i < (1 << order); i++)
- clear_highpage(page + i);
-diff --git a/mm/slab.h b/mm/slab.h
-index 9632772e14be..802ff9ee8172 100644
---- a/mm/slab.h
-+++ b/mm/slab.h
-@@ -314,7 +314,11 @@ static inline bool is_root_cache(struct kmem_cache *s)
- static inline bool slab_equal_or_root(struct kmem_cache *s,
- struct kmem_cache *p)
- {
-+#ifdef CONFIG_SLAB_HARDENED
-+ return p == s;
-+#else
- return true;
-+#endif
- }
-
- static inline const char *cache_name(struct kmem_cache *s)
-@@ -366,18 +370,26 @@ static inline struct kmem_cache *cache_from_obj(struct kmem_cache *s, void *x)
- * to not do even the assignment. In that case, slab_equal_or_root
- * will also be a constant.
- */
-- if (!memcg_kmem_enabled() &&
-+ if (!IS_ENABLED(CONFIG_SLAB_HARDENED) &&
-+ !memcg_kmem_enabled() &&
- !unlikely(s->flags & SLAB_CONSISTENCY_CHECKS))
- return s;
-
- page = virt_to_head_page(x);
-+#ifdef CONFIG_SLAB_HARDENED
-+ BUG_ON(!PageSlab(page));
-+#endif
- cachep = page->slab_cache;
- if (slab_equal_or_root(cachep, s))
- return cachep;
-
- pr_err("%s: Wrong slab cache. %s but object is from %s\n",
- __func__, s->name, cachep->name);
-+#ifdef CONFIG_BUG_ON_DATA_CORRUPTION
-+ BUG_ON(1);
-+#else
- WARN_ON_ONCE(1);
-+#endif
- return s;
- }
-
-@@ -402,7 +414,7 @@ static inline size_t slab_ksize(const struct kmem_cache *s)
- * back there or track user information then we can
- * only use the space before that information.
- */
-- if (s->flags & (SLAB_TYPESAFE_BY_RCU | SLAB_STORE_USER))
-+ if ((s->flags & (SLAB_TYPESAFE_BY_RCU | SLAB_STORE_USER)) || IS_ENABLED(CONFIG_SLAB_CANARY))
- return s->inuse;
- /*
- * Else we can use all the padding etc for the allocation
-diff --git a/mm/slab_common.c b/mm/slab_common.c
-index b5776b1301f0..8461504d8346 100644
---- a/mm/slab_common.c
-+++ b/mm/slab_common.c
-@@ -27,10 +27,10 @@
-
- #include "slab.h"
-
--enum slab_state slab_state;
-+enum slab_state slab_state __ro_after_init;
- LIST_HEAD(slab_caches);
- DEFINE_MUTEX(slab_mutex);
--struct kmem_cache *kmem_cache;
-+struct kmem_cache *kmem_cache __ro_after_init;
-
- #ifdef CONFIG_HARDENED_USERCOPY
- bool usercopy_fallback __ro_after_init =
-@@ -58,7 +58,7 @@ static DECLARE_WORK(slab_caches_to_rcu_destroy_work,
- /*
- * Merge control. If this is set then no merging of slab caches will occur.
- */
--static bool slab_nomerge = !IS_ENABLED(CONFIG_SLAB_MERGE_DEFAULT);
-+static bool slab_nomerge __ro_after_init = !IS_ENABLED(CONFIG_SLAB_MERGE_DEFAULT);
-
- static int __init setup_slab_nomerge(char *str)
- {
-diff --git a/mm/slub.c b/mm/slub.c
-index b94ba8d35a02..ca9d18891363 100644
---- a/mm/slub.c
-+++ b/mm/slub.c
-@@ -124,6 +124,16 @@ static inline int kmem_cache_debug(struct kmem_cache *s)
- #endif
- }
-
-+static inline bool has_sanitize(struct kmem_cache *s)
-+{
-+ return IS_ENABLED(CONFIG_SLAB_SANITIZE) && !(s->flags & (SLAB_TYPESAFE_BY_RCU | SLAB_POISON));
-+}
-+
-+static inline bool has_sanitize_verify(struct kmem_cache *s)
-+{
-+ return IS_ENABLED(CONFIG_SLAB_SANITIZE_VERIFY) && has_sanitize(s);
-+}
-+
- void *fixup_red_left(struct kmem_cache *s, void *p)
- {
- if (kmem_cache_debug(s) && s->flags & SLAB_RED_ZONE)
-@@ -297,6 +307,35 @@ static inline void set_freepointer(struct kmem_cache *s, void *object, void *fp)
- *(void **)freeptr_addr = freelist_ptr(s, fp, freeptr_addr);
- }
-
-+#ifdef CONFIG_SLAB_CANARY
-+static inline unsigned long *get_canary(struct kmem_cache *s, void *object)
-+{
-+ if (s->offset)
-+ return object + s->offset + sizeof(void *);
-+ return object + s->inuse;
-+}
-+
-+static inline unsigned long get_canary_value(const void *canary, unsigned long value)
-+{
-+ return (value ^ (unsigned long)canary) & CANARY_MASK;
-+}
-+
-+static inline void set_canary(struct kmem_cache *s, void *object, unsigned long value)
-+{
-+ unsigned long *canary = get_canary(s, object);
-+ *canary = get_canary_value(canary, value);
-+}
-+
-+static inline void check_canary(struct kmem_cache *s, void *object, unsigned long value)
-+{
-+ unsigned long *canary = get_canary(s, object);
-+ BUG_ON(*canary != get_canary_value(canary, value));
-+}
-+#else
-+#define set_canary(s, object, value)
-+#define check_canary(s, object, value)
-+#endif
-+
- /* Loop over all objects in a slab */
- #define for_each_object(__p, __s, __addr, __objects) \
- for (__p = fixup_red_left(__s, __addr); \
-@@ -469,13 +508,13 @@ static inline void *restore_red_left(struct kmem_cache *s, void *p)
- * Debug settings:
- */
- #if defined(CONFIG_SLUB_DEBUG_ON)
--static slab_flags_t slub_debug = DEBUG_DEFAULT_FLAGS;
-+static slab_flags_t slub_debug __ro_after_init = DEBUG_DEFAULT_FLAGS;
- #else
--static slab_flags_t slub_debug;
-+static slab_flags_t slub_debug __ro_after_init;
- #endif
-
--static char *slub_debug_slabs;
--static int disable_higher_order_debug;
-+static char *slub_debug_slabs __ro_after_init;
-+static int disable_higher_order_debug __ro_after_init;
-
- /*
- * slub is about to manipulate internal object metadata. This memory lies
-@@ -535,6 +574,9 @@ static struct track *get_track(struct kmem_cache *s, void *object,
- else
- p = object + s->inuse;
-
-+ if (IS_ENABLED(CONFIG_SLAB_CANARY))
-+ p = (void *)p + sizeof(void *);
-+
- return p + alloc;
- }
-
-@@ -674,6 +716,9 @@ static void print_trailer(struct kmem_cache *s, struct page *page, u8 *p)
- else
- off = s->inuse;
-
-+ if (IS_ENABLED(CONFIG_SLAB_CANARY))
-+ off += sizeof(void *);
-+
- if (s->flags & SLAB_STORE_USER)
- off += 2 * sizeof(struct track);
-
-@@ -803,6 +848,9 @@ static int check_pad_bytes(struct kmem_cache *s, struct page *page, u8 *p)
- /* Freepointer is placed after the object. */
- off += sizeof(void *);
-
-+ if (IS_ENABLED(CONFIG_SLAB_CANARY))
-+ off += sizeof(void *);
-+
- if (s->flags & SLAB_STORE_USER)
- /* We also have user information there */
- off += 2 * sizeof(struct track);
-@@ -1417,8 +1465,9 @@ static void setup_object(struct kmem_cache *s, struct page *page,
- void *object)
- {
- setup_object_debug(s, page, object);
-+ set_canary(s, object, s->random_inactive);
- kasan_init_slab_obj(s, object);
-- if (unlikely(s->ctor)) {
-+ if (unlikely(s->ctor) && !has_sanitize_verify(s)) {
- kasan_unpoison_object_data(s, object);
- s->ctor(object);
- kasan_poison_object_data(s, object);
-@@ -2708,9 +2757,21 @@ static __always_inline void *slab_alloc_node(struct kmem_cache *s,
- stat(s, ALLOC_FASTPATH);
- }
-
-- if (unlikely(gfpflags & __GFP_ZERO) && object)
-+ if (has_sanitize_verify(s) && object) {
-+ size_t offset = s->offset ? 0 : sizeof(void *);
-+ BUG_ON(memchr_inv(object + offset, 0, s->object_size - offset));
-+ if (s->ctor)
-+ s->ctor(object);
-+ if (unlikely(gfpflags & __GFP_ZERO) && offset)
-+ memset(object, 0, sizeof(void *));
-+ } else if (unlikely(gfpflags & __GFP_ZERO) && object)
- memset(object, 0, s->object_size);
-
-+ if (object) {
-+ check_canary(s, object, s->random_inactive);
-+ set_canary(s, object, s->random_active);
-+ }
-+
- slab_post_alloc_hook(s, gfpflags, 1, &object);
-
- return object;
-@@ -2917,6 +2978,27 @@ static __always_inline void do_slab_free(struct kmem_cache *s,
- void *tail_obj = tail ? : head;
- struct kmem_cache_cpu *c;
- unsigned long tid;
-+ bool sanitize = has_sanitize(s);
-+
-+ if (IS_ENABLED(CONFIG_SLAB_CANARY) || sanitize) {
-+ __maybe_unused int offset = s->offset ? 0 : sizeof(void *);
-+ void *x = head;
-+
-+ while (1) {
-+ check_canary(s, x, s->random_active);
-+ set_canary(s, x, s->random_inactive);
-+
-+ if (sanitize) {
-+ memset(x + offset, 0, s->object_size - offset);
-+ if (!IS_ENABLED(CONFIG_SLAB_SANITIZE_VERIFY) && s->ctor)
-+ s->ctor(x);
-+ }
-+ if (x == tail_obj)
-+ break;
-+ x = get_freepointer(s, x);
-+ }
-+ }
-+
- redo:
- /*
- * Determine the currently cpus per cpu slab.
-@@ -3095,7 +3177,7 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size,
- void **p)
- {
- struct kmem_cache_cpu *c;
-- int i;
-+ int i, k;
-
- /* memcg and kmem_cache debug support */
- s = slab_pre_alloc_hook(s, flags);
-@@ -3141,13 +3223,29 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size,
- local_irq_enable();
-
- /* Clear memory outside IRQ disabled fastpath loop */
-- if (unlikely(flags & __GFP_ZERO)) {
-+ if (has_sanitize_verify(s)) {
-+ int j;
-+
-+ for (j = 0; j < i; j++) {
-+ size_t offset = s->offset ? 0 : sizeof(void *);
-+ BUG_ON(memchr_inv(p[j] + offset, 0, s->object_size - offset));
-+ if (s->ctor)
-+ s->ctor(p[j]);
-+ if (unlikely(flags & __GFP_ZERO) && offset)
-+ memset(p[j], 0, sizeof(void *));
-+ }
-+ } else if (unlikely(flags & __GFP_ZERO)) {
- int j;
-
- for (j = 0; j < i; j++)
- memset(p[j], 0, s->object_size);
- }
-
-+ for (k = 0; k < i; k++) {
-+ check_canary(s, p[k], s->random_inactive);
-+ set_canary(s, p[k], s->random_active);
-+ }
-+
- /* memcg and kmem_cache debug support */
- slab_post_alloc_hook(s, flags, size, p);
- return i;
-@@ -3179,9 +3277,9 @@ EXPORT_SYMBOL(kmem_cache_alloc_bulk);
- * and increases the number of allocations possible without having to
- * take the list_lock.
- */
--static unsigned int slub_min_order;
--static unsigned int slub_max_order = PAGE_ALLOC_COSTLY_ORDER;
--static unsigned int slub_min_objects;
-+static unsigned int slub_min_order __ro_after_init;
-+static unsigned int slub_max_order __ro_after_init = PAGE_ALLOC_COSTLY_ORDER;
-+static unsigned int slub_min_objects __ro_after_init;
-
- /*
- * Calculate the order of allocation given an slab object size.
-@@ -3353,6 +3451,7 @@ static void early_kmem_cache_node_alloc(int node)
- init_object(kmem_cache_node, n, SLUB_RED_ACTIVE);
- init_tracking(kmem_cache_node, n);
- #endif
-+ set_canary(kmem_cache_node, n, kmem_cache_node->random_active);
- kasan_kmalloc(kmem_cache_node, n, sizeof(struct kmem_cache_node),
- GFP_KERNEL);
- init_kmem_cache_node(n);
-@@ -3509,6 +3608,9 @@ static int calculate_sizes(struct kmem_cache *s, int forced_order)
- size += sizeof(void *);
- }
-
-+ if (IS_ENABLED(CONFIG_SLAB_CANARY))
-+ size += sizeof(void *);
-+
- #ifdef CONFIG_SLUB_DEBUG
- if (flags & SLAB_STORE_USER)
- /*
-@@ -3581,6 +3683,10 @@ static int kmem_cache_open(struct kmem_cache *s, slab_flags_t flags)
- #ifdef CONFIG_SLAB_FREELIST_HARDENED
- s->random = get_random_long();
- #endif
-+#ifdef CONFIG_SLAB_CANARY
-+ s->random_active = get_random_long();
-+ s->random_inactive = get_random_long();
-+#endif
-
- if (!calculate_sizes(s, -1))
- goto error;
-@@ -3857,6 +3963,8 @@ void __check_heap_object(const void *ptr, unsigned long n, struct page *page,
- offset -= s->red_left_pad;
- }
-
-+ check_canary(s, (void *)ptr - offset, s->random_active);
-+
- /* Allow address range falling entirely within usercopy region. */
- if (offset >= s->useroffset &&
- offset - s->useroffset <= s->usersize &&
-@@ -3890,7 +3998,11 @@ static size_t __ksize(const void *object)
- page = virt_to_head_page(object);
-
- if (unlikely(!PageSlab(page))) {
-+#ifdef CONFIG_BUG_ON_DATA_CORRUPTION
-+ BUG_ON(!PageCompound(page));
-+#else
- WARN_ON(!PageCompound(page));
-+#endif
- return PAGE_SIZE << compound_order(page);
- }
-
-@@ -4750,7 +4862,7 @@ enum slab_stat_type {
- #define SO_TOTAL (1 << SL_TOTAL)
-
- #ifdef CONFIG_MEMCG
--static bool memcg_sysfs_enabled = IS_ENABLED(CONFIG_SLUB_MEMCG_SYSFS_ON);
-+static bool memcg_sysfs_enabled __ro_after_init = IS_ENABLED(CONFIG_SLUB_MEMCG_SYSFS_ON);
-
- static int __init setup_slub_memcg_sysfs(char *str)
- {
-diff --git a/mm/swap.c b/mm/swap.c
-index 45fdbfb6b2a6..55ec851eb819 100644
---- a/mm/swap.c
-+++ b/mm/swap.c
-@@ -93,6 +93,13 @@ static void __put_compound_page(struct page *page)
- if (!PageHuge(page))
- __page_cache_release(page);
- dtor = get_compound_page_dtor(page);
-+ if (!PageHuge(page))
-+ BUG_ON(dtor != free_compound_page
-+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
-+ && dtor != free_transhuge_page
-+#endif
-+ );
-+
- (*dtor)(page);
- }
-
-diff --git a/net/core/dev.c b/net/core/dev.c
-index 4b1053057ca6..c0efe00432c3 100644
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -4533,7 +4533,7 @@ int netif_rx_ni(struct sk_buff *skb)
- }
- EXPORT_SYMBOL(netif_rx_ni);
-
--static __latent_entropy void net_tx_action(struct softirq_action *h)
-+static __latent_entropy void net_tx_action(void)
- {
- struct softnet_data *sd = this_cpu_ptr(&softnet_data);
-
-@@ -6311,7 +6311,7 @@ static int napi_poll(struct napi_struct *n, struct list_head *repoll)
- return work;
- }
-
--static __latent_entropy void net_rx_action(struct softirq_action *h)
-+static __latent_entropy void net_rx_action(void)
- {
- struct softnet_data *sd = this_cpu_ptr(&softnet_data);
- unsigned long time_limit = jiffies +
-diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
-index 6cec08cd0bb9..ffc74355a94d 100644
---- a/net/core/sysctl_net_core.c
-+++ b/net/core/sysctl_net_core.c
-@@ -36,6 +36,10 @@ static int net_msg_warn; /* Unused, but still a sysctl */
- int sysctl_fb_tunnels_only_for_init_net __read_mostly = 0;
- EXPORT_SYMBOL(sysctl_fb_tunnels_only_for_init_net);
-
-+#ifdef CONFIG_HARDENED_STEALTH_NETWORKING
-+int sysctl_stealth_blackhole __read_mostly = 1;
-+#endif
-+
- #ifdef CONFIG_RPS
- static int rps_sock_flow_sysctl(struct ctl_table *table, int write,
- void __user *buffer, size_t *lenp, loff_t *ppos)
-@@ -505,6 +509,17 @@ static struct ctl_table net_core_table[] = {
- .proc_handler = set_default_qdisc
- },
- #endif
-+#ifdef CONFIG_HARDENED_STEALTH_NETWORKING
-+ {
-+ .procname = "ip_blackhole",
-+ .data = &sysctl_stealth_blackhole,
-+ .maxlen = sizeof(int),
-+ .mode = 0644,
-+ .proc_handler = proc_dointvec_minmax,
-+ .extra1 = &zero,
-+ .extra2 = &one,
-+ },
-+#endif
- #endif /* CONFIG_NET */
- {
- .procname = "netdev_budget",
-diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
-index 2e12f848203a..4115419d5e35 100644
---- a/net/ipv4/Kconfig
-+++ b/net/ipv4/Kconfig
-@@ -266,6 +266,7 @@ config IP_PIMSM_V2
-
- config SYN_COOKIES
- bool "IP: TCP syncookie support"
-+ default y
- ---help---
- Normal TCP/IP networking is open to an attack known as "SYN
- flooding". This denial-of-service attack prevents legitimate remote
-diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
-index 4efa5e33513e..ae82ff1ea5e7 100644
---- a/net/ipv4/icmp.c
-+++ b/net/ipv4/icmp.c
-@@ -195,6 +195,10 @@ struct icmp_control {
- short error; /* This ICMP is classed as an error message */
- };
-
-+#ifdef CONFIG_HARDENED_STEALTH_NETWORKING
-+extern int sysctl_stealth_blackhole;
-+#endif
-+
- static const struct icmp_control icmp_pointers[NR_ICMP_TYPES+1];
-
- /*
-@@ -934,6 +938,11 @@ static bool icmp_echo(struct sk_buff *skb)
- {
- struct net *net;
-
-+#ifdef CONFIG_HARDENED_STEALTH_NETWORKING
-+ if (likely(sysctl_stealth_blackhole) && !(skb->dev->flags & IFF_LOOPBACK))
-+ return true;
-+#endif
-+
- net = dev_net(skb_dst(skb)->dev);
- if (!net->ipv4.sysctl_icmp_echo_ignore_all) {
- struct icmp_bxm icmp_param;
-@@ -960,6 +969,12 @@ static bool icmp_echo(struct sk_buff *skb)
- static bool icmp_timestamp(struct sk_buff *skb)
- {
- struct icmp_bxm icmp_param;
-+
-+#ifdef CONFIG_HARDENED_STEALTH_NETWORKING
-+ if (likely(sysctl_stealth_blackhole) && !(skb->dev->flags & IFF_LOOPBACK))
-+ return true;
-+#endif
-+
- /*
- * Too short.
- */
-diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
-index 523d26f5e22e..10070b040661 100644
---- a/net/ipv4/igmp.c
-+++ b/net/ipv4/igmp.c
-@@ -136,6 +136,10 @@
- ((in_dev)->mr_v2_seen && \
- time_before(jiffies, (in_dev)->mr_v2_seen)))
-
-+#ifdef CONFIG_HARDENED_STEALTH_NETWORKING
-+extern int sysctl_stealth_blackhole;
-+#endif
-+
- static int unsolicited_report_interval(struct in_device *in_dev)
- {
- int interval_ms, interval_jiffies;
-@@ -737,6 +741,11 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
- __be32 dst;
- int hlen, tlen;
-
-+#ifdef CONFIG_HARDENED_STEALTH_NETWORKING
-+ if (likely(sysctl_stealth_blackhole))
-+ return -1;
-+#endif
-+
- if (type == IGMPV3_HOST_MEMBERSHIP_REPORT)
- return igmpv3_send_report(in_dev, pmc);
-
-diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
-index 7441ecfc8320..662e902f48a4 100644
---- a/net/ipv4/tcp_input.c
-+++ b/net/ipv4/tcp_input.c
-@@ -308,11 +308,13 @@ static void tcp_ecn_rcv_synack(struct tcp_sock *tp, const struct tcphdr *th)
- tp->ecn_flags &= ~TCP_ECN_OK;
- }
-
-+#ifndef CONFIG_HARDENED_NO_SIMULT_CONNECT
- static void tcp_ecn_rcv_syn(struct tcp_sock *tp, const struct tcphdr *th)
- {
- if ((tp->ecn_flags & TCP_ECN_OK) && (!th->ece || !th->cwr))
- tp->ecn_flags &= ~TCP_ECN_OK;
- }
-+#endif
-
- static bool tcp_ecn_rcv_ecn_echo(const struct tcp_sock *tp, const struct tcphdr *th)
- {
-@@ -5938,6 +5940,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
- tcp_paws_reject(&tp->rx_opt, 0))
- goto discard_and_undo;
-
-+#ifndef CONFIG_HARDENED_NO_SIMULT_CONNECT
- if (th->syn) {
- /* We see SYN without ACK. It is attempt of
- * simultaneous connect with crossed SYNs.
-@@ -5989,6 +5992,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
- goto discard;
- #endif
- }
-+#endif
- /* "fifth, if neither of the SYN or RST bits is set then
- * drop the segment and return."
- */
-diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
-index 6da393016c11..e6171d1ea7c9 100644
---- a/net/ipv4/tcp_ipv4.c
-+++ b/net/ipv4/tcp_ipv4.c
-@@ -95,6 +95,10 @@ static int tcp_v4_md5_hash_hdr(char *md5_hash, const struct tcp_md5sig_key *key,
- struct inet_hashinfo tcp_hashinfo;
- EXPORT_SYMBOL(tcp_hashinfo);
-
-+#ifdef CONFIG_HARDENED_STEALTH_NETWORKING
-+extern int sysctl_stealth_blackhole;
-+#endif
-+
- static u32 tcp_v4_init_seq(const struct sk_buff *skb)
- {
- return secure_tcp_seq(ip_hdr(skb)->daddr,
-@@ -1561,6 +1565,9 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
- return 0;
-
- reset:
-+#ifdef CONFIG_HARDENED_STEALTH_NETWORKING
-+ if (!likely(sysctl_stealth_blackhole))
-+#endif
- tcp_v4_send_reset(rsk, skb);
- discard:
- kfree_skb(skb);
-@@ -1709,6 +1716,27 @@ int tcp_v4_rcv(struct sk_buff *skb)
- if (!pskb_may_pull(skb, th->doff * 4))
- goto discard_it;
-
-+#ifdef CONFIG_HARDENED_STEALTH_NETWORKING
-+ if (likely(sysctl_stealth_blackhole) &&
-+ (
-+ th->res1 || !tcp_flag_word(th) ||
-+ tcp_flag_word(th) == TCP_FLAG_PSH ||
-+ tcp_flag_word(th) & (TCP_FLAG_CWR | TCP_FLAG_ECE) ||
-+ (
-+ tcp_flag_word(th) &
-+ (TCP_FLAG_SYN | TCP_FLAG_FIN | TCP_FLAG_RST) &&
-+ tcp_flag_word(th) & TCP_FLAG_URG
-+ ) ||
-+ (
-+ tcp_flag_word(th) &
-+ (TCP_FLAG_FIN | TCP_FLAG_RST) &&
-+ tcp_flag_word(th) & TCP_FLAG_SYN
-+ )
-+ )
-+ )
-+ goto discard_it;
-+#endif
-+
- /* An explanation is required here, I think.
- * Packet length and doff are validated by header prediction,
- * provided case of th->doff==0 is eliminated.
-@@ -1722,12 +1750,22 @@ int tcp_v4_rcv(struct sk_buff *skb)
- lookup:
- sk = __inet_lookup_skb(&tcp_hashinfo, skb, __tcp_hdrlen(th), th->source,
- th->dest, sdif, &refcounted);
-- if (!sk)
-+ if (!sk) {
-+#ifdef CONFIG_HARDENED_STEALTH_NETWORKING
-+ ret = 1;
-+#endif
-+
- goto no_tcp_socket;
-+ }
-
- process:
-- if (sk->sk_state == TCP_TIME_WAIT)
-+ if (sk->sk_state == TCP_TIME_WAIT) {
-+#ifdef CONFIG_HARDENED_STEALTH_NETWORKING
-+ ret = 2;
-+#endif
-+
- goto do_time_wait;
-+ }
-
- if (sk->sk_state == TCP_NEW_SYN_RECV) {
- struct request_sock *req = inet_reqsk(sk);
-@@ -1841,6 +1879,11 @@ int tcp_v4_rcv(struct sk_buff *skb)
- bad_packet:
- __TCP_INC_STATS(net, TCP_MIB_INERRS);
- } else {
-+#ifdef CONFIG_HARDENED_STEALTH_NETWORKING
-+ if (!sysctl_stealth_blackhole || (ret == 1 &&
-+ (skb->dev->flags & IFF_LOOPBACK)))
-+#endif
-+
- tcp_v4_send_reset(NULL, skb);
- }
-
-diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
-index 7ba8a90772b0..8c359b649bcd 100644
---- a/net/ipv4/tcp_minisocks.c
-+++ b/net/ipv4/tcp_minisocks.c
-@@ -29,6 +29,10 @@
- #include <net/xfrm.h>
- #include <net/busy_poll.h>
-
-+#ifdef CONFIG_HARDENED_STEALTH_NETWORKING
-+extern int sysctl_stealth_blackhole;
-+#endif
-+
- static bool tcp_in_window(u32 seq, u32 end_seq, u32 s_win, u32 e_win)
- {
- if (seq == s_win)
-@@ -809,6 +813,10 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
- * avoid becoming vulnerable to outside attack aiming at
- * resetting legit local connections.
- */
-+#ifdef CONFIG_HARDENED_STEALTH_NETWORKING
-+ if (!sysctl_stealth_blackhole || skb->dev->flags & IFF_LOOPBACK)
-+#endif
-+
- req->rsk_ops->send_reset(sk, skb);
- } else if (fastopen) { /* received a valid RST pkt */
- reqsk_fastopen_remove(sk, req, true);
-diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
-index 0ef04cda1b27..6cb1efa826dc 100644
---- a/net/ipv4/udp.c
-+++ b/net/ipv4/udp.c
-@@ -128,6 +128,10 @@ EXPORT_SYMBOL(udp_memory_allocated);
- #define MAX_UDP_PORTS 65536
- #define PORTS_PER_CHAIN (MAX_UDP_PORTS / UDP_HTABLE_SIZE_MIN)
-
-+#ifdef CONFIG_HARDENED_STEALTH_NETWORKING
-+extern int sysctl_stealth_blackhole;
-+#endif
-+
- /* IPCB reference means this can not be used from early demux */
- static bool udp_lib_exact_dif_match(struct net *net, struct sk_buff *skb)
- {
-@@ -2262,6 +2266,9 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
- goto csum_error;
-
- __UDP_INC_STATS(net, UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE);
-+#ifdef CONFIG_HARDENED_STEALTH_NETWORKING
-+ if (!likely(sysctl_stealth_blackhole) || (skb->dev->flags & IFF_LOOPBACK))
-+#endif
- icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
-
- /*
-diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
-index 6d14cbe443f8..4eeebbdc452e 100644
---- a/net/ipv6/icmp.c
-+++ b/net/ipv6/icmp.c
-@@ -72,6 +72,10 @@
-
- #include <linux/uaccess.h>
-
-+#ifdef CONFIG_HARDENED_STEALTH_NETWORKING
-+extern int sysctl_stealth_blackhole;
-+#endif
-+
- /*
- * The ICMP socket(s). This is the most convenient way to flow control
- * our ICMP output as well as maintain a clean interface throughout
-@@ -848,6 +852,9 @@ static int icmpv6_rcv(struct sk_buff *skb)
-
- switch (type) {
- case ICMPV6_ECHO_REQUEST:
-+#ifdef CONFIG_HARDENED_STEALTH_NETWORKING
-+ if (!sysctl_stealth_blackhole || skb->dev->flags & IFF_LOOPBACK)
-+#endif
- if (!net->ipv6.sysctl.icmpv6_echo_ignore_all)
- icmpv6_echo_reply(skb);
- break;
-diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
-index 2e76ebfdc907..5f98b9f4b57d 100644
---- a/net/ipv6/tcp_ipv6.c
-+++ b/net/ipv6/tcp_ipv6.c
-@@ -71,6 +71,10 @@
-
- #include <trace/events/tcp.h>
-
-+#ifdef CONFIG_HARDENED_STEALTH_NETWORKING
-+extern int sysctl_stealth_blackhole;
-+#endif
-+
- static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb);
- static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb,
- struct request_sock *req);
-@@ -1355,6 +1359,10 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
- return 0;
-
- reset:
-+#ifdef CONFIG_HARDENED_STEALTH_NETWORKING
-+ if (!likely(sysctl_stealth_blackhole))
-+#endif
-+
- tcp_v6_send_reset(sk, skb);
- discard:
- if (opt_skb)
-@@ -1452,6 +1460,27 @@ static int tcp_v6_rcv(struct sk_buff *skb)
- if (!pskb_may_pull(skb, th->doff*4))
- goto discard_it;
-
-+#ifdef CONFIG_HARDENED_STEALTH_NETWORKING
-+ if (likely(sysctl_stealth_blackhole) &&
-+ (
-+ th->res1 || !tcp_flag_word(th) ||
-+ tcp_flag_word(th) == TCP_FLAG_PSH ||
-+ tcp_flag_word(th) & (TCP_FLAG_CWR | TCP_FLAG_ECE) ||
-+ (
-+ tcp_flag_word(th) &
-+ (TCP_FLAG_SYN | TCP_FLAG_FIN | TCP_FLAG_RST) &&
-+ tcp_flag_word(th) & TCP_FLAG_URG
-+ ) ||
-+ (
-+ tcp_flag_word(th) &
-+ (TCP_FLAG_FIN | TCP_FLAG_RST) &&
-+ tcp_flag_word(th) & TCP_FLAG_SYN
-+ )
-+ )
-+ )
-+ goto discard_it;
-+#endif
-+
- if (skb_checksum_init(skb, IPPROTO_TCP, ip6_compute_pseudo))
- goto csum_error;
-
-@@ -1462,12 +1491,22 @@ static int tcp_v6_rcv(struct sk_buff *skb)
- sk = __inet6_lookup_skb(&tcp_hashinfo, skb, __tcp_hdrlen(th),
- th->source, th->dest, inet6_iif(skb), sdif,
- &refcounted);
-- if (!sk)
-+ if (!sk) {
-+#ifdef CONFIG_HARDENED_STEALTH_NETWORKING
-+ ret = 1;
-+#endif
-+
- goto no_tcp_socket;
-+ }
-
- process:
-- if (sk->sk_state == TCP_TIME_WAIT)
-+ if (sk->sk_state == TCP_TIME_WAIT) {
-+#ifdef CONFIG_HARDENED_STEALTH_NETWORKING
-+ ret = 2;
-+#endif
-+
- goto do_time_wait;
-+ }
-
- if (sk->sk_state == TCP_NEW_SYN_RECV) {
- struct request_sock *req = inet_reqsk(sk);
-@@ -1575,6 +1614,11 @@ static int tcp_v6_rcv(struct sk_buff *skb)
- bad_packet:
- __TCP_INC_STATS(net, TCP_MIB_INERRS);
- } else {
-+#ifdef CONFIG_HARDENED_STEALTH_NETWORKING
-+ if (!sysctl_stealth_blackhole || (ret == 1 &&
-+ (skb->dev->flags & IFF_LOOPBACK)))
-+#endif
-+
- tcp_v6_send_reset(NULL, skb);
- }
-
-diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
-index 1979922bcf67..6a8a3666648f 100644
---- a/net/ipv6/udp.c
-+++ b/net/ipv6/udp.c
-@@ -56,6 +56,10 @@
- #include <trace/events/skb.h>
- #include "udp_impl.h"
-
-+#ifdef CONFIG_HARDENED_STEALTH_NETWORKING
-+extern int sysctl_stealth_blackhole;
-+#endif
-+
- static bool udp6_lib_exact_dif_match(struct net *net, struct sk_buff *skb)
- {
- #if defined(CONFIG_NET_L3_MASTER_DEV)
-@@ -863,6 +867,9 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
- goto csum_error;
-
- __UDP6_INC_STATS(net, UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE);
-+#ifdef CONFIG_HARDENED_STEALTH_NETWORKING
-+ if (!likely(sysctl_stealth_blackhole) || skb->dev->flags & IFF_LOOPBACK)
-+#endif
- icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);
-
- kfree_skb(skb);
-diff --git a/scripts/gcc-plugins/Kconfig b/scripts/gcc-plugins/Kconfig
-index cb0c889e13aa..305f52f58c1a 100644
---- a/scripts/gcc-plugins/Kconfig
-+++ b/scripts/gcc-plugins/Kconfig
-@@ -59,6 +59,11 @@ config GCC_PLUGIN_LATENT_ENTROPY
- is some slowdown of the boot process (about 0.5%) and fork and
- irq processing.
-
-+ When extra_latent_entropy is passed on the kernel command line,
-+ entropy will be extracted from up to the first 4GB of RAM while the
-+ runtime memory allocator is being initialized. This costs even more
-+ slowdown of the boot process.
-+
- Note that entropy extracted this way is not cryptographically
- secure!
-
-diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
-index 91a80036c05d..41692ca62c98 100644
---- a/scripts/mod/modpost.c
-+++ b/scripts/mod/modpost.c
-@@ -35,6 +35,7 @@ static int vmlinux_section_warnings = 1;
- static int warn_unresolved = 0;
- /* How a symbol is exported */
- static int sec_mismatch_count = 0;
-+static int writable_fptr_count = 0;
- static int sec_mismatch_verbose = 1;
- static int sec_mismatch_fatal = 0;
- /* ignore missing files */
-@@ -954,6 +955,7 @@ enum mismatch {
- ANY_EXIT_TO_ANY_INIT,
- EXPORT_TO_INIT_EXIT,
- EXTABLE_TO_NON_TEXT,
-+ DATA_TO_TEXT
- };
-
- /**
-@@ -1080,6 +1082,12 @@ static const struct sectioncheck sectioncheck[] = {
- .good_tosec = {ALL_TEXT_SECTIONS , NULL},
- .mismatch = EXTABLE_TO_NON_TEXT,
- .handler = extable_mismatch_handler,
-+},
-+/* Do not reference code from writable data */
-+{
-+ .fromsec = { DATA_SECTIONS, NULL },
-+ .bad_tosec = { ALL_TEXT_SECTIONS, NULL },
-+ .mismatch = DATA_TO_TEXT
- }
- };
-
-@@ -1267,10 +1275,10 @@ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr,
- continue;
- if (!is_valid_name(elf, sym))
- continue;
-- if (sym->st_value == addr)
-- return sym;
- /* Find a symbol nearby - addr are maybe negative */
- d = sym->st_value - addr;
-+ if (d == 0)
-+ return sym;
- if (d < 0)
- d = addr - sym->st_value;
- if (d < distance) {
-@@ -1405,7 +1413,11 @@ static void report_sec_mismatch(const char *modname,
- char *prl_from;
- char *prl_to;
-
-- sec_mismatch_count++;
-+ if (mismatch->mismatch == DATA_TO_TEXT)
-+ writable_fptr_count++;
-+ else
-+ sec_mismatch_count++;
-+
- if (!sec_mismatch_verbose)
- return;
-
-@@ -1529,6 +1541,14 @@ static void report_sec_mismatch(const char *modname,
- fatal("There's a special handler for this mismatch type, "
- "we should never get here.");
- break;
-+ case DATA_TO_TEXT:
-+#if 0
-+ fprintf(stderr,
-+ "The %s %s:%s references\n"
-+ "the %s %s:%s%s\n",
-+ from, fromsec, fromsym, to, tosec, tosym, to_p);
-+#endif
-+ break;
- }
- fprintf(stderr, "\n");
- }
-@@ -2540,6 +2560,14 @@ int main(int argc, char **argv)
- }
- }
- free(buf.p);
-+ if (writable_fptr_count) {
-+ if (!sec_mismatch_verbose) {
-+ warn("modpost: Found %d writable function pointer(s).\n"
-+ "To see full details build your kernel with:\n"
-+ "'make CONFIG_DEBUG_SECTION_MISMATCH=y'\n",
-+ writable_fptr_count);
-+ }
-+ }
-
- return err;
- }
-diff --git a/security/Kconfig b/security/Kconfig
-index d9aa521b5206..438acc17532e 100644
---- a/security/Kconfig
-+++ b/security/Kconfig
-@@ -8,7 +8,7 @@ source security/keys/Kconfig
-
- config SECURITY_DMESG_RESTRICT
- bool "Restrict unprivileged access to the kernel syslog"
-- default n
-+ default y
- help
- This enforces restrictions on unprivileged users reading the kernel
- syslog via dmesg(8).
-@@ -18,10 +18,34 @@ config SECURITY_DMESG_RESTRICT
-
- If you are unsure how to answer this question, answer N.
-
-+config SECURITY_PERF_EVENTS_RESTRICT
-+ bool "Restrict unprivileged use of performance events"
-+ depends on PERF_EVENTS
-+ default y
-+ help
-+ If you say Y here, the kernel.perf_event_paranoid sysctl
-+ will be set to 3 by default, and no unprivileged use of the
-+ perf_event_open syscall will be permitted unless it is
-+ changed.
-+
-+config SECURITY_TIOCSTI_RESTRICT
-+ bool "Restrict unprivileged use of tiocsti command injection"
-+ default y
-+ help
-+ This enforces restrictions on unprivileged users injecting commands
-+ into other processes which share a tty session using the TIOCSTI
-+ ioctl. This option makes TIOCSTI use require CAP_SYS_ADMIN.
-+
-+ If this option is not selected, no restrictions will be enforced
-+ unless the tiocsti_restrict sysctl is explicitly set to (1).
-+
-+ If you are unsure how to answer this question, answer N.
-+
- config SECURITY
- bool "Enable different security models"
- depends on SYSFS
- depends on MULTIUSER
-+ default y
- help
- This allows you to choose different security modules to be
- configured into your kernel.
-@@ -48,6 +72,7 @@ config SECURITYFS
- config SECURITY_NETWORK
- bool "Socket and Networking Security Hooks"
- depends on SECURITY
-+ default y
- help
- This enables the socket and networking security hooks.
- If enabled, a security module can use these hooks to
-@@ -154,6 +179,7 @@ config HARDENED_USERCOPY
- bool "Harden memory copies between kernel and userspace"
- depends on HAVE_HARDENED_USERCOPY_ALLOCATOR
- imply STRICT_DEVMEM
-+ default y
- help
- This option checks for obviously wrong memory regions when
- copying memory to/from the kernel (via copy_to_user() and
-@@ -166,7 +192,6 @@ config HARDENED_USERCOPY
- config HARDENED_USERCOPY_FALLBACK
- bool "Allow usercopy whitelist violations to fallback to object size"
- depends on HARDENED_USERCOPY
-- default y
- help
- This is a temporary option that allows missing usercopy whitelists
- to be discovered via a WARN() to the kernel log, instead of
-@@ -191,10 +216,36 @@ config HARDENED_USERCOPY_PAGESPAN
- config FORTIFY_SOURCE
- bool "Harden common str/mem functions against buffer overflows"
- depends on ARCH_HAS_FORTIFY_SOURCE
-+ default y
- help
- Detect overflows of buffers in common string and memory functions
- where the compiler can determine and validate the buffer sizes.
-
-+config FORTIFY_SOURCE_STRICT_STRING
-+ bool "Harden common functions against buffer overflows"
-+ depends on FORTIFY_SOURCE
-+ depends on EXPERT
-+ help
-+ Perform stricter overflow checks catching overflows within objects
-+ for common C string functions rather than only between objects.
-+
-+ This is not yet intended for production use, only bug finding.
-+
-+config PAGE_SANITIZE
-+ bool "Sanitize pages"
-+ default y
-+ help
-+ Zero fill page allocations on free, reducing the lifetime of
-+ sensitive data and helping to mitigate use-after-free bugs.
-+
-+config PAGE_SANITIZE_VERIFY
-+ bool "Verify sanitized pages"
-+ depends on PAGE_SANITIZE
-+ default y
-+ help
-+ Verify that newly allocated pages are zeroed to detect
-+ write-after-free bugs.
-+
- config STATIC_USERMODEHELPER
- bool "Force all usermode helper calls through a single binary"
- help
-@@ -278,3 +329,128 @@ config DEFAULT_SECURITY
-
- endmenu
-
-+menu "Hardened Enhancements"
-+
-+config HARDENED_RANDOM
-+ bool "Enhance the random number generator"
-+ default n
-+ help
-+ Enabling this option enhances the Linux kernel random number generator.
-+ This is done by:
-+ - Increasing the pool size from 4096 bits to 262144 bits. ( 512B -> 32KB )
-+ - Increasing the diffusion via the linear feedback shift register.
-+ - Defines newer 64-bit polynomial fields for the input and output pools.
-+
-+ Overall, this enhances the total entropy available to the system and further
-+ enhances the random number generator.
-+
-+
-+config HARDENED_STEALTH_NETWORKING
-+ bool "Enable stealth networking [GRSECURITY]"
-+ default n
-+ depends on NET
-+ help
-+ If you say Y here, neither TCP resets nor ICMP
-+ destination-unreachable packets will be sent in response to packets
-+ sent to ports for which no associated listening process exists.
-+ This feature supports both IPV4 and IPV6 and exempts the
-+ loopback interface from blackholing. Enabling this feature
-+ makes a host more resilient to DoS attacks and reduces network
-+ visibility against scanners.
-+
-+ The blackhole feature as-implemented is equivalent to the FreeBSD
-+ blackhole feature, as it prevents RST responses to all packets, not
-+ just SYNs. Under most application behavior this causes no
-+ problems, but applications (like haproxy) may not close certain
-+ connections in a way that cleanly terminates them on the remote
-+ end, leaving the remote host in LAST_ACK state. Because of this
-+ side-effect and to prevent intentional LAST_ACK DoSes, this
-+ feature also adds automatic mitigation against such attacks.
-+ The mitigation drastically reduces the amount of time a socket
-+ can spend in LAST_ACK state. If you're using haproxy and not
-+ all servers it connects to have this option enabled, consider
-+ disabling this feature on the haproxy host.
-+
-+ If the sysctl option is enabled, a sysctl option with names
-+ "ip_blackhole" will be created.
-+ This sysctl, "ip_blackhole" takes the standard zero/non-zero
-+ on/off toggle to enable or disable this feature.
-+
-+
-+config HARDENED_NO_SIMULT_CONNECT
-+ bool "Disable simultaneous TCP connections [GRSECURITY]"
-+ default n
-+ depends on NET
-+ help
-+ If you say Y here, a feature by Willy Tarreau will be enabled that
-+ removes a weakness in Linux's strict implementation of TCP that
-+ allows two clients to connect to each other without either entering
-+ a listening state. The weakness allows an attacker to easily prevent
-+ a client from connecting to a known server provided the source port
-+ for the connection is guessed correctly.
-+
-+ As the weakness could be used to prevent an antivirus or IPS from
-+ fetching updates, or prevent an SSL gateway from fetching a CRL,
-+ it should be eliminated by enabling this option. Though Linux is
-+ one of few operating systems supporting simultaneous connect, it
-+ has no legitimate use in practice and is rarely supported by firewalls.
-+
-+
-+config HARDENED_SYSFS_RESTRICT
-+ bool "Restrict SysFS & DebugFS [GRSECURITY]"
-+ default y
-+ depends on SYSFS
-+ help
-+ If you say Y here, sysfs (the pseudo-filesystem mounted at /sys) and
-+ any filesystem normally mounted under it (e.g. debugfs) will be
-+ mostly accessible only by root. These filesystems generally provide access
-+ to hardware and debug information that isn't appropriate for unprivileged
-+ users of the system. Sysfs and debugfs have also become a large source
-+ of new vulnerabilities, ranging from infoleaks to local compromise.
-+ There has been very little oversight with an eye toward security involved
-+ in adding new exporters of information to these filesystems, so their
-+ use is discouraged.
-+ To enable or disable this feature at runtime, use the sysctl
-+ kernel.sysfs_restricted.
-+ For reasons of compatibility, a few directories have been whitelisted
-+ for access by non-root users:
-+ /sys/fs/selinux
-+ /sys/fs/fuse
-+ /sys/devices/system/cpu
-+
-+
-+config HARDENED_FIFO
-+ bool "Restrict FIFO [GRSECURITY]"
-+ default y
-+ help
-+ If you say Y here, users will not be able to write to FIFOs they don't
-+ own in world-writable +t directories (e.g. /tmp), unless the owner of
-+ the FIFO is the same owner of the directory it's held in. If the sysctl
-+ option is enabled, a sysctl option with name "fifo_restrictions" is
-+ created.
-+
-+
-+config HARDENED_MODULE_LOAD
-+ bool "Harden module auto-loading [GRSECURITY]"
-+ default y
-+ depends on MODULES
-+ help
-+ If you say Y here, module auto-loading in response to use of some
-+ feature implemented by an unloaded module will be restricted to
-+ root users. Enabling this option helps defend against attacks
-+ by unprivileged users who abuse the auto-loading behavior to
-+ cause a vulnerable module to load that is then exploited.
-+
-+ If this option prevents a legitimate use of auto-loading for a
-+ non-root user, the administrator can execute modprobe manually
-+ with the exact name of the module mentioned in the alert log.
-+ Alternatively, the administrator can add the module to the list
-+ of modules loaded at boot by modifying init scripts.
-+
-+ Modification of init scripts will most likely be needed on
-+ Ubuntu servers with encrypted home directory support enabled,
-+ as the first non-root user logging in will cause the ecb(aes),
-+ ecb(aes)-all, cbc(aes), and cbc(aes)-all modules to be loaded.
-+
-+
-+endmenu
-diff --git a/security/selinux/Kconfig b/security/selinux/Kconfig
-index 8af7a690eb40..6539694b0fd3 100644
---- a/security/selinux/Kconfig
-+++ b/security/selinux/Kconfig
-@@ -2,7 +2,7 @@ config SECURITY_SELINUX
- bool "NSA SELinux Support"
- depends on SECURITY_NETWORK && AUDIT && NET && INET
- select NETWORK_SECMARK
-- default n
-+ default y
- help
- This selects NSA Security-Enhanced Linux (SELinux).
- You will also need a policy configuration and a labeled filesystem.
-@@ -79,23 +79,3 @@ config SECURITY_SELINUX_AVC_STATS
- This option collects access vector cache statistics to
- /selinux/avc/cache_stats, which may be monitored via
- tools such as avcstat.
--
--config SECURITY_SELINUX_CHECKREQPROT_VALUE
-- int "NSA SELinux checkreqprot default value"
-- depends on SECURITY_SELINUX
-- range 0 1
-- default 0
-- help
-- This option sets the default value for the 'checkreqprot' flag
-- that determines whether SELinux checks the protection requested
-- by the application or the protection that will be applied by the
-- kernel (including any implied execute for read-implies-exec) for
-- mmap and mprotect calls. If this option is set to 0 (zero),
-- SELinux will default to checking the protection that will be applied
-- by the kernel. If this option is set to 1 (one), SELinux will
-- default to checking the protection requested by the application.
-- The checkreqprot flag may be changed from the default via the
-- 'checkreqprot=' boot parameter. It may also be changed at runtime
-- via /selinux/checkreqprot if authorized by policy.
--
-- If you are unsure how to answer this question, answer 0.
-diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
-index 452254fd89f8..1822fa3bc0b3 100644
---- a/security/selinux/hooks.c
-+++ b/security/selinux/hooks.c
-@@ -135,18 +135,7 @@ __setup("selinux=", selinux_enabled_setup);
- int selinux_enabled = 1;
- #endif
-
--static unsigned int selinux_checkreqprot_boot =
-- CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
--
--static int __init checkreqprot_setup(char *str)
--{
-- unsigned long checkreqprot;
--
-- if (!kstrtoul(str, 0, &checkreqprot))
-- selinux_checkreqprot_boot = checkreqprot ? 1 : 0;
-- return 1;
--}
--__setup("checkreqprot=", checkreqprot_setup);
-+static const unsigned int selinux_checkreqprot_boot;
-
- static struct kmem_cache *sel_inode_cache;
- static struct kmem_cache *file_security_cache;
-diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
-index f3a5a138a096..d95f3c5fe6f0 100644
---- a/security/selinux/selinuxfs.c
-+++ b/security/selinux/selinuxfs.c
-@@ -640,7 +640,6 @@ static ssize_t sel_read_checkreqprot(struct file *filp, char __user *buf,
- static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
- {
-- struct selinux_fs_info *fsi = file_inode(file)->i_sb->s_fs_info;
- char *page;
- ssize_t length;
- unsigned int new_value;
-@@ -664,10 +663,9 @@ static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf,
- return PTR_ERR(page);
-
- length = -EINVAL;
-- if (sscanf(page, "%u", &new_value) != 1)
-+ if (sscanf(page, "%u", &new_value) != 1 || new_value)
- goto out;
-
-- fsi->state->checkreqprot = new_value ? 1 : 0;
- length = count;
- out:
- kfree(page);
-diff --git a/security/yama/Kconfig b/security/yama/Kconfig
-index 96b27405558a..485c1b85c325 100644
---- a/security/yama/Kconfig
-+++ b/security/yama/Kconfig
-@@ -1,7 +1,7 @@
- config SECURITY_YAMA
- bool "Yama support"
- depends on SECURITY
-- default n
-+ default y
- help
- This selects Yama, which extends DAC support with additional
- system-wide security settings beyond regular Linux discretionary
-diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
-index 1218ea663c6d..700f28148b4e 100644
---- a/virt/kvm/kvm_main.c
-+++ b/virt/kvm/kvm_main.c
-@@ -626,6 +626,10 @@ static int kvm_create_vm_debugfs(struct kvm *kvm, int fd)
- struct kvm_stat_data *stat_data;
- struct kvm_stats_debugfs_item *p;
-
-+#ifdef CONFIG_HARDENED_SYSFS_RESTRICT
-+ return 0;
-+#endif
-+
- if (!debugfs_initialized())
- return 0;
-