diff options
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.patch | 3846 |
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; - |