summaryrefslogtreecommitdiff
path: root/sys-kernel/cairn-sources/files/5.10.9
diff options
context:
space:
mode:
Diffstat (limited to 'sys-kernel/cairn-sources/files/5.10.9')
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/gentoo-patches/0000_README112
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/gentoo-patches/1500_XATTR_USER_PREFIX.patch67
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/gentoo-patches/1510_fs-enable-link-security-restrictions-by-default.patch20
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/gentoo-patches/2000_BT-Check-key-sizes-only-if-Secure-Simple-Pairing-enabled.patch37
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/gentoo-patches/2900_tmp513-Fix-build-issue-by-selecting-CONFIG_REG.patch30
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/gentoo-patches/2920_sign-file-patch-for-libressl.patch16
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/gentoo-patches/4567_distro-Gentoo-Kconfig.patch169
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/gentoo-patches/5000_shiftfs-ubuntu-20.04.patch2203
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0001-make-DEFAULT_MMAP_MIN_ADDR-match-LSM_MMAP_MIN_ADDR.patch27
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0002-enable-HARDENED_USERCOPY-by-default.patch25
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0003-disable-HARDENED_USERCOPY_FALLBACK-by-default.patch24
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0004-enable-SECURITY_DMESG_RESTRICT-by-default.patch26
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0005-set-kptr_restrict-2-by-default.patch26
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0006-enable-DEBUG_LIST-by-default.patch25
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0007-enable-BUG_ON_DATA_CORRUPTION-by-default.patch25
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0008-enable-ARM64_SW_TTBR0_PAN-by-default.patch24
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0009-arm64-enable-RANDOMIZE_BASE-by-default.patch24
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0010-enable-SLAB_FREELIST_RANDOM-by-default.patch25
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0011-enable-SLAB_FREELIST_HARDENED-by-default.patch24
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0012-disable-SLAB_MERGE_DEFAULT-by-default.patch24
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0013-enable-FORTIFY_SOURCE-by-default.patch25
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0014-enable-PANIC_ON_OOPS-by-default.patch34
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0015-stop-hiding-SLUB_DEBUG-behind-EXPERT.patch26
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0016-stop-hiding-X86_16BIT-behind-EXPERT.patch25
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0017-disable-X86_16BIT-by-default.patch25
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0018-stop-hiding-MODIFY_LDT_SYSCALL-behind-EXPERT.patch25
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0019-disable-MODIFY_LDT_SYSCALL-by-default.patch26
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0020-set-LEGACY_VSYSCALL_NONE-by-default.patch25
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0021-stop-hiding-AIO-behind-EXPERT.patch25
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0022-disable-AIO-by-default.patch24
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0023-remove-SYSVIPC-from-arm64-x86_64-defconfigs.patch32
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0024-disable-DEVPORT-by-default.patch24
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0025-disable-PROC_VMCORE-by-default.patch24
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0026-disable-NFS_DEBUG-by-default.patch24
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0027-enable-DEBUG_WX-by-default.patch25
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0028-disable-LEGACY_PTYS-by-default.patch24
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0029-disable-DEVMEM-by-default.patch24
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0030-enable-IO_STRICT_DEVMEM-by-default.patch24
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0031-disable-COMPAT_BRK-by-default.patch24
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0032-use-maximum-supported-mmap-rnd-entropy-by-default.patch35
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0033-enable-protected_-symlinks-hardlinks-by-default.patch27
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0034-enable-SECURITY-by-default.patch24
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0035-enable-SECURITY_YAMA-by-default.patch25
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0036-enable-SECURITY_NETWORK-by-default.patch24
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0037-enable-AUDIT-by-default.patch24
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0038-enable-SECURITY_SELINUX-by-default.patch25
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0039-enable-SYN_COOKIES-by-default.patch24
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0040-enable-INIT_ON_ALLOC_DEFAULT_ON-by-default.patch24
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0041-enable-INIT_ON_FREE_DEFAULT_ON-by-default.patch24
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0042-kconfig-select-DEBUG_FS_ALLOW_NONE-by-default-if-DEB.patch27
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0043-stop-hiding-SYSFS_SYSCALL-behind-EXPERT.patch25
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0044-disable-SYSFS_SYSCALL-by-default.patch31
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0045-stop-hiding-UID16-behind-EXPERT.patch25
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0046-disable-UID16-by-default.patch24
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0047-add-__read_only-for-non-init-related-usage.patch25
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0048-make-sysctl-constants-read-only.patch108
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0049-mark-kernel_set_to_readonly-as-__ro_after_init.patch67
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0050-Revert-mark-kernel_set_to_readonly-as-__ro_after_ini.patch70
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0051-mark-slub-runtime-configuration-as-__ro_after_init.patch57
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0052-add-__ro_after_init-to-slab_nomerge-and-slab_state.patch38
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0053-mark-kmem_cache-as-__ro_after_init.patch25
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0054-mark-__supported_pte_mask-as-__ro_after_init.patch49
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0055-mark-kobj_ns_type_register-as-only-used-for-init.patch45
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0056-mark-open_softirq-as-only-used-for-init.patch39
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0057-remove-unused-softirq_action-callback-parameter.patch208
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0058-mark-softirq_vec-as-__ro_after_init.patch28
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0059-mm-slab-trigger-BUG-if-requested-object-is-not-a-sla.patch34
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0060-bug-on-kmem_cache_free-with-the-wrong-cache.patch40
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0061-bug-on-PageSlab-PageCompound-in-ksize.patch31
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0062-mm-add-support-for-verifying-page-sanitization.patch70
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0063-slub-Extend-init_on_free-to-slab-caches-with-constru.patch75
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0064-slub-Add-support-for-verifying-slab-sanitization.patch116
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0065-slub-add-multi-purpose-random-canaries.patch264
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0066-security-perf-Allow-further-restriction-of-perf_even.patch122
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0067-enable-SECURITY_PERF_EVENTS_RESTRICT-by-default.patch25
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0068-add-sysctl-to-disallow-unprivileged-CLONE_NEWUSER-by.patch124
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0069-add-CONFIG-for-unprivileged_userns_clone.patch66
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0070-add-kmalloc-krealloc-alloc_size-attributes.patch65
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0071-add-vmalloc-alloc_size-attributes.patch47
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0072-add-kvmalloc-alloc_size-attribute.patch26
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0073-add-percpu-alloc_size-attributes.patch37
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0074-add-alloc_pages_exact-alloc_size-attributes.patch30
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0075-Add-the-extra_latent_entropy-kernel-parameter.patch104
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0076-ata-avoid-null-pointer-dereference-on-bug.patch37
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0077-sanity-check-for-negative-length-in-nla_memcpy.patch28
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0078-add-page-destructor-sanity-check.patch71
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0079-PaX-shadow-cr4-sanity-check-essentially-a-revert.patch52
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0080-add-writable-function-pointer-detection.patch98
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0081-support-overriding-early-audit-kernel-cmdline.patch26
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0082-FORTIFY_SOURCE-intra-object-overflow-checking.patch135
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0083-Revert-mm-revert-x86_64-and-arm64-ELF_ET_DYN_BASE-ba.patch54
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0084-x86_64-move-vdso-to-mmap-region-from-stack-region.patch118
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0085-x86-determine-stack-entropy-based-on-mmap-entropy.patch60
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0086-arm64-determine-stack-entropy-based-on-mmap-entropy.patch51
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0087-randomize-lower-bits-of-the-argument-block.patch47
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0088-x86_64-match-arm64-brk-randomization-entropy.patch38
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0089-support-randomizing-the-lower-bits-of-brk.patch42
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0090-mm-randomize-lower-bits-of-brk.patch31
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0091-x86-randomize-lower-bits-of-brk.patch31
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0092-mm-guarantee-brk-gap-is-at-least-one-page.patch31
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0093-x86-guarantee-brk-gap-is-at-least-one-page.patch31
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0094-x86_64-bound-mmap-between-legacy-modern-bases.patch37
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0095-restrict-device-timing-side-channels.patch174
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0096-sysctl-expose-proc_dointvec_minmax_sysadmin-as-API-f.patch95
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0097-usb-add-toggle-for-disabling-newly-added-USB-devices.patch92
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0098-usb-implement-dedicated-subsystem-sysctl-tables.patch195
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0099-hard-wire-legacy-checkreqprot-option-to-0.patch133
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0100-security-tty-Add-owner-user-namespace-to-tty_struct.patch70
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0101-security-tty-make-TIOCSTI-ioctl-require-CAP_SYS_ADMI.patch197
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0102-enable-SECURITY_TIOCSTI_RESTRICT-by-default.patch26
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0103-disable-unprivileged-eBPF-access-by-default.patch25
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0104-enable-BPF-JIT-hardening-by-default-if-available.patch25
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0105-enable-protected_-fifos-regular-by-default.patch27
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0106-modpost-Add-CONFIG_DEBUG_WRITABLE_FUNCTION_POINTERS_.patch129
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0107-mm-Fix-extra_latent_entropy.patch103
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0108-add-CONFIG-for-unprivileged_userfaultfd.patch68
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0109-slub-Extend-init_on_alloc-to-slab-caches-with-constr.patch81
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0110-net-tcp-add-option-to-disable-TCP-simultaneous-conne.patch151
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0111-dccp-ccid-move-timers-to-struct-dccp_sock.patch238
-rw-r--r--sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0112-Revert-dccp-don-t-free-ccid2_hc_tx_sock-struct-in-dc.patch40
120 files changed, 8748 insertions, 0 deletions
diff --git a/sys-kernel/cairn-sources/files/5.10.9/gentoo-patches/0000_README b/sys-kernel/cairn-sources/files/5.10.9/gentoo-patches/0000_README
new file mode 100644
index 000000000000..e4c8baca988b
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/gentoo-patches/0000_README
@@ -0,0 +1,112 @@
+README
+--------------------------------------------------------------------------
+This patchset is to be the series of patches for gentoo-sources.
+It is designed for cross-compatibility, fixes and stability, with performance
+and additional features/driver support being a second.
+
+Unless otherwise stated and marked as such, this kernel should be suitable for
+all environments.
+
+
+Patchset Numbering Scheme
+--------------------------------------------------------------------------
+
+FIXES
+1000-1400 linux-stable
+1400-1500 linux-stable queue
+1500-1700 security
+1700-1800 architecture-related
+1800-1900 mm/scheduling/misc
+1900-2000 filesystems
+2000-2100 networking core
+2100-2200 storage core
+2200-2300 power management (ACPI, APM)
+2300-2400 bus (USB, IEEE1394, PCI, PCMCIA, ...)
+2400-2500 network drivers
+2500-2600 storage drivers
+2600-2700 input
+2700-2900 media (graphics, sound, tv)
+2900-3000 other
+3000-4000 reserved
+
+FEATURES
+4000-4100 network
+4100-4200 storage
+4200-4300 graphics
+4300-4400 filesystem
+4400-4500 security enhancement
+4500-4600 other
+
+EXPERIMENTAL
+5000-5100 experimental patches (BFQ, ...)
+
+Individual Patch Descriptions:
+--------------------------------------------------------------------------
+
+Patch: 1000_linux-5.10.1.patch
+From: http://www.kernel.org
+Desc: Linux 5.10.1
+
+Patch: 1001_linux-5.10.2.patch
+From: http://www.kernel.org
+Desc: Linux 5.10.2
+
+Patch: 1002_linux-5.10.3.patch
+From: http://www.kernel.org
+Desc: Linux 5.10.3
+
+Patch: 1003_linux-5.10.4.patch
+From: http://www.kernel.org
+Desc: Linux 5.10.4
+
+Patch: 1004_linux-5.10.5.patch
+From: http://www.kernel.org
+Desc: Linux 5.10.5
+
+Patch: 1005_linux-5.10.6.patch
+From: http://www.kernel.org
+Desc: Linux 5.10.6
+
+Patch: 1006_linux-5.10.7.patch
+From: http://www.kernel.org
+Desc: Linux 5.10.7
+
+Patch: 1007_linux-5.10.8.patch
+From: http://www.kernel.org
+Desc: Linux 5.10.8
+
+Patch: 1008_linux-5.10.9.patch
+From: http://www.kernel.org
+Desc: Linux 5.10.9
+
+Patch: 1500_XATTR_USER_PREFIX.patch
+From: https://bugs.gentoo.org/show_bug.cgi?id=470644
+Desc: Support for namespace user.pax.* on tmpfs.
+
+Patch: 1510_fs-enable-link-security-restrictions-by-default.patch
+From: http://sources.debian.net/src/linux/3.16.7-ckt4-3/debian/patches/debian/fs-enable-link-security-restrictions-by-default.patch/
+Desc: Enable link security restrictions by default.
+
+Patch: 2000_BT-Check-key-sizes-only-if-Secure-Simple-Pairing-enabled.patch
+From: https://lore.kernel.org/linux-bluetooth/20190522070540.48895-1-marcel@holtmann.org/raw
+Desc: Bluetooth: Check key sizes only when Secure Simple Pairing is enabled. See bug #686758
+
+Patch: 2900_tmp513-Fix-build-issue-by-selecting-CONFIG_REG.patch
+From: https://bugs.gentoo.org/710790
+Desc: tmp513 requies REGMAP_I2C to build. Select it by default in Kconfig. See bug #710790. Thanks to Phil Stracchino
+
+Patch: 2920_sign-file-patch-for-libressl.patch
+From: https://bugs.gentoo.org/717166
+Desc: sign-file: full functionality with modern LibreSSL
+
+Patch: 4567_distro-Gentoo-Kconfig.patch
+From: Tom Wijsman <TomWij@gentoo.org>
+Desc: Add Gentoo Linux support config settings and defaults.
+
+Patch: 5000_shifts-ubuntu-20.04.patch
+From: https://git.launchpad.net/~ubuntu-kernel/ubuntu/+source/linux/+git/focal
+Desc: UID/GID shifting overlay filesystem for containers
+
+Patch: 5013_enable-cpu-optimizations-for-gcc10.patch
+From: https://github.com/graysky2/kernel_gcc_patch/
+Desc: Kernel patch enables gcc = v10.1+ optimizations for additional CPUs.
diff --git a/sys-kernel/cairn-sources/files/5.10.9/gentoo-patches/1500_XATTR_USER_PREFIX.patch b/sys-kernel/cairn-sources/files/5.10.9/gentoo-patches/1500_XATTR_USER_PREFIX.patch
new file mode 100644
index 000000000000..245dcc29fa56
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/gentoo-patches/1500_XATTR_USER_PREFIX.patch
@@ -0,0 +1,67 @@
+From: Anthony G. Basile <blueness@gentoo.org>
+
+This patch adds support for a restricted user-controlled namespace on
+tmpfs filesystem used to house PaX flags. The namespace must be of the
+form user.pax.* and its value cannot exceed a size of 8 bytes.
+
+This is needed even on all Gentoo systems so that XATTR_PAX flags
+are preserved for users who might build packages using portage on
+a tmpfs system with a non-hardened kernel and then switch to a
+hardened kernel with XATTR_PAX enabled.
+
+The namespace is added to any user with Extended Attribute support
+enabled for tmpfs. Users who do not enable xattrs will not have
+the XATTR_PAX flags preserved.
+
+diff --git a/include/uapi/linux/xattr.h b/include/uapi/linux/xattr.h
+index 1590c49..5eab462 100644
+--- a/include/uapi/linux/xattr.h
++++ b/include/uapi/linux/xattr.h
+@@ -73,5 +73,9 @@
+ #define XATTR_POSIX_ACL_DEFAULT "posix_acl_default"
+ #define XATTR_NAME_POSIX_ACL_DEFAULT XATTR_SYSTEM_PREFIX XATTR_POSIX_ACL_DEFAULT
+
++/* User namespace */
++#define XATTR_PAX_PREFIX XATTR_USER_PREFIX "pax."
++#define XATTR_PAX_FLAGS_SUFFIX "flags"
++#define XATTR_NAME_PAX_FLAGS XATTR_PAX_PREFIX XATTR_PAX_FLAGS_SUFFIX
+
+ #endif /* _UAPI_LINUX_XATTR_H */
+--- a/mm/shmem.c 2020-05-04 15:30:27.042035334 -0400
++++ b/mm/shmem.c 2020-05-04 15:34:57.013881725 -0400
+@@ -3238,6 +3238,14 @@ static int shmem_xattr_handler_set(const
+ struct shmem_inode_info *info = SHMEM_I(inode);
+
+ name = xattr_full_name(handler, name);
++
++ if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) {
++ if (strcmp(name, XATTR_NAME_PAX_FLAGS))
++ return -EOPNOTSUPP;
++ if (size > 8)
++ return -EINVAL;
++ }
++
+ return simple_xattr_set(&info->xattrs, name, value, size, flags, NULL);
+ }
+
+@@ -3253,6 +3261,12 @@ static const struct xattr_handler shmem_
+ .set = shmem_xattr_handler_set,
+ };
+
++static const struct xattr_handler shmem_user_xattr_handler = {
++ .prefix = XATTR_USER_PREFIX,
++ .get = shmem_xattr_handler_get,
++ .set = shmem_xattr_handler_set,
++};
++
+ static const struct xattr_handler *shmem_xattr_handlers[] = {
+ #ifdef CONFIG_TMPFS_POSIX_ACL
+ &posix_acl_access_xattr_handler,
+@@ -3260,6 +3274,7 @@ static const struct xattr_handler *shmem
+ #endif
+ &shmem_security_xattr_handler,
+ &shmem_trusted_xattr_handler,
++ &shmem_user_xattr_handler,
+ NULL
+ };
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/gentoo-patches/1510_fs-enable-link-security-restrictions-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/gentoo-patches/1510_fs-enable-link-security-restrictions-by-default.patch
new file mode 100644
index 000000000000..f0ed144fb17a
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/gentoo-patches/1510_fs-enable-link-security-restrictions-by-default.patch
@@ -0,0 +1,20 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Subject: fs: Enable link security restrictions by default
+Date: Fri, 02 Nov 2012 05:32:06 +0000
+Bug-Debian: https://bugs.debian.org/609455
+Forwarded: not-needed
+This reverts commit 561ec64ae67ef25cac8d72bb9c4bfc955edfd415
+('VFS: don't do protected {sym,hard}links by default').
+--- a/fs/namei.c 2018-09-28 07:56:07.770005006 -0400
++++ b/fs/namei.c 2018-09-28 07:56:43.370349204 -0400
+@@ -885,8 +885,8 @@ static inline void put_link(struct namei
+ path_put(&last->link);
+ }
+
+-int sysctl_protected_symlinks __read_mostly = 0;
+-int sysctl_protected_hardlinks __read_mostly = 0;
++int sysctl_protected_symlinks __read_mostly = 1;
++int sysctl_protected_hardlinks __read_mostly = 1;
+ int sysctl_protected_fifos __read_mostly;
+ int sysctl_protected_regular __read_mostly;
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/gentoo-patches/2000_BT-Check-key-sizes-only-if-Secure-Simple-Pairing-enabled.patch b/sys-kernel/cairn-sources/files/5.10.9/gentoo-patches/2000_BT-Check-key-sizes-only-if-Secure-Simple-Pairing-enabled.patch
new file mode 100644
index 000000000000..394ad48fc20c
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/gentoo-patches/2000_BT-Check-key-sizes-only-if-Secure-Simple-Pairing-enabled.patch
@@ -0,0 +1,37 @@
+The encryption is only mandatory to be enforced when both sides are using
+Secure Simple Pairing and this means the key size check makes only sense
+in that case.
+
+On legacy Bluetooth 2.0 and earlier devices like mice the encryption was
+optional and thus causing an issue if the key size check is not bound to
+using Secure Simple Pairing.
+
+Fixes: d5bb334a8e17 ("Bluetooth: Align minimum encryption key size for LE and BR/EDR connections")
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Cc: stable@vger.kernel.org
+---
+ net/bluetooth/hci_conn.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
+index 3cf0764d5793..7516cdde3373 100644
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -1272,8 +1272,13 @@ int hci_conn_check_link_mode(struct hci_conn *conn)
+ return 0;
+ }
+
+- if (hci_conn_ssp_enabled(conn) &&
+- !test_bit(HCI_CONN_ENCRYPT, &conn->flags))
++ /* If Secure Simple Pairing is not enabled, then legacy connection
++ * setup is used and no encryption or key sizes can be enforced.
++ */
++ if (!hci_conn_ssp_enabled(conn))
++ return 1;
++
++ if (!test_bit(HCI_CONN_ENCRYPT, &conn->flags))
+ return 0;
+
+ /* The minimum encryption key size needs to be enforced by the
+--
+2.20.1
diff --git a/sys-kernel/cairn-sources/files/5.10.9/gentoo-patches/2900_tmp513-Fix-build-issue-by-selecting-CONFIG_REG.patch b/sys-kernel/cairn-sources/files/5.10.9/gentoo-patches/2900_tmp513-Fix-build-issue-by-selecting-CONFIG_REG.patch
new file mode 100644
index 000000000000..433568579cab
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/gentoo-patches/2900_tmp513-Fix-build-issue-by-selecting-CONFIG_REG.patch
@@ -0,0 +1,30 @@
+From dc328d75a6f37f4ff11a81ae16b1ec88c3197640 Mon Sep 17 00:00:00 2001
+From: Mike Pagano <mpagano@gentoo.org>
+Date: Mon, 23 Mar 2020 08:20:06 -0400
+Subject: [PATCH 1/1] This driver requires REGMAP_I2C to build. Select it by
+ default in Kconfig. Reported at gentoo bugzilla:
+ https://bugs.gentoo.org/710790
+Cc: mpagano@gentoo.org
+
+Reported-by: Phil Stracchino <phils@caerllewys.net>
+
+Signed-off-by: Mike Pagano <mpagano@gentoo.org>
+---
+ drivers/hwmon/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
+index 47ac20aee06f..530b4f29ba85 100644
+--- a/drivers/hwmon/Kconfig
++++ b/drivers/hwmon/Kconfig
+@@ -1769,6 +1769,7 @@ config SENSORS_TMP421
+ config SENSORS_TMP513
+ tristate "Texas Instruments TMP513 and compatibles"
+ depends on I2C
++ select REGMAP_I2C
+ help
+ If you say yes here you get support for Texas Instruments TMP512,
+ and TMP513 temperature and power supply sensor chips.
+--
+2.24.1
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/gentoo-patches/2920_sign-file-patch-for-libressl.patch b/sys-kernel/cairn-sources/files/5.10.9/gentoo-patches/2920_sign-file-patch-for-libressl.patch
new file mode 100644
index 000000000000..e6ec017d46c8
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/gentoo-patches/2920_sign-file-patch-for-libressl.patch
@@ -0,0 +1,16 @@
+--- a/scripts/sign-file.c 2020-05-20 18:47:21.282820662 -0400
++++ b/scripts/sign-file.c 2020-05-20 18:48:37.991081899 -0400
+@@ -41,9 +41,10 @@
+ * signing with anything other than SHA1 - so we're stuck with that if such is
+ * the case.
+ */
+-#if defined(LIBRESSL_VERSION_NUMBER) || \
+- OPENSSL_VERSION_NUMBER < 0x10000000L || \
+- defined(OPENSSL_NO_CMS)
++#if defined(OPENSSL_NO_CMS) || \
++ ( defined(LIBRESSL_VERSION_NUMBER) \
++ && (LIBRESSL_VERSION_NUMBER < 0x3010000fL) ) || \
++ OPENSSL_VERSION_NUMBER < 0x10000000L
+ #define USE_PKCS7
+ #endif
+ #ifndef USE_PKCS7
diff --git a/sys-kernel/cairn-sources/files/5.10.9/gentoo-patches/4567_distro-Gentoo-Kconfig.patch b/sys-kernel/cairn-sources/files/5.10.9/gentoo-patches/4567_distro-Gentoo-Kconfig.patch
new file mode 100644
index 000000000000..e754a3e6e459
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/gentoo-patches/4567_distro-Gentoo-Kconfig.patch
@@ -0,0 +1,169 @@
+--- a/Kconfig 2020-04-15 11:05:30.202413863 -0400
++++ b/Kconfig 2020-04-15 10:37:45.683952949 -0400
+@@ -32,3 +32,5 @@ source "lib/Kconfig"
+ source "lib/Kconfig.debug"
+
+ source "Documentation/Kconfig"
++
++source "distro/Kconfig"
+--- /dev/null 2020-09-24 03:06:47.590000000 -0400
++++ b/distro/Kconfig 2020-09-24 11:31:29.403150624 -0400
+@@ -0,0 +1,158 @@
++menu "Gentoo Linux"
++
++config GENTOO_LINUX
++ bool "Gentoo Linux support"
++
++ default y
++
++ help
++ In order to boot Gentoo Linux a minimal set of config settings needs to
++ be enabled in the kernel; to avoid the users from having to enable them
++ manually as part of a Gentoo Linux installation or a new clean config,
++ we enable these config settings by default for convenience.
++
++ See the settings that become available for more details and fine-tuning.
++
++config GENTOO_LINUX_UDEV
++ bool "Linux dynamic and persistent device naming (userspace devfs) support"
++
++ depends on GENTOO_LINUX
++ default y if GENTOO_LINUX
++
++ select DEVTMPFS
++ select TMPFS
++ select UNIX
++
++ select MMU
++ select SHMEM
++
++ help
++ In order to boot Gentoo Linux a minimal set of config settings needs to
++ be enabled in the kernel; to avoid the users from having to enable them
++ manually as part of a Gentoo Linux installation or a new clean config,
++ we enable these config settings by default for convenience.
++
++ Currently this only selects TMPFS, DEVTMPFS and their dependencies.
++ TMPFS is enabled to maintain a tmpfs file system at /dev/shm, /run and
++ /sys/fs/cgroup; DEVTMPFS to maintain a devtmpfs file system at /dev.
++
++ Some of these are critical files that need to be available early in the
++ boot process; if not available, it causes sysfs and udev to malfunction.
++
++ To ensure Gentoo Linux boots, it is best to leave this setting enabled;
++ if you run a custom setup, you could consider whether to disable this.
++
++config GENTOO_LINUX_PORTAGE
++ bool "Select options required by Portage features"
++
++ depends on GENTOO_LINUX
++ default y if GENTOO_LINUX
++
++ select CGROUPS
++ select NAMESPACES
++ select IPC_NS
++ select NET_NS
++ select PID_NS
++ select SYSVIPC
++ select UTS_NS
++
++ help
++ This enables options required by various Portage FEATURES.
++ Currently this selects:
++
++ CGROUPS (required for FEATURES=cgroup)
++ IPC_NS (required for FEATURES=ipc-sandbox)
++ NET_NS (required for FEATURES=network-sandbox)
++ PID_NS (required for FEATURES=pid-sandbox)
++ SYSVIPC (required by IPC_NS)
++
++
++ It is highly recommended that you leave this enabled as these FEATURES
++ are, or will soon be, enabled by default.
++
++menu "Support for init systems, system and service managers"
++ visible if GENTOO_LINUX
++
++config GENTOO_LINUX_INIT_SCRIPT
++ bool "OpenRC, runit and other script based systems and managers"
++
++ default y if GENTOO_LINUX
++
++ depends on GENTOO_LINUX
++
++ select BINFMT_SCRIPT
++ select CGROUPS
++ select EPOLL
++ select FILE_LOCKING
++ select INOTIFY_USER
++ select SIGNALFD
++ select TIMERFD
++
++ help
++ The init system is the first thing that loads after the kernel booted.
++
++ These config settings allow you to select which init systems to support;
++ instead of having to select all the individual settings all over the
++ place, these settings allows you to select all the settings at once.
++
++ This particular setting enables all the known requirements for OpenRC,
++ runit and similar script based systems and managers.
++
++ If you are unsure about this, it is best to leave this setting enabled.
++
++config GENTOO_LINUX_INIT_SYSTEMD
++ bool "systemd"
++
++ default n
++
++ depends on GENTOO_LINUX && GENTOO_LINUX_UDEV
++
++ select AUTOFS4_FS
++ select BLK_DEV_BSG
++ select BPF_SYSCALL
++ select CGROUP_BPF
++ select CGROUPS
++ select CHECKPOINT_RESTORE
++ select CRYPTO_HMAC
++ select CRYPTO_SHA256
++ select CRYPTO_USER_API_HASH
++ select DEVPTS_MULTIPLE_INSTANCES
++ select DMIID if X86_32 || X86_64 || X86
++ select EPOLL
++ select FANOTIFY
++ select FHANDLE
++ select FILE_LOCKING
++ select INOTIFY_USER
++ select IPV6
++ select NET
++ select NET_NS
++ select PROC_FS
++ select SECCOMP
++ select SECCOMP_FILTER
++ select SIGNALFD
++ select SYSFS
++ select TIMERFD
++ select TMPFS_POSIX_ACL
++ select TMPFS_XATTR
++ select USER_NS
++
++ select ANON_INODES
++ select BLOCK
++ select EVENTFD
++ select FSNOTIFY
++ select INET
++ select NLATTR
++
++ help
++ The init system is the first thing that loads after the kernel booted.
++
++ These config settings allow you to select which init systems to support;
++ instead of having to select all the individual settings all over the
++ place, these settings allows you to select all the settings at once.
++
++ This particular setting enables all the known requirements for systemd;
++ it also enables suggested optional settings, as the package suggests to.
++
++endmenu
++
++endmenu
diff --git a/sys-kernel/cairn-sources/files/5.10.9/gentoo-patches/5000_shiftfs-ubuntu-20.04.patch b/sys-kernel/cairn-sources/files/5.10.9/gentoo-patches/5000_shiftfs-ubuntu-20.04.patch
new file mode 100644
index 000000000000..665fc660b0de
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/gentoo-patches/5000_shiftfs-ubuntu-20.04.patch
@@ -0,0 +1,2203 @@
+--- /dev/null 2021-01-08 13:33:13.190303432 -0500
++++ b/fs/shiftfs.c 2021-01-08 19:02:40.000000000 -0500
+@@ -0,0 +1,2157 @@
++#include <linux/btrfs.h>
++#include <linux/capability.h>
++#include <linux/cred.h>
++#include <linux/mount.h>
++#include <linux/fdtable.h>
++#include <linux/file.h>
++#include <linux/fs.h>
++#include <linux/namei.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/magic.h>
++#include <linux/parser.h>
++#include <linux/security.h>
++#include <linux/seq_file.h>
++#include <linux/statfs.h>
++#include <linux/slab.h>
++#include <linux/user_namespace.h>
++#include <linux/uidgid.h>
++#include <linux/xattr.h>
++#include <linux/posix_acl.h>
++#include <linux/posix_acl_xattr.h>
++#include <linux/uio.h>
++#include <linux/fiemap.h>
++
++struct shiftfs_super_info {
++ struct vfsmount *mnt;
++ struct user_namespace *userns;
++ /* creds of process who created the super block */
++ const struct cred *creator_cred;
++ bool mark;
++ unsigned int passthrough;
++ unsigned int passthrough_mark;
++};
++
++static void shiftfs_fill_inode(struct inode *inode, unsigned long ino,
++ umode_t mode, dev_t dev, struct dentry *dentry);
++
++#define SHIFTFS_PASSTHROUGH_NONE 0
++#define SHIFTFS_PASSTHROUGH_STAT 1
++#define SHIFTFS_PASSTHROUGH_IOCTL 2
++#define SHIFTFS_PASSTHROUGH_ALL \
++ (SHIFTFS_PASSTHROUGH_STAT | SHIFTFS_PASSTHROUGH_IOCTL)
++
++static inline bool shiftfs_passthrough_ioctls(struct shiftfs_super_info *info)
++{
++ if (!(info->passthrough & SHIFTFS_PASSTHROUGH_IOCTL))
++ return false;
++
++ return true;
++}
++
++static inline bool shiftfs_passthrough_statfs(struct shiftfs_super_info *info)
++{
++ if (!(info->passthrough & SHIFTFS_PASSTHROUGH_STAT))
++ return false;
++
++ return true;
++}
++
++enum {
++ OPT_MARK,
++ OPT_PASSTHROUGH,
++ OPT_LAST,
++};
++
++/* global filesystem options */
++static const match_table_t tokens = {
++ { OPT_MARK, "mark" },
++ { OPT_PASSTHROUGH, "passthrough=%u" },
++ { OPT_LAST, NULL }
++};
++
++static const struct cred *shiftfs_override_creds(const struct super_block *sb)
++{
++ struct shiftfs_super_info *sbinfo = sb->s_fs_info;
++
++ return override_creds(sbinfo->creator_cred);
++}
++
++static inline void shiftfs_revert_object_creds(const struct cred *oldcred,
++ struct cred *newcred)
++{
++ revert_creds(oldcred);
++ put_cred(newcred);
++}
++
++static kuid_t shift_kuid(struct user_namespace *from, struct user_namespace *to,
++ kuid_t kuid)
++{
++ uid_t uid = from_kuid(from, kuid);
++ return make_kuid(to, uid);
++}
++
++static kgid_t shift_kgid(struct user_namespace *from, struct user_namespace *to,
++ kgid_t kgid)
++{
++ gid_t gid = from_kgid(from, kgid);
++ return make_kgid(to, gid);
++}
++
++static int shiftfs_override_object_creds(const struct super_block *sb,
++ const struct cred **oldcred,
++ struct cred **newcred,
++ struct dentry *dentry, umode_t mode,
++ bool hardlink)
++{
++ struct shiftfs_super_info *sbinfo = sb->s_fs_info;
++ kuid_t fsuid = current_fsuid();
++ kgid_t fsgid = current_fsgid();
++
++ *oldcred = shiftfs_override_creds(sb);
++
++ *newcred = prepare_creds();
++ if (!*newcred) {
++ revert_creds(*oldcred);
++ return -ENOMEM;
++ }
++
++ (*newcred)->fsuid = shift_kuid(sb->s_user_ns, sbinfo->userns, fsuid);
++ (*newcred)->fsgid = shift_kgid(sb->s_user_ns, sbinfo->userns, fsgid);
++
++ if (!hardlink) {
++ int err = security_dentry_create_files_as(dentry, mode,
++ &dentry->d_name,
++ *oldcred, *newcred);
++ if (err) {
++ shiftfs_revert_object_creds(*oldcred, *newcred);
++ return err;
++ }
++ }
++
++ put_cred(override_creds(*newcred));
++ return 0;
++}
++
++static void shiftfs_copyattr(struct inode *from, struct inode *to)
++{
++ struct user_namespace *from_ns = from->i_sb->s_user_ns;
++ struct user_namespace *to_ns = to->i_sb->s_user_ns;
++
++ to->i_uid = shift_kuid(from_ns, to_ns, from->i_uid);
++ to->i_gid = shift_kgid(from_ns, to_ns, from->i_gid);
++ to->i_mode = from->i_mode;
++ to->i_atime = from->i_atime;
++ to->i_mtime = from->i_mtime;
++ to->i_ctime = from->i_ctime;
++ i_size_write(to, i_size_read(from));
++}
++
++static void shiftfs_copyflags(struct inode *from, struct inode *to)
++{
++ unsigned int mask = S_SYNC | S_IMMUTABLE | S_APPEND | S_NOATIME;
++
++ inode_set_flags(to, from->i_flags & mask, mask);
++}
++
++static void shiftfs_file_accessed(struct file *file)
++{
++ struct inode *upperi, *loweri;
++
++ if (file->f_flags & O_NOATIME)
++ return;
++
++ upperi = file_inode(file);
++ loweri = upperi->i_private;
++
++ if (!loweri)
++ return;
++
++ upperi->i_mtime = loweri->i_mtime;
++ upperi->i_ctime = loweri->i_ctime;
++
++ touch_atime(&file->f_path);
++}
++
++static int shiftfs_parse_mount_options(struct shiftfs_super_info *sbinfo,
++ char *options)
++{
++ char *p;
++ substring_t args[MAX_OPT_ARGS];
++
++ sbinfo->mark = false;
++ sbinfo->passthrough = 0;
++
++ while ((p = strsep(&options, ",")) != NULL) {
++ int err, intarg, token;
++
++ if (!*p)
++ continue;
++
++ token = match_token(p, tokens, args);
++ switch (token) {
++ case OPT_MARK:
++ sbinfo->mark = true;
++ break;
++ case OPT_PASSTHROUGH:
++ err = match_int(&args[0], &intarg);
++ if (err)
++ return err;
++
++ if (intarg & ~SHIFTFS_PASSTHROUGH_ALL)
++ return -EINVAL;
++
++ sbinfo->passthrough = intarg;
++ break;
++ default:
++ return -EINVAL;
++ }
++ }
++
++ return 0;
++}
++
++static void shiftfs_d_release(struct dentry *dentry)
++{
++ struct dentry *lowerd = dentry->d_fsdata;
++
++ if (lowerd)
++ dput(lowerd);
++}
++
++static struct dentry *shiftfs_d_real(struct dentry *dentry,
++ const struct inode *inode)
++{
++ struct dentry *lowerd = dentry->d_fsdata;
++
++ if (inode && d_inode(dentry) == inode)
++ return dentry;
++
++ lowerd = d_real(lowerd, inode);
++ if (lowerd && (!inode || inode == d_inode(lowerd)))
++ return lowerd;
++
++ WARN(1, "shiftfs_d_real(%pd4, %s:%lu): real dentry not found\n", dentry,
++ inode ? inode->i_sb->s_id : "NULL", inode ? inode->i_ino : 0);
++ return dentry;
++}
++
++static int shiftfs_d_weak_revalidate(struct dentry *dentry, unsigned int flags)
++{
++ int err = 1;
++ struct dentry *lowerd = dentry->d_fsdata;
++
++ if (d_is_negative(lowerd) != d_is_negative(dentry))
++ return 0;
++
++ if ((lowerd->d_flags & DCACHE_OP_WEAK_REVALIDATE))
++ err = lowerd->d_op->d_weak_revalidate(lowerd, flags);
++
++ if (d_really_is_positive(dentry)) {
++ struct inode *inode = d_inode(dentry);
++ struct inode *loweri = d_inode(lowerd);
++
++ shiftfs_copyattr(loweri, inode);
++ }
++
++ return err;
++}
++
++static int shiftfs_d_revalidate(struct dentry *dentry, unsigned int flags)
++{
++ int err = 1;
++ struct dentry *lowerd = dentry->d_fsdata;
++
++ if (d_unhashed(lowerd) ||
++ ((d_is_negative(lowerd) != d_is_negative(dentry))))
++ return 0;
++
++ if (flags & LOOKUP_RCU)
++ return -ECHILD;
++
++ if ((lowerd->d_flags & DCACHE_OP_REVALIDATE))
++ err = lowerd->d_op->d_revalidate(lowerd, flags);
++
++ if (d_really_is_positive(dentry)) {
++ struct inode *inode = d_inode(dentry);
++ struct inode *loweri = d_inode(lowerd);
++
++ shiftfs_copyattr(loweri, inode);
++ }
++
++ return err;
++}
++
++static const struct dentry_operations shiftfs_dentry_ops = {
++ .d_release = shiftfs_d_release,
++ .d_real = shiftfs_d_real,
++ .d_revalidate = shiftfs_d_revalidate,
++ .d_weak_revalidate = shiftfs_d_weak_revalidate,
++};
++
++static const char *shiftfs_get_link(struct dentry *dentry, struct inode *inode,
++ struct delayed_call *done)
++{
++ const char *p;
++ const struct cred *oldcred;
++ struct dentry *lowerd;
++
++ /* RCU lookup not supported */
++ if (!dentry)
++ return ERR_PTR(-ECHILD);
++
++ lowerd = dentry->d_fsdata;
++ oldcred = shiftfs_override_creds(dentry->d_sb);
++ p = vfs_get_link(lowerd, done);
++ revert_creds(oldcred);
++
++ return p;
++}
++
++static int shiftfs_setxattr(struct dentry *dentry, struct inode *inode,
++ const char *name, const void *value,
++ size_t size, int flags)
++{
++ struct dentry *lowerd = dentry->d_fsdata;
++ int err;
++ const struct cred *oldcred;
++
++ oldcred = shiftfs_override_creds(dentry->d_sb);
++ err = vfs_setxattr(lowerd, name, value, size, flags);
++ revert_creds(oldcred);
++
++ shiftfs_copyattr(lowerd->d_inode, inode);
++
++ return err;
++}
++
++static int shiftfs_xattr_get(const struct xattr_handler *handler,
++ struct dentry *dentry, struct inode *inode,
++ const char *name, void *value, size_t size)
++{
++ struct dentry *lowerd = dentry->d_fsdata;
++ int err;
++ const struct cred *oldcred;
++
++ oldcred = shiftfs_override_creds(dentry->d_sb);
++ err = vfs_getxattr(lowerd, name, value, size);
++ revert_creds(oldcred);
++
++ return err;
++}
++
++static ssize_t shiftfs_listxattr(struct dentry *dentry, char *list,
++ size_t size)
++{
++ struct dentry *lowerd = dentry->d_fsdata;
++ int err;
++ const struct cred *oldcred;
++
++ oldcred = shiftfs_override_creds(dentry->d_sb);
++ err = vfs_listxattr(lowerd, list, size);
++ revert_creds(oldcred);
++
++ return err;
++}
++
++static int shiftfs_removexattr(struct dentry *dentry, const char *name)
++{
++ struct dentry *lowerd = dentry->d_fsdata;
++ int err;
++ const struct cred *oldcred;
++
++ oldcred = shiftfs_override_creds(dentry->d_sb);
++ err = vfs_removexattr(lowerd, name);
++ revert_creds(oldcred);
++
++ /* update c/mtime */
++ shiftfs_copyattr(lowerd->d_inode, d_inode(dentry));
++
++ return err;
++}
++
++static int shiftfs_xattr_set(const struct xattr_handler *handler,
++ struct dentry *dentry, struct inode *inode,
++ const char *name, const void *value, size_t size,
++ int flags)
++{
++ if (!value)
++ return shiftfs_removexattr(dentry, name);
++ return shiftfs_setxattr(dentry, inode, name, value, size, flags);
++}
++
++static int shiftfs_inode_test(struct inode *inode, void *data)
++{
++ return inode->i_private == data;
++}
++
++static int shiftfs_inode_set(struct inode *inode, void *data)
++{
++ inode->i_private = data;
++ return 0;
++}
++
++static int shiftfs_create_object(struct inode *diri, struct dentry *dentry,
++ umode_t mode, const char *symlink,
++ struct dentry *hardlink, bool excl)
++{
++ int err;
++ const struct cred *oldcred;
++ struct cred *newcred;
++ void *loweri_iop_ptr = NULL;
++ umode_t modei = mode;
++ struct super_block *dir_sb = diri->i_sb;
++ struct dentry *lowerd_new = dentry->d_fsdata;
++ struct inode *inode = NULL, *loweri_dir = diri->i_private;
++ const struct inode_operations *loweri_dir_iop = loweri_dir->i_op;
++ struct dentry *lowerd_link = NULL;
++
++ if (hardlink) {
++ loweri_iop_ptr = loweri_dir_iop->link;
++ } else {
++ switch (mode & S_IFMT) {
++ case S_IFDIR:
++ loweri_iop_ptr = loweri_dir_iop->mkdir;
++ break;
++ case S_IFREG:
++ loweri_iop_ptr = loweri_dir_iop->create;
++ break;
++ case S_IFLNK:
++ loweri_iop_ptr = loweri_dir_iop->symlink;
++ break;
++ case S_IFSOCK:
++ /* fall through */
++ case S_IFIFO:
++ loweri_iop_ptr = loweri_dir_iop->mknod;
++ break;
++ }
++ }
++ if (!loweri_iop_ptr) {
++ err = -EINVAL;
++ goto out_iput;
++ }
++
++ inode_lock_nested(loweri_dir, I_MUTEX_PARENT);
++
++ if (!hardlink) {
++ inode = new_inode(dir_sb);
++ if (!inode) {
++ err = -ENOMEM;
++ goto out_iput;
++ }
++
++ /*
++ * new_inode() will have added the new inode to the super
++ * block's list of inodes. Further below we will call
++ * inode_insert5() Which would perform the same operation again
++ * thereby corrupting the list. To avoid this raise I_CREATING
++ * in i_state which will cause inode_insert5() to skip this
++ * step. I_CREATING will be cleared by d_instantiate_new()
++ * below.
++ */
++ spin_lock(&inode->i_lock);
++ inode->i_state |= I_CREATING;
++ spin_unlock(&inode->i_lock);
++
++ inode_init_owner(inode, diri, mode);
++ modei = inode->i_mode;
++ }
++
++ err = shiftfs_override_object_creds(dentry->d_sb, &oldcred, &newcred,
++ dentry, modei, hardlink != NULL);
++ if (err)
++ goto out_iput;
++
++ if (hardlink) {
++ lowerd_link = hardlink->d_fsdata;
++ err = vfs_link(lowerd_link, loweri_dir, lowerd_new, NULL);
++ } else {
++ switch (modei & S_IFMT) {
++ case S_IFDIR:
++ err = vfs_mkdir(loweri_dir, lowerd_new, modei);
++ break;
++ case S_IFREG:
++ err = vfs_create(loweri_dir, lowerd_new, modei, excl);
++ break;
++ case S_IFLNK:
++ err = vfs_symlink(loweri_dir, lowerd_new, symlink);
++ break;
++ case S_IFSOCK:
++ /* fall through */
++ case S_IFIFO:
++ err = vfs_mknod(loweri_dir, lowerd_new, modei, 0);
++ break;
++ default:
++ err = -EINVAL;
++ break;
++ }
++ }
++
++ shiftfs_revert_object_creds(oldcred, newcred);
++
++ if (!err && WARN_ON(!lowerd_new->d_inode))
++ err = -EIO;
++ if (err)
++ goto out_iput;
++
++ if (hardlink) {
++ inode = d_inode(hardlink);
++ ihold(inode);
++
++ /* copy up times from lower inode */
++ shiftfs_copyattr(d_inode(lowerd_link), inode);
++ set_nlink(d_inode(hardlink), d_inode(lowerd_link)->i_nlink);
++ d_instantiate(dentry, inode);
++ } else {
++ struct inode *inode_tmp;
++ struct inode *loweri_new = d_inode(lowerd_new);
++
++ inode_tmp = inode_insert5(inode, (unsigned long)loweri_new,
++ shiftfs_inode_test, shiftfs_inode_set,
++ loweri_new);
++ if (unlikely(inode_tmp != inode)) {
++ pr_err_ratelimited("shiftfs: newly created inode found in cache\n");
++ iput(inode_tmp);
++ err = -EINVAL;
++ goto out_iput;
++ }
++
++ ihold(loweri_new);
++ shiftfs_fill_inode(inode, loweri_new->i_ino, loweri_new->i_mode,
++ 0, lowerd_new);
++ d_instantiate_new(dentry, inode);
++ }
++
++ shiftfs_copyattr(loweri_dir, diri);
++ if (loweri_iop_ptr == loweri_dir_iop->mkdir)
++ set_nlink(diri, loweri_dir->i_nlink);
++
++ inode = NULL;
++
++out_iput:
++ iput(inode);
++ inode_unlock(loweri_dir);
++
++ return err;
++}
++
++static int shiftfs_create(struct inode *dir, struct dentry *dentry,
++ umode_t mode, bool excl)
++{
++ mode |= S_IFREG;
++
++ return shiftfs_create_object(dir, dentry, mode, NULL, NULL, excl);
++}
++
++static int shiftfs_mkdir(struct inode *dir, struct dentry *dentry,
++ umode_t mode)
++{
++ mode |= S_IFDIR;
++
++ return shiftfs_create_object(dir, dentry, mode, NULL, NULL, false);
++}
++
++static int shiftfs_link(struct dentry *hardlink, struct inode *dir,
++ struct dentry *dentry)
++{
++ return shiftfs_create_object(dir, dentry, 0, NULL, hardlink, false);
++}
++
++static int shiftfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
++ dev_t rdev)
++{
++ if (!S_ISFIFO(mode) && !S_ISSOCK(mode))
++ return -EPERM;
++
++ return shiftfs_create_object(dir, dentry, mode, NULL, NULL, false);
++}
++
++static int shiftfs_symlink(struct inode *dir, struct dentry *dentry,
++ const char *symlink)
++{
++ return shiftfs_create_object(dir, dentry, S_IFLNK, symlink, NULL, false);
++}
++
++static int shiftfs_rm(struct inode *dir, struct dentry *dentry, bool rmdir)
++{
++ struct dentry *lowerd = dentry->d_fsdata;
++ struct inode *loweri = dir->i_private;
++ struct inode *inode = d_inode(dentry);
++ int err;
++ const struct cred *oldcred;
++
++ dget(lowerd);
++ oldcred = shiftfs_override_creds(dentry->d_sb);
++ inode_lock_nested(loweri, I_MUTEX_PARENT);
++ if (rmdir)
++ err = vfs_rmdir(loweri, lowerd);
++ else
++ err = vfs_unlink(loweri, lowerd, NULL);
++ revert_creds(oldcred);
++
++ if (!err) {
++ d_drop(dentry);
++
++ if (rmdir)
++ clear_nlink(inode);
++ else
++ drop_nlink(inode);
++ }
++ inode_unlock(loweri);
++
++ shiftfs_copyattr(loweri, dir);
++ dput(lowerd);
++
++ return err;
++}
++
++static int shiftfs_unlink(struct inode *dir, struct dentry *dentry)
++{
++ return shiftfs_rm(dir, dentry, false);
++}
++
++static int shiftfs_rmdir(struct inode *dir, struct dentry *dentry)
++{
++ return shiftfs_rm(dir, dentry, true);
++}
++
++static int shiftfs_rename(struct inode *olddir, struct dentry *old,
++ struct inode *newdir, struct dentry *new,
++ unsigned int flags)
++{
++ struct dentry *lowerd_dir_old = old->d_parent->d_fsdata,
++ *lowerd_dir_new = new->d_parent->d_fsdata,
++ *lowerd_old = old->d_fsdata, *lowerd_new = new->d_fsdata,
++ *trapd;
++ struct inode *loweri_dir_old = lowerd_dir_old->d_inode,
++ *loweri_dir_new = lowerd_dir_new->d_inode;
++ int err = -EINVAL;
++ const struct cred *oldcred;
++
++ trapd = lock_rename(lowerd_dir_new, lowerd_dir_old);
++
++ if (trapd == lowerd_old || trapd == lowerd_new)
++ goto out_unlock;
++
++ oldcred = shiftfs_override_creds(old->d_sb);
++ err = vfs_rename(loweri_dir_old, lowerd_old, loweri_dir_new, lowerd_new,
++ NULL, flags);
++ revert_creds(oldcred);
++
++ shiftfs_copyattr(loweri_dir_old, olddir);
++ shiftfs_copyattr(loweri_dir_new, newdir);
++
++out_unlock:
++ unlock_rename(lowerd_dir_new, lowerd_dir_old);
++
++ return err;
++}
++
++static struct dentry *shiftfs_lookup(struct inode *dir, struct dentry *dentry,
++ unsigned int flags)
++{
++ struct dentry *new;
++ struct inode *newi;
++ const struct cred *oldcred;
++ struct dentry *lowerd = dentry->d_parent->d_fsdata;
++ struct inode *inode = NULL, *loweri = lowerd->d_inode;
++
++ inode_lock(loweri);
++ oldcred = shiftfs_override_creds(dentry->d_sb);
++ new = lookup_one_len(dentry->d_name.name, lowerd, dentry->d_name.len);
++ revert_creds(oldcred);
++ inode_unlock(loweri);
++
++ if (IS_ERR(new))
++ return new;
++
++ dentry->d_fsdata = new;
++
++ newi = new->d_inode;
++ if (!newi)
++ goto out;
++
++ inode = iget5_locked(dentry->d_sb, (unsigned long)newi,
++ shiftfs_inode_test, shiftfs_inode_set, newi);
++ if (!inode) {
++ dput(new);
++ return ERR_PTR(-ENOMEM);
++ }
++ if (inode->i_state & I_NEW) {
++ /*
++ * inode->i_private set by shiftfs_inode_set(), but we still
++ * need to take a reference
++ */
++ ihold(newi);
++ shiftfs_fill_inode(inode, newi->i_ino, newi->i_mode, 0, new);
++ unlock_new_inode(inode);
++ }
++
++out:
++ return d_splice_alias(inode, dentry);
++}
++
++static int shiftfs_permission(struct inode *inode, int mask)
++{
++ int err;
++ const struct cred *oldcred;
++ struct inode *loweri = inode->i_private;
++
++ if (!loweri) {
++ WARN_ON(!(mask & MAY_NOT_BLOCK));
++ return -ECHILD;
++ }
++
++ err = generic_permission(inode, mask);
++ if (err)
++ return err;
++
++ oldcred = shiftfs_override_creds(inode->i_sb);
++ err = inode_permission(loweri, mask);
++ revert_creds(oldcred);
++
++ return err;
++}
++
++static int shiftfs_fiemap(struct inode *inode,
++ struct fiemap_extent_info *fieinfo, u64 start,
++ u64 len)
++{
++ int err;
++ const struct cred *oldcred;
++ struct inode *loweri = inode->i_private;
++
++ if (!loweri->i_op->fiemap)
++ return -EOPNOTSUPP;
++
++ oldcred = shiftfs_override_creds(inode->i_sb);
++ if (fieinfo->fi_flags & FIEMAP_FLAG_SYNC)
++ filemap_write_and_wait(loweri->i_mapping);
++ err = loweri->i_op->fiemap(loweri, fieinfo, start, len);
++ revert_creds(oldcred);
++
++ return err;
++}
++
++static int shiftfs_tmpfile(struct inode *dir, struct dentry *dentry,
++ umode_t mode)
++{
++ int err;
++ const struct cred *oldcred;
++ struct dentry *lowerd = dentry->d_fsdata;
++ struct inode *loweri = dir->i_private;
++
++ if (!loweri->i_op->tmpfile)
++ return -EOPNOTSUPP;
++
++ oldcred = shiftfs_override_creds(dir->i_sb);
++ err = loweri->i_op->tmpfile(loweri, lowerd, mode);
++ revert_creds(oldcred);
++
++ return err;
++}
++
++static int shiftfs_setattr(struct dentry *dentry, struct iattr *attr)
++{
++ struct dentry *lowerd = dentry->d_fsdata;
++ struct inode *loweri = lowerd->d_inode;
++ struct iattr newattr;
++ const struct cred *oldcred;
++ struct super_block *sb = dentry->d_sb;
++ struct shiftfs_super_info *sbinfo = sb->s_fs_info;
++ int err;
++
++ err = setattr_prepare(dentry, attr);
++ if (err)
++ return err;
++
++ newattr = *attr;
++ newattr.ia_uid = shift_kuid(sb->s_user_ns, sbinfo->userns, attr->ia_uid);
++ newattr.ia_gid = shift_kgid(sb->s_user_ns, sbinfo->userns, attr->ia_gid);
++
++ /*
++ * mode change is for clearing setuid/setgid bits. Allow lower fs
++ * to interpret this in its own way.
++ */
++ if (newattr.ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
++ newattr.ia_valid &= ~ATTR_MODE;
++
++ inode_lock(loweri);
++ oldcred = shiftfs_override_creds(dentry->d_sb);
++ err = notify_change(lowerd, &newattr, NULL);
++ revert_creds(oldcred);
++ inode_unlock(loweri);
++
++ shiftfs_copyattr(loweri, d_inode(dentry));
++
++ return err;
++}
++
++static int shiftfs_getattr(const struct path *path, struct kstat *stat,
++ u32 request_mask, unsigned int query_flags)
++{
++ struct inode *inode = path->dentry->d_inode;
++ struct dentry *lowerd = path->dentry->d_fsdata;
++ struct inode *loweri = lowerd->d_inode;
++ struct shiftfs_super_info *info = path->dentry->d_sb->s_fs_info;
++ struct path newpath = { .mnt = info->mnt, .dentry = lowerd };
++ struct user_namespace *from_ns = loweri->i_sb->s_user_ns;
++ struct user_namespace *to_ns = inode->i_sb->s_user_ns;
++ const struct cred *oldcred;
++ int err;
++
++ oldcred = shiftfs_override_creds(inode->i_sb);
++ err = vfs_getattr(&newpath, stat, request_mask, query_flags);
++ revert_creds(oldcred);
++
++ if (err)
++ return err;
++
++ /* transform the underlying id */
++ stat->uid = shift_kuid(from_ns, to_ns, stat->uid);
++ stat->gid = shift_kgid(from_ns, to_ns, stat->gid);
++ return 0;
++}
++
++#ifdef CONFIG_SHIFT_FS_POSIX_ACL
++
++static int
++shift_acl_ids(struct user_namespace *from, struct user_namespace *to,
++ struct posix_acl *acl)
++{
++ int i;
++
++ for (i = 0; i < acl->a_count; i++) {
++ struct posix_acl_entry *e = &acl->a_entries[i];
++ switch(e->e_tag) {
++ case ACL_USER:
++ e->e_uid = shift_kuid(from, to, e->e_uid);
++ if (!uid_valid(e->e_uid))
++ return -EOVERFLOW;
++ break;
++ case ACL_GROUP:
++ e->e_gid = shift_kgid(from, to, e->e_gid);
++ if (!gid_valid(e->e_gid))
++ return -EOVERFLOW;
++ break;
++ }
++ }
++ return 0;
++}
++
++static void
++shift_acl_xattr_ids(struct user_namespace *from, struct user_namespace *to,
++ void *value, size_t size)
++{
++ struct posix_acl_xattr_header *header = value;
++ struct posix_acl_xattr_entry *entry = (void *)(header + 1), *end;
++ int count;
++ kuid_t kuid;
++ kgid_t kgid;
++
++ if (!value)
++ return;
++ if (size < sizeof(struct posix_acl_xattr_header))
++ return;
++ if (header->a_version != cpu_to_le32(POSIX_ACL_XATTR_VERSION))
++ return;
++
++ count = posix_acl_xattr_count(size);
++ if (count < 0)
++ return;
++ if (count == 0)
++ return;
++
++ for (end = entry + count; entry != end; entry++) {
++ switch(le16_to_cpu(entry->e_tag)) {
++ case ACL_USER:
++ kuid = make_kuid(&init_user_ns, le32_to_cpu(entry->e_id));
++ kuid = shift_kuid(from, to, kuid);
++ entry->e_id = cpu_to_le32(from_kuid(&init_user_ns, kuid));
++ break;
++ case ACL_GROUP:
++ kgid = make_kgid(&init_user_ns, le32_to_cpu(entry->e_id));
++ kgid = shift_kgid(from, to, kgid);
++ entry->e_id = cpu_to_le32(from_kgid(&init_user_ns, kgid));
++ break;
++ default:
++ break;
++ }
++ }
++}
++
++static struct posix_acl *shiftfs_get_acl(struct inode *inode, int type)
++{
++ struct inode *loweri = inode->i_private;
++ const struct cred *oldcred;
++ struct posix_acl *lower_acl, *acl = NULL;
++ struct user_namespace *from_ns = loweri->i_sb->s_user_ns;
++ struct user_namespace *to_ns = inode->i_sb->s_user_ns;
++ int size;
++ int err;
++
++ if (!IS_POSIXACL(loweri))
++ return NULL;
++
++ oldcred = shiftfs_override_creds(inode->i_sb);
++ lower_acl = get_acl(loweri, type);
++ revert_creds(oldcred);
++
++ if (lower_acl && !IS_ERR(lower_acl)) {
++ /* XXX: export posix_acl_clone? */
++ size = sizeof(struct posix_acl) +
++ lower_acl->a_count * sizeof(struct posix_acl_entry);
++ acl = kmemdup(lower_acl, size, GFP_KERNEL);
++ posix_acl_release(lower_acl);
++
++ if (!acl)
++ return ERR_PTR(-ENOMEM);
++
++ refcount_set(&acl->a_refcount, 1);
++
++ err = shift_acl_ids(from_ns, to_ns, acl);
++ if (err) {
++ kfree(acl);
++ return ERR_PTR(err);
++ }
++ }
++
++ return acl;
++}
++
++static int
++shiftfs_posix_acl_xattr_get(const struct xattr_handler *handler,
++ struct dentry *dentry, struct inode *inode,
++ const char *name, void *buffer, size_t size)
++{
++ struct inode *loweri = inode->i_private;
++ int ret;
++
++ ret = shiftfs_xattr_get(NULL, dentry, inode, handler->name,
++ buffer, size);
++ if (ret < 0)
++ return ret;
++
++ inode_lock(loweri);
++ shift_acl_xattr_ids(loweri->i_sb->s_user_ns, inode->i_sb->s_user_ns,
++ buffer, size);
++ inode_unlock(loweri);
++ return ret;
++}
++
++static int
++shiftfs_posix_acl_xattr_set(const struct xattr_handler *handler,
++ struct dentry *dentry, struct inode *inode,
++ const char *name, const void *value,
++ size_t size, int flags)
++{
++ struct inode *loweri = inode->i_private;
++ int err;
++
++ if (!IS_POSIXACL(loweri) || !loweri->i_op->set_acl)
++ return -EOPNOTSUPP;
++ if (handler->flags == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode))
++ return value ? -EACCES : 0;
++ if (!inode_owner_or_capable(inode))
++ return -EPERM;
++
++ if (value) {
++ shift_acl_xattr_ids(inode->i_sb->s_user_ns,
++ loweri->i_sb->s_user_ns,
++ (void *)value, size);
++ err = shiftfs_setxattr(dentry, inode, handler->name, value,
++ size, flags);
++ } else {
++ err = shiftfs_removexattr(dentry, handler->name);
++ }
++
++ if (!err)
++ shiftfs_copyattr(loweri, inode);
++
++ return err;
++}
++
++static const struct xattr_handler
++shiftfs_posix_acl_access_xattr_handler = {
++ .name = XATTR_NAME_POSIX_ACL_ACCESS,
++ .flags = ACL_TYPE_ACCESS,
++ .get = shiftfs_posix_acl_xattr_get,
++ .set = shiftfs_posix_acl_xattr_set,
++};
++
++static const struct xattr_handler
++shiftfs_posix_acl_default_xattr_handler = {
++ .name = XATTR_NAME_POSIX_ACL_DEFAULT,
++ .flags = ACL_TYPE_DEFAULT,
++ .get = shiftfs_posix_acl_xattr_get,
++ .set = shiftfs_posix_acl_xattr_set,
++};
++
++#else /* !CONFIG_SHIFT_FS_POSIX_ACL */
++
++#define shiftfs_get_acl NULL
++
++#endif /* CONFIG_SHIFT_FS_POSIX_ACL */
++
++static const struct inode_operations shiftfs_dir_inode_operations = {
++ .lookup = shiftfs_lookup,
++ .mkdir = shiftfs_mkdir,
++ .symlink = shiftfs_symlink,
++ .unlink = shiftfs_unlink,
++ .rmdir = shiftfs_rmdir,
++ .rename = shiftfs_rename,
++ .link = shiftfs_link,
++ .setattr = shiftfs_setattr,
++ .create = shiftfs_create,
++ .mknod = shiftfs_mknod,
++ .permission = shiftfs_permission,
++ .getattr = shiftfs_getattr,
++ .listxattr = shiftfs_listxattr,
++ .get_acl = shiftfs_get_acl,
++};
++
++static const struct inode_operations shiftfs_file_inode_operations = {
++ .fiemap = shiftfs_fiemap,
++ .getattr = shiftfs_getattr,
++ .get_acl = shiftfs_get_acl,
++ .listxattr = shiftfs_listxattr,
++ .permission = shiftfs_permission,
++ .setattr = shiftfs_setattr,
++ .tmpfile = shiftfs_tmpfile,
++};
++
++static const struct inode_operations shiftfs_special_inode_operations = {
++ .getattr = shiftfs_getattr,
++ .get_acl = shiftfs_get_acl,
++ .listxattr = shiftfs_listxattr,
++ .permission = shiftfs_permission,
++ .setattr = shiftfs_setattr,
++};
++
++static const struct inode_operations shiftfs_symlink_inode_operations = {
++ .getattr = shiftfs_getattr,
++ .get_link = shiftfs_get_link,
++ .listxattr = shiftfs_listxattr,
++ .setattr = shiftfs_setattr,
++};
++
++static struct file *shiftfs_open_realfile(const struct file *file,
++ struct inode *realinode)
++{
++ struct file *realfile;
++ const struct cred *old_cred;
++ struct inode *inode = file_inode(file);
++ struct dentry *lowerd = file->f_path.dentry->d_fsdata;
++ struct shiftfs_super_info *info = inode->i_sb->s_fs_info;
++ struct path realpath = { .mnt = info->mnt, .dentry = lowerd };
++
++ old_cred = shiftfs_override_creds(inode->i_sb);
++ realfile = open_with_fake_path(&realpath, file->f_flags, realinode,
++ info->creator_cred);
++ revert_creds(old_cred);
++
++ return realfile;
++}
++
++#define SHIFTFS_SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT)
++
++static int shiftfs_change_flags(struct file *file, unsigned int flags)
++{
++ struct inode *inode = file_inode(file);
++ int err;
++
++ /* if some flag changed that cannot be changed then something's amiss */
++ if (WARN_ON((file->f_flags ^ flags) & ~SHIFTFS_SETFL_MASK))
++ return -EIO;
++
++ flags &= SHIFTFS_SETFL_MASK;
++
++ if (((flags ^ file->f_flags) & O_APPEND) && IS_APPEND(inode))
++ return -EPERM;
++
++ if (flags & O_DIRECT) {
++ if (!file->f_mapping->a_ops ||
++ !file->f_mapping->a_ops->direct_IO)
++ return -EINVAL;
++ }
++
++ if (file->f_op->check_flags) {
++ err = file->f_op->check_flags(flags);
++ if (err)
++ return err;
++ }
++
++ spin_lock(&file->f_lock);
++ file->f_flags = (file->f_flags & ~SHIFTFS_SETFL_MASK) | flags;
++ spin_unlock(&file->f_lock);
++
++ return 0;
++}
++
++static int shiftfs_open(struct inode *inode, struct file *file)
++{
++ struct file *realfile;
++
++ realfile = shiftfs_open_realfile(file, inode->i_private);
++ if (IS_ERR(realfile))
++ return PTR_ERR(realfile);
++
++ file->private_data = realfile;
++ /* For O_DIRECT dentry_open() checks f_mapping->a_ops->direct_IO. */
++ file->f_mapping = realfile->f_mapping;
++
++ return 0;
++}
++
++static int shiftfs_dir_open(struct inode *inode, struct file *file)
++{
++ struct file *realfile;
++ const struct cred *oldcred;
++ struct dentry *lowerd = file->f_path.dentry->d_fsdata;
++ struct shiftfs_super_info *info = inode->i_sb->s_fs_info;
++ struct path realpath = { .mnt = info->mnt, .dentry = lowerd };
++
++ oldcred = shiftfs_override_creds(file->f_path.dentry->d_sb);
++ realfile = dentry_open(&realpath, file->f_flags | O_NOATIME,
++ info->creator_cred);
++ revert_creds(oldcred);
++ if (IS_ERR(realfile))
++ return PTR_ERR(realfile);
++
++ file->private_data = realfile;
++
++ return 0;
++}
++
++static int shiftfs_release(struct inode *inode, struct file *file)
++{
++ struct file *realfile = file->private_data;
++
++ if (realfile)
++ fput(realfile);
++
++ return 0;
++}
++
++static int shiftfs_dir_release(struct inode *inode, struct file *file)
++{
++ return shiftfs_release(inode, file);
++}
++
++static loff_t shiftfs_dir_llseek(struct file *file, loff_t offset, int whence)
++{
++ struct file *realfile = file->private_data;
++
++ return vfs_llseek(realfile, offset, whence);
++}
++
++static loff_t shiftfs_file_llseek(struct file *file, loff_t offset, int whence)
++{
++ struct inode *realinode = file_inode(file)->i_private;
++
++ return generic_file_llseek_size(file, offset, whence,
++ realinode->i_sb->s_maxbytes,
++ i_size_read(realinode));
++}
++
++/* XXX: Need to figure out what to to about atime updates, maybe other
++ * timestamps too ... ref. ovl_file_accessed() */
++
++static rwf_t shiftfs_iocb_to_rwf(struct kiocb *iocb)
++{
++ int ifl = iocb->ki_flags;
++ rwf_t flags = 0;
++
++ if (ifl & IOCB_NOWAIT)
++ flags |= RWF_NOWAIT;
++ if (ifl & IOCB_HIPRI)
++ flags |= RWF_HIPRI;
++ if (ifl & IOCB_DSYNC)
++ flags |= RWF_DSYNC;
++ if (ifl & IOCB_SYNC)
++ flags |= RWF_SYNC;
++
++ return flags;
++}
++
++static int shiftfs_real_fdget(const struct file *file, struct fd *lowerfd)
++{
++ struct file *realfile;
++
++ if (file->f_op->open != shiftfs_open &&
++ file->f_op->open != shiftfs_dir_open)
++ return -EINVAL;
++
++ realfile = file->private_data;
++ lowerfd->flags = 0;
++ lowerfd->file = realfile;
++
++ /* Did the flags change since open? */
++ if (unlikely(file->f_flags & ~lowerfd->file->f_flags))
++ return shiftfs_change_flags(lowerfd->file, file->f_flags);
++
++ return 0;
++}
++
++static ssize_t shiftfs_read_iter(struct kiocb *iocb, struct iov_iter *iter)
++{
++ struct file *file = iocb->ki_filp;
++ struct fd lowerfd;
++ const struct cred *oldcred;
++ ssize_t ret;
++
++ if (!iov_iter_count(iter))
++ return 0;
++
++ ret = shiftfs_real_fdget(file, &lowerfd);
++ if (ret)
++ return ret;
++
++ oldcred = shiftfs_override_creds(file->f_path.dentry->d_sb);
++ ret = vfs_iter_read(lowerfd.file, iter, &iocb->ki_pos,
++ shiftfs_iocb_to_rwf(iocb));
++ revert_creds(oldcred);
++
++ shiftfs_file_accessed(file);
++
++ fdput(lowerfd);
++ return ret;
++}
++
++static ssize_t shiftfs_write_iter(struct kiocb *iocb, struct iov_iter *iter)
++{
++ struct file *file = iocb->ki_filp;
++ struct inode *inode = file_inode(file);
++ struct fd lowerfd;
++ const struct cred *oldcred;
++ ssize_t ret;
++
++ if (!iov_iter_count(iter))
++ return 0;
++
++ inode_lock(inode);
++ /* Update mode */
++ shiftfs_copyattr(inode->i_private, inode);
++ ret = file_remove_privs(file);
++ if (ret)
++ goto out_unlock;
++
++ ret = shiftfs_real_fdget(file, &lowerfd);
++ if (ret)
++ goto out_unlock;
++
++ oldcred = shiftfs_override_creds(file->f_path.dentry->d_sb);
++ file_start_write(lowerfd.file);
++ ret = vfs_iter_write(lowerfd.file, iter, &iocb->ki_pos,
++ shiftfs_iocb_to_rwf(iocb));
++ file_end_write(lowerfd.file);
++ revert_creds(oldcred);
++
++ /* Update size */
++ shiftfs_copyattr(inode->i_private, inode);
++
++ fdput(lowerfd);
++
++out_unlock:
++ inode_unlock(inode);
++ return ret;
++}
++
++static int shiftfs_fsync(struct file *file, loff_t start, loff_t end,
++ int datasync)
++{
++ struct fd lowerfd;
++ const struct cred *oldcred;
++ int ret;
++
++ ret = shiftfs_real_fdget(file, &lowerfd);
++ if (ret)
++ return ret;
++
++ oldcred = shiftfs_override_creds(file->f_path.dentry->d_sb);
++ ret = vfs_fsync_range(lowerfd.file, start, end, datasync);
++ revert_creds(oldcred);
++
++ fdput(lowerfd);
++ return ret;
++}
++
++static int shiftfs_mmap(struct file *file, struct vm_area_struct *vma)
++{
++ struct file *realfile = file->private_data;
++ const struct cred *oldcred;
++ int ret;
++
++ if (!realfile->f_op->mmap)
++ return -ENODEV;
++
++ if (WARN_ON(file != vma->vm_file))
++ return -EIO;
++
++ oldcred = shiftfs_override_creds(file->f_path.dentry->d_sb);
++ vma->vm_file = get_file(realfile);
++ ret = call_mmap(vma->vm_file, vma);
++ revert_creds(oldcred);
++
++ shiftfs_file_accessed(file);
++
++ if (ret) {
++ /*
++ * Drop refcount from new vm_file value and restore original
++ * vm_file value
++ */
++ vma->vm_file = file;
++ fput(realfile);
++ } else {
++ /* Drop refcount from previous vm_file value */
++ fput(file);
++ }
++
++ return ret;
++}
++
++static long shiftfs_fallocate(struct file *file, int mode, loff_t offset,
++ loff_t len)
++{
++ struct inode *inode = file_inode(file);
++ struct inode *loweri = inode->i_private;
++ struct fd lowerfd;
++ const struct cred *oldcred;
++ int ret;
++
++ ret = shiftfs_real_fdget(file, &lowerfd);
++ if (ret)
++ return ret;
++
++ oldcred = shiftfs_override_creds(file->f_path.dentry->d_sb);
++ ret = vfs_fallocate(lowerfd.file, mode, offset, len);
++ revert_creds(oldcred);
++
++ /* Update size */
++ shiftfs_copyattr(loweri, inode);
++
++ fdput(lowerfd);
++ return ret;
++}
++
++static int shiftfs_fadvise(struct file *file, loff_t offset, loff_t len,
++ int advice)
++{
++ struct fd lowerfd;
++ const struct cred *oldcred;
++ int ret;
++
++ ret = shiftfs_real_fdget(file, &lowerfd);
++ if (ret)
++ return ret;
++
++ oldcred = shiftfs_override_creds(file->f_path.dentry->d_sb);
++ ret = vfs_fadvise(lowerfd.file, offset, len, advice);
++ revert_creds(oldcred);
++
++ fdput(lowerfd);
++ return ret;
++}
++
++static int shiftfs_override_ioctl_creds(int cmd, const struct super_block *sb,
++ const struct cred **oldcred,
++ struct cred **newcred)
++{
++ struct shiftfs_super_info *sbinfo = sb->s_fs_info;
++ kuid_t fsuid = current_fsuid();
++ kgid_t fsgid = current_fsgid();
++
++ *oldcred = shiftfs_override_creds(sb);
++
++ *newcred = prepare_creds();
++ if (!*newcred) {
++ revert_creds(*oldcred);
++ return -ENOMEM;
++ }
++
++ (*newcred)->fsuid = shift_kuid(sb->s_user_ns, sbinfo->userns, fsuid);
++ (*newcred)->fsgid = shift_kgid(sb->s_user_ns, sbinfo->userns, fsgid);
++
++ /* clear all caps to prevent bypassing capable() checks */
++ cap_clear((*newcred)->cap_bset);
++ cap_clear((*newcred)->cap_effective);
++ cap_clear((*newcred)->cap_inheritable);
++ cap_clear((*newcred)->cap_permitted);
++
++ if (cmd == BTRFS_IOC_SNAP_DESTROY) {
++ kuid_t kuid_root = make_kuid(sb->s_user_ns, 0);
++ /*
++ * Allow the root user in the container to remove subvolumes
++ * from other users.
++ */
++ if (uid_valid(kuid_root) && uid_eq(fsuid, kuid_root))
++ cap_raise((*newcred)->cap_effective, CAP_DAC_OVERRIDE);
++ }
++
++ put_cred(override_creds(*newcred));
++ return 0;
++}
++
++static inline void shiftfs_revert_ioctl_creds(const struct cred *oldcred,
++ struct cred *newcred)
++{
++ return shiftfs_revert_object_creds(oldcred, newcred);
++}
++
++static inline bool is_btrfs_snap_ioctl(int cmd)
++{
++ if ((cmd == BTRFS_IOC_SNAP_CREATE) || (cmd == BTRFS_IOC_SNAP_CREATE_V2))
++ return true;
++
++ return false;
++}
++
++static int shiftfs_btrfs_ioctl_fd_restore(int cmd, int fd, void __user *arg,
++ struct btrfs_ioctl_vol_args *v1,
++ struct btrfs_ioctl_vol_args_v2 *v2)
++{
++ int ret;
++
++ if (!is_btrfs_snap_ioctl(cmd))
++ return 0;
++
++ if (cmd == BTRFS_IOC_SNAP_CREATE)
++ ret = copy_to_user(arg, v1, sizeof(*v1));
++ else
++ ret = copy_to_user(arg, v2, sizeof(*v2));
++
++ __close_fd(current->files, fd);
++ kfree(v1);
++ kfree(v2);
++
++ return ret;
++}
++
++static int shiftfs_btrfs_ioctl_fd_replace(int cmd, void __user *arg,
++ struct btrfs_ioctl_vol_args **b1,
++ struct btrfs_ioctl_vol_args_v2 **b2,
++ int *newfd)
++{
++ int oldfd, ret;
++ struct fd src;
++ struct fd lfd = {};
++ struct btrfs_ioctl_vol_args *v1 = NULL;
++ struct btrfs_ioctl_vol_args_v2 *v2 = NULL;
++
++ if (!is_btrfs_snap_ioctl(cmd))
++ return 0;
++
++ if (cmd == BTRFS_IOC_SNAP_CREATE) {
++ v1 = memdup_user(arg, sizeof(*v1));
++ if (IS_ERR(v1))
++ return PTR_ERR(v1);
++ oldfd = v1->fd;
++ *b1 = v1;
++ } else {
++ v2 = memdup_user(arg, sizeof(*v2));
++ if (IS_ERR(v2))
++ return PTR_ERR(v2);
++ oldfd = v2->fd;
++ *b2 = v2;
++ }
++
++ src = fdget(oldfd);
++ if (!src.file)
++ return -EINVAL;
++
++ ret = shiftfs_real_fdget(src.file, &lfd);
++ if (ret) {
++ fdput(src);
++ return ret;
++ }
++
++ /*
++ * shiftfs_real_fdget() does not take a reference to lfd.file, so
++ * take a reference here to offset the one which will be put by
++ * __close_fd(), and make sure that reference is put on fdput(lfd).
++ */
++ get_file(lfd.file);
++ lfd.flags |= FDPUT_FPUT;
++ fdput(src);
++
++ *newfd = get_unused_fd_flags(lfd.file->f_flags);
++ if (*newfd < 0) {
++ fdput(lfd);
++ return *newfd;
++ }
++
++ fd_install(*newfd, lfd.file);
++
++ if (cmd == BTRFS_IOC_SNAP_CREATE) {
++ v1->fd = *newfd;
++ ret = copy_to_user(arg, v1, sizeof(*v1));
++ v1->fd = oldfd;
++ } else {
++ v2->fd = *newfd;
++ ret = copy_to_user(arg, v2, sizeof(*v2));
++ v2->fd = oldfd;
++ }
++
++ if (ret)
++ shiftfs_btrfs_ioctl_fd_restore(cmd, *newfd, arg, v1, v2);
++
++ return ret;
++}
++
++static long shiftfs_real_ioctl(struct file *file, unsigned int cmd,
++ unsigned long arg)
++{
++ struct fd lowerfd;
++ struct cred *newcred;
++ const struct cred *oldcred;
++ int newfd = -EBADF;
++ long err = 0, ret = 0;
++ void __user *argp = (void __user *)arg;
++ struct super_block *sb = file->f_path.dentry->d_sb;
++ struct btrfs_ioctl_vol_args *btrfs_v1 = NULL;
++ struct btrfs_ioctl_vol_args_v2 *btrfs_v2 = NULL;
++
++ ret = shiftfs_btrfs_ioctl_fd_replace(cmd, argp, &btrfs_v1, &btrfs_v2,
++ &newfd);
++ if (ret < 0)
++ return ret;
++
++ ret = shiftfs_real_fdget(file, &lowerfd);
++ if (ret)
++ goto out_restore;
++
++ ret = shiftfs_override_ioctl_creds(cmd, sb, &oldcred, &newcred);
++ if (ret)
++ goto out_fdput;
++
++ ret = vfs_ioctl(lowerfd.file, cmd, arg);
++
++ shiftfs_revert_ioctl_creds(oldcred, newcred);
++
++ shiftfs_copyattr(file_inode(lowerfd.file), file_inode(file));
++ shiftfs_copyflags(file_inode(lowerfd.file), file_inode(file));
++
++out_fdput:
++ fdput(lowerfd);
++
++out_restore:
++ err = shiftfs_btrfs_ioctl_fd_restore(cmd, newfd, argp,
++ btrfs_v1, btrfs_v2);
++ if (!ret)
++ ret = err;
++
++ return ret;
++}
++
++static bool in_ioctl_whitelist(int flag, unsigned long arg)
++{
++ void __user *argp = (void __user *)arg;
++ u64 flags = 0;
++
++ switch (flag) {
++ case BTRFS_IOC_FS_INFO:
++ return true;
++ case BTRFS_IOC_SNAP_CREATE:
++ return true;
++ case BTRFS_IOC_SNAP_CREATE_V2:
++ return true;
++ case BTRFS_IOC_SUBVOL_CREATE:
++ return true;
++ case BTRFS_IOC_SUBVOL_CREATE_V2:
++ return true;
++ case BTRFS_IOC_SUBVOL_GETFLAGS:
++ return true;
++ case BTRFS_IOC_SUBVOL_SETFLAGS:
++ if (copy_from_user(&flags, argp, sizeof(flags)))
++ return false;
++
++ if (flags & ~BTRFS_SUBVOL_RDONLY)
++ return false;
++
++ return true;
++ case BTRFS_IOC_SNAP_DESTROY:
++ return true;
++ }
++
++ return false;
++}
++
++static long shiftfs_ioctl(struct file *file, unsigned int cmd,
++ unsigned long arg)
++{
++ switch (cmd) {
++ case FS_IOC_GETVERSION:
++ /* fall through */
++ case FS_IOC_GETFLAGS:
++ /* fall through */
++ case FS_IOC_SETFLAGS:
++ break;
++ default:
++ if (!in_ioctl_whitelist(cmd, arg) ||
++ !shiftfs_passthrough_ioctls(file->f_path.dentry->d_sb->s_fs_info))
++ return -ENOTTY;
++ }
++
++ return shiftfs_real_ioctl(file, cmd, arg);
++}
++
++static long shiftfs_compat_ioctl(struct file *file, unsigned int cmd,
++ unsigned long arg)
++{
++ switch (cmd) {
++ case FS_IOC32_GETVERSION:
++ /* fall through */
++ case FS_IOC32_GETFLAGS:
++ /* fall through */
++ case FS_IOC32_SETFLAGS:
++ break;
++ default:
++ if (!in_ioctl_whitelist(cmd, arg) ||
++ !shiftfs_passthrough_ioctls(file->f_path.dentry->d_sb->s_fs_info))
++ return -ENOIOCTLCMD;
++ }
++
++ return shiftfs_real_ioctl(file, cmd, arg);
++}
++
++enum shiftfs_copyop {
++ SHIFTFS_COPY,
++ SHIFTFS_CLONE,
++ SHIFTFS_DEDUPE,
++};
++
++static ssize_t shiftfs_copyfile(struct file *file_in, loff_t pos_in,
++ struct file *file_out, loff_t pos_out, u64 len,
++ unsigned int flags, enum shiftfs_copyop op)
++{
++ ssize_t ret;
++ struct fd real_in, real_out;
++ const struct cred *oldcred;
++ struct inode *inode_out = file_inode(file_out);
++ struct inode *loweri = inode_out->i_private;
++
++ ret = shiftfs_real_fdget(file_out, &real_out);
++ if (ret)
++ return ret;
++
++ ret = shiftfs_real_fdget(file_in, &real_in);
++ if (ret) {
++ fdput(real_out);
++ return ret;
++ }
++
++ oldcred = shiftfs_override_creds(inode_out->i_sb);
++ switch (op) {
++ case SHIFTFS_COPY:
++ ret = vfs_copy_file_range(real_in.file, pos_in, real_out.file,
++ pos_out, len, flags);
++ break;
++
++ case SHIFTFS_CLONE:
++ ret = vfs_clone_file_range(real_in.file, pos_in, real_out.file,
++ pos_out, len, flags);
++ break;
++
++ case SHIFTFS_DEDUPE:
++ ret = vfs_dedupe_file_range_one(real_in.file, pos_in,
++ real_out.file, pos_out, len,
++ flags);
++ break;
++ }
++ revert_creds(oldcred);
++
++ /* Update size */
++ shiftfs_copyattr(loweri, inode_out);
++
++ fdput(real_in);
++ fdput(real_out);
++
++ return ret;
++}
++
++static ssize_t shiftfs_copy_file_range(struct file *file_in, loff_t pos_in,
++ struct file *file_out, loff_t pos_out,
++ size_t len, unsigned int flags)
++{
++ return shiftfs_copyfile(file_in, pos_in, file_out, pos_out, len, flags,
++ SHIFTFS_COPY);
++}
++
++static loff_t shiftfs_remap_file_range(struct file *file_in, loff_t pos_in,
++ struct file *file_out, loff_t pos_out,
++ loff_t len, unsigned int remap_flags)
++{
++ enum shiftfs_copyop op;
++
++ if (remap_flags & ~(REMAP_FILE_DEDUP | REMAP_FILE_ADVISORY))
++ return -EINVAL;
++
++ if (remap_flags & REMAP_FILE_DEDUP)
++ op = SHIFTFS_DEDUPE;
++ else
++ op = SHIFTFS_CLONE;
++
++ return shiftfs_copyfile(file_in, pos_in, file_out, pos_out, len,
++ remap_flags, op);
++}
++
++static int shiftfs_iterate_shared(struct file *file, struct dir_context *ctx)
++{
++ const struct cred *oldcred;
++ int err = -ENOTDIR;
++ struct file *realfile = file->private_data;
++
++ oldcred = shiftfs_override_creds(file->f_path.dentry->d_sb);
++ err = iterate_dir(realfile, ctx);
++ revert_creds(oldcred);
++
++ return err;
++}
++
++const struct file_operations shiftfs_file_operations = {
++ .open = shiftfs_open,
++ .release = shiftfs_release,
++ .llseek = shiftfs_file_llseek,
++ .read_iter = shiftfs_read_iter,
++ .write_iter = shiftfs_write_iter,
++ .fsync = shiftfs_fsync,
++ .mmap = shiftfs_mmap,
++ .fallocate = shiftfs_fallocate,
++ .fadvise = shiftfs_fadvise,
++ .unlocked_ioctl = shiftfs_ioctl,
++ .compat_ioctl = shiftfs_compat_ioctl,
++ .copy_file_range = shiftfs_copy_file_range,
++ .remap_file_range = shiftfs_remap_file_range,
++};
++
++const struct file_operations shiftfs_dir_operations = {
++ .open = shiftfs_dir_open,
++ .release = shiftfs_dir_release,
++ .compat_ioctl = shiftfs_compat_ioctl,
++ .fsync = shiftfs_fsync,
++ .iterate_shared = shiftfs_iterate_shared,
++ .llseek = shiftfs_dir_llseek,
++ .read = generic_read_dir,
++ .unlocked_ioctl = shiftfs_ioctl,
++};
++
++static const struct address_space_operations shiftfs_aops = {
++ /* For O_DIRECT dentry_open() checks f_mapping->a_ops->direct_IO */
++ .direct_IO = noop_direct_IO,
++};
++
++static void shiftfs_fill_inode(struct inode *inode, unsigned long ino,
++ umode_t mode, dev_t dev, struct dentry *dentry)
++{
++ struct inode *loweri;
++
++ inode->i_ino = ino;
++ inode->i_flags |= S_NOCMTIME;
++
++ mode &= S_IFMT;
++ inode->i_mode = mode;
++ switch (mode & S_IFMT) {
++ case S_IFDIR:
++ inode->i_op = &shiftfs_dir_inode_operations;
++ inode->i_fop = &shiftfs_dir_operations;
++ break;
++ case S_IFLNK:
++ inode->i_op = &shiftfs_symlink_inode_operations;
++ break;
++ case S_IFREG:
++ inode->i_op = &shiftfs_file_inode_operations;
++ inode->i_fop = &shiftfs_file_operations;
++ inode->i_mapping->a_ops = &shiftfs_aops;
++ break;
++ default:
++ inode->i_op = &shiftfs_special_inode_operations;
++ init_special_inode(inode, mode, dev);
++ break;
++ }
++
++ if (!dentry)
++ return;
++
++ loweri = dentry->d_inode;
++ if (!loweri->i_op->get_link)
++ inode->i_opflags |= IOP_NOFOLLOW;
++
++ shiftfs_copyattr(loweri, inode);
++ shiftfs_copyflags(loweri, inode);
++ set_nlink(inode, loweri->i_nlink);
++}
++
++static int shiftfs_show_options(struct seq_file *m, struct dentry *dentry)
++{
++ struct super_block *sb = dentry->d_sb;
++ struct shiftfs_super_info *sbinfo = sb->s_fs_info;
++
++ if (sbinfo->mark)
++ seq_show_option(m, "mark", NULL);
++
++ if (sbinfo->passthrough)
++ seq_printf(m, ",passthrough=%u", sbinfo->passthrough);
++
++ return 0;
++}
++
++static int shiftfs_statfs(struct dentry *dentry, struct kstatfs *buf)
++{
++ struct super_block *sb = dentry->d_sb;
++ struct shiftfs_super_info *sbinfo = sb->s_fs_info;
++ struct dentry *root = sb->s_root;
++ struct dentry *realroot = root->d_fsdata;
++ struct path realpath = { .mnt = sbinfo->mnt, .dentry = realroot };
++ int err;
++
++ err = vfs_statfs(&realpath, buf);
++ if (err)
++ return err;
++
++ if (!shiftfs_passthrough_statfs(sbinfo))
++ buf->f_type = sb->s_magic;
++
++ return 0;
++}
++
++static void shiftfs_evict_inode(struct inode *inode)
++{
++ struct inode *loweri = inode->i_private;
++
++ clear_inode(inode);
++
++ if (loweri)
++ iput(loweri);
++}
++
++static void shiftfs_put_super(struct super_block *sb)
++{
++ struct shiftfs_super_info *sbinfo = sb->s_fs_info;
++
++ if (sbinfo) {
++ mntput(sbinfo->mnt);
++ put_cred(sbinfo->creator_cred);
++ kfree(sbinfo);
++ }
++}
++
++static const struct xattr_handler shiftfs_xattr_handler = {
++ .prefix = "",
++ .get = shiftfs_xattr_get,
++ .set = shiftfs_xattr_set,
++};
++
++const struct xattr_handler *shiftfs_xattr_handlers[] = {
++#ifdef CONFIG_SHIFT_FS_POSIX_ACL
++ &shiftfs_posix_acl_access_xattr_handler,
++ &shiftfs_posix_acl_default_xattr_handler,
++#endif
++ &shiftfs_xattr_handler,
++ NULL
++};
++
++static inline bool passthrough_is_subset(int old_flags, int new_flags)
++{
++ if ((new_flags & old_flags) != new_flags)
++ return false;
++
++ return true;
++}
++
++static int shiftfs_super_check_flags(unsigned long old_flags,
++ unsigned long new_flags)
++{
++ if ((old_flags & SB_RDONLY) && !(new_flags & SB_RDONLY))
++ return -EPERM;
++
++ if ((old_flags & SB_NOSUID) && !(new_flags & SB_NOSUID))
++ return -EPERM;
++
++ if ((old_flags & SB_NODEV) && !(new_flags & SB_NODEV))
++ return -EPERM;
++
++ if ((old_flags & SB_NOEXEC) && !(new_flags & SB_NOEXEC))
++ return -EPERM;
++
++ if ((old_flags & SB_NOATIME) && !(new_flags & SB_NOATIME))
++ return -EPERM;
++
++ if ((old_flags & SB_NODIRATIME) && !(new_flags & SB_NODIRATIME))
++ return -EPERM;
++
++ if (!(old_flags & SB_POSIXACL) && (new_flags & SB_POSIXACL))
++ return -EPERM;
++
++ return 0;
++}
++
++static int shiftfs_remount(struct super_block *sb, int *flags, char *data)
++{
++ int err;
++ struct shiftfs_super_info new = {};
++ struct shiftfs_super_info *info = sb->s_fs_info;
++
++ err = shiftfs_parse_mount_options(&new, data);
++ if (err)
++ return err;
++
++ err = shiftfs_super_check_flags(sb->s_flags, *flags);
++ if (err)
++ return err;
++
++ /* Mark mount option cannot be changed. */
++ if (info->mark || (info->mark != new.mark))
++ return -EPERM;
++
++ if (info->passthrough != new.passthrough) {
++ /* Don't allow exceeding passthrough options of mark mount. */
++ if (!passthrough_is_subset(info->passthrough_mark,
++ info->passthrough))
++ return -EPERM;
++
++ info->passthrough = new.passthrough;
++ }
++
++ return 0;
++}
++
++static const struct super_operations shiftfs_super_ops = {
++ .put_super = shiftfs_put_super,
++ .show_options = shiftfs_show_options,
++ .statfs = shiftfs_statfs,
++ .remount_fs = shiftfs_remount,
++ .evict_inode = shiftfs_evict_inode,
++};
++
++struct shiftfs_data {
++ void *data;
++ const char *path;
++};
++
++static void shiftfs_super_force_flags(struct super_block *sb,
++ unsigned long lower_flags)
++{
++ sb->s_flags |= lower_flags & (SB_RDONLY | SB_NOSUID | SB_NODEV |
++ SB_NOEXEC | SB_NOATIME | SB_NODIRATIME);
++
++ if (!(lower_flags & SB_POSIXACL))
++ sb->s_flags &= ~SB_POSIXACL;
++}
++
++static int shiftfs_fill_super(struct super_block *sb, void *raw_data,
++ int silent)
++{
++ int err;
++ struct path path = {};
++ struct shiftfs_super_info *sbinfo_mp;
++ char *name = NULL;
++ struct inode *inode = NULL;
++ struct dentry *dentry = NULL;
++ struct shiftfs_data *data = raw_data;
++ struct shiftfs_super_info *sbinfo = NULL;
++
++ if (!data->path)
++ return -EINVAL;
++
++ sb->s_fs_info = kzalloc(sizeof(*sbinfo), GFP_KERNEL);
++ if (!sb->s_fs_info)
++ return -ENOMEM;
++ sbinfo = sb->s_fs_info;
++
++ err = shiftfs_parse_mount_options(sbinfo, data->data);
++ if (err)
++ return err;
++
++ /* to mount a mark, must be userns admin */
++ if (!sbinfo->mark && !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
++ return -EPERM;
++
++ name = kstrdup(data->path, GFP_KERNEL);
++ if (!name)
++ return -ENOMEM;
++
++ err = kern_path(name, LOOKUP_FOLLOW, &path);
++ if (err)
++ goto out_free_name;
++
++ if (!S_ISDIR(path.dentry->d_inode->i_mode)) {
++ err = -ENOTDIR;
++ goto out_put_path;
++ }
++
++ sb->s_flags |= SB_POSIXACL;
++
++ if (sbinfo->mark) {
++ struct cred *cred_tmp;
++ struct super_block *lower_sb = path.mnt->mnt_sb;
++
++ /* to mark a mount point, must root wrt lower s_user_ns */
++ if (!ns_capable(lower_sb->s_user_ns, CAP_SYS_ADMIN)) {
++ err = -EPERM;
++ goto out_put_path;
++ }
++
++ /*
++ * this part is visible unshifted, so make sure no
++ * executables that could be used to give suid
++ * privileges
++ */
++ sb->s_iflags = SB_I_NOEXEC;
++
++ shiftfs_super_force_flags(sb, lower_sb->s_flags);
++
++ /*
++ * Handle nesting of shiftfs mounts by referring this mark
++ * mount back to the original mark mount. This is more
++ * efficient and alleviates concerns about stack depth.
++ */
++ if (lower_sb->s_magic == SHIFTFS_MAGIC) {
++ sbinfo_mp = lower_sb->s_fs_info;
++
++ /* Doesn't make sense to mark a mark mount */
++ if (sbinfo_mp->mark) {
++ err = -EINVAL;
++ goto out_put_path;
++ }
++
++ if (!passthrough_is_subset(sbinfo_mp->passthrough,
++ sbinfo->passthrough)) {
++ err = -EPERM;
++ goto out_put_path;
++ }
++
++ sbinfo->mnt = mntget(sbinfo_mp->mnt);
++ dentry = dget(path.dentry->d_fsdata);
++ /*
++ * Copy up the passthrough mount options from the
++ * parent mark mountpoint.
++ */
++ sbinfo->passthrough_mark = sbinfo_mp->passthrough_mark;
++ sbinfo->creator_cred = get_cred(sbinfo_mp->creator_cred);
++ } else {
++ sbinfo->mnt = mntget(path.mnt);
++ dentry = dget(path.dentry);
++ /*
++ * For a new mark passthrough_mark and passthrough
++ * are identical.
++ */
++ sbinfo->passthrough_mark = sbinfo->passthrough;
++
++ cred_tmp = prepare_creds();
++ if (!cred_tmp) {
++ err = -ENOMEM;
++ goto out_put_path;
++ }
++ /* Don't override disk quota limits or use reserved space. */
++ cap_lower(cred_tmp->cap_effective, CAP_SYS_RESOURCE);
++ sbinfo->creator_cred = cred_tmp;
++ }
++ } else {
++ /*
++ * This leg executes if we're admin capable in the namespace,
++ * so be very careful.
++ */
++ err = -EPERM;
++ if (path.dentry->d_sb->s_magic != SHIFTFS_MAGIC)
++ goto out_put_path;
++
++ sbinfo_mp = path.dentry->d_sb->s_fs_info;
++ if (!sbinfo_mp->mark)
++ goto out_put_path;
++
++ if (!passthrough_is_subset(sbinfo_mp->passthrough,
++ sbinfo->passthrough))
++ goto out_put_path;
++
++ sbinfo->mnt = mntget(sbinfo_mp->mnt);
++ sbinfo->creator_cred = get_cred(sbinfo_mp->creator_cred);
++ dentry = dget(path.dentry->d_fsdata);
++ /*
++ * Copy up passthrough settings from mark mountpoint so we can
++ * verify when the overlay wants to remount with different
++ * passthrough settings.
++ */
++ sbinfo->passthrough_mark = sbinfo_mp->passthrough;
++ shiftfs_super_force_flags(sb, path.mnt->mnt_sb->s_flags);
++ }
++
++ sb->s_stack_depth = dentry->d_sb->s_stack_depth + 1;
++ if (sb->s_stack_depth > FILESYSTEM_MAX_STACK_DEPTH) {
++ printk(KERN_ERR "shiftfs: maximum stacking depth exceeded\n");
++ err = -EINVAL;
++ goto out_put_path;
++ }
++
++ inode = new_inode(sb);
++ if (!inode) {
++ err = -ENOMEM;
++ goto out_put_path;
++ }
++ shiftfs_fill_inode(inode, dentry->d_inode->i_ino, S_IFDIR, 0, dentry);
++
++ ihold(dentry->d_inode);
++ inode->i_private = dentry->d_inode;
++
++ sb->s_magic = SHIFTFS_MAGIC;
++ sb->s_maxbytes = MAX_LFS_FILESIZE;
++ sb->s_op = &shiftfs_super_ops;
++ sb->s_xattr = shiftfs_xattr_handlers;
++ sb->s_d_op = &shiftfs_dentry_ops;
++ sb->s_root = d_make_root(inode);
++ if (!sb->s_root) {
++ err = -ENOMEM;
++ goto out_put_path;
++ }
++
++ sb->s_root->d_fsdata = dentry;
++ sbinfo->userns = get_user_ns(dentry->d_sb->s_user_ns);
++ shiftfs_copyattr(dentry->d_inode, sb->s_root->d_inode);
++
++ dentry = NULL;
++ err = 0;
++
++out_put_path:
++ path_put(&path);
++
++out_free_name:
++ kfree(name);
++
++ dput(dentry);
++
++ return err;
++}
++
++static struct dentry *shiftfs_mount(struct file_system_type *fs_type,
++ int flags, const char *dev_name, void *data)
++{
++ struct shiftfs_data d = { data, dev_name };
++
++ return mount_nodev(fs_type, flags, &d, shiftfs_fill_super);
++}
++
++static struct file_system_type shiftfs_type = {
++ .owner = THIS_MODULE,
++ .name = "shiftfs",
++ .mount = shiftfs_mount,
++ .kill_sb = kill_anon_super,
++ .fs_flags = FS_USERNS_MOUNT,
++};
++
++static int __init shiftfs_init(void)
++{
++ return register_filesystem(&shiftfs_type);
++}
++
++static void __exit shiftfs_exit(void)
++{
++ unregister_filesystem(&shiftfs_type);
++}
++
++MODULE_ALIAS_FS("shiftfs");
++MODULE_AUTHOR("James Bottomley");
++MODULE_AUTHOR("Seth Forshee <seth.forshee@canonical.com>");
++MODULE_AUTHOR("Christian Brauner <christian.brauner@ubuntu.com>");
++MODULE_DESCRIPTION("id shifting filesystem");
++MODULE_LICENSE("GPL v2");
++module_init(shiftfs_init)
++module_exit(shiftfs_exit)
+--- a/include/uapi/linux/magic.h 2021-01-06 19:08:45.234777659 -0500
++++ b/include/uapi/linux/magic.h 2021-01-06 19:09:53.900375394 -0500
+@@ -96,4 +96,6 @@
+ #define DEVMEM_MAGIC 0x454d444d /* "DMEM" */
+ #define Z3FOLD_MAGIC 0x33
+
++#define SHIFTFS_MAGIC 0x6a656a62
++
+ #endif /* __LINUX_MAGIC_H__ */
+--- a/fs/Makefile 2021-01-08 18:08:28.187064015 -0500
++++ b/fs/Makefile 2021-01-08 18:09:00.788217579 -0500
+@@ -136,3 +136,4 @@ obj-$(CONFIG_EFIVAR_FS) += efivarfs/
+ obj-$(CONFIG_EROFS_FS) += erofs/
+ obj-$(CONFIG_VBOXSF_FS) += vboxsf/
+ obj-$(CONFIG_ZONEFS_FS) += zonefs/
++obj-$(CONFIG_SHIFT_FS) += shiftfs.o
+--- a/fs/Kconfig 2021-01-06 19:14:17.709697891 -0500
++++ b/fs/Kconfig 2021-01-06 19:15:23.413281282 -0500
+@@ -122,6 +122,24 @@ source "fs/autofs/Kconfig"
+ source "fs/fuse/Kconfig"
+ source "fs/overlayfs/Kconfig"
+
++config SHIFT_FS
++ tristate "UID/GID shifting overlay filesystem for containers"
++ help
++ This filesystem can overlay any mounted filesystem and shift
++ the uid/gid the files appear at. The idea is that
++ unprivileged containers can use this to mount root volumes
++ using this technique.
++
++config SHIFT_FS_POSIX_ACL
++ bool "shiftfs POSIX Access Control Lists"
++ depends on SHIFT_FS
++ select FS_POSIX_ACL
++ help
++ POSIX Access Control Lists (ACLs) support permissions for users and
++ groups beyond the owner/group/world scheme.
++
++ If you don't know what Access Control Lists are, say N.
++
+ menu "Caches"
+
+ source "fs/fscache/Kconfig"
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0001-make-DEFAULT_MMAP_MIN_ADDR-match-LSM_MMAP_MIN_ADDR.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0001-make-DEFAULT_MMAP_MIN_ADDR-match-LSM_MMAP_MIN_ADDR.patch
new file mode 100644
index 000000000000..6d51081a6c82
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0001-make-DEFAULT_MMAP_MIN_ADDR-match-LSM_MMAP_MIN_ADDR.patch
@@ -0,0 +1,27 @@
+From c08148e63cf99a834bdcc61af247e6b6ad40951b Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Sat, 27 May 2017 07:22:12 -0400
+Subject: [PATCH 001/113] make DEFAULT_MMAP_MIN_ADDR match LSM_MMAP_MIN_ADDR
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ mm/Kconfig | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/mm/Kconfig b/mm/Kconfig
+index 390165ffbb0f..3b24c9e3535e 100644
+--- a/mm/Kconfig
++++ b/mm/Kconfig
+@@ -321,7 +321,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
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0002-enable-HARDENED_USERCOPY-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0002-enable-HARDENED_USERCOPY-by-default.patch
new file mode 100644
index 000000000000..5e7e86682928
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0002-enable-HARDENED_USERCOPY-by-default.patch
@@ -0,0 +1,25 @@
+From b895b1b6a104ad8f4c2c05d8c85040b4b787732a Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Mon, 29 May 2017 06:17:41 -0400
+Subject: [PATCH 002/113] enable HARDENED_USERCOPY by default
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ security/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/security/Kconfig b/security/Kconfig
+index 7561f6f99f1d..9446ddf40974 100644
+--- a/security/Kconfig
++++ b/security/Kconfig
+@@ -154,6 +154,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
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0003-disable-HARDENED_USERCOPY_FALLBACK-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0003-disable-HARDENED_USERCOPY_FALLBACK-by-default.patch
new file mode 100644
index 000000000000..5ea45ca688fa
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0003-disable-HARDENED_USERCOPY_FALLBACK-by-default.patch
@@ -0,0 +1,24 @@
+From 467fa2ec364a40ccb9a7618fa211104bc79c3a7b Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Thu, 26 Apr 2018 02:01:26 -0400
+Subject: [PATCH 003/113] disable HARDENED_USERCOPY_FALLBACK by default
+
+---
+ security/Kconfig | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/security/Kconfig b/security/Kconfig
+index 9446ddf40974..5c388f7fe09d 100644
+--- a/security/Kconfig
++++ b/security/Kconfig
+@@ -167,7 +167,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
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0004-enable-SECURITY_DMESG_RESTRICT-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0004-enable-SECURITY_DMESG_RESTRICT-by-default.patch
new file mode 100644
index 000000000000..402c5a6cd5b0
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0004-enable-SECURITY_DMESG_RESTRICT-by-default.patch
@@ -0,0 +1,26 @@
+From 593daac6352ec4fceff83c152ba3632ea64d85a8 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Wed, 3 May 2017 12:05:15 -0400
+Subject: [PATCH 004/113] enable SECURITY_DMESG_RESTRICT by default
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ security/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/security/Kconfig b/security/Kconfig
+index 5c388f7fe09d..428ad7622370 100644
+--- a/security/Kconfig
++++ b/security/Kconfig
+@@ -9,7 +9,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).
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0005-set-kptr_restrict-2-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0005-set-kptr_restrict-2-by-default.patch
new file mode 100644
index 000000000000..c64e04c8bb19
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0005-set-kptr_restrict-2-by-default.patch
@@ -0,0 +1,26 @@
+From 967e396861b82f8d0daff25b5a9b2bb008076aec Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Wed, 3 May 2017 12:06:14 -0400
+Subject: [PATCH 005/113] set kptr_restrict=2 by default
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ lib/vsprintf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/vsprintf.c b/lib/vsprintf.c
+index 14c9a6af1b23..2501f75bd74d 100644
+--- a/lib/vsprintf.c
++++ b/lib/vsprintf.c
+@@ -821,7 +821,7 @@ static char *ptr_to_id(char *buf, char *end, const void *ptr,
+ return pointer_string(buf, end, (const void *)hashval, 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,
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0006-enable-DEBUG_LIST-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0006-enable-DEBUG_LIST-by-default.patch
new file mode 100644
index 000000000000..208bb4f287c7
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0006-enable-DEBUG_LIST-by-default.patch
@@ -0,0 +1,25 @@
+From 0febc4111e3e908623ab2489e5cba9446e9213e9 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Wed, 3 May 2017 12:10:57 -0400
+Subject: [PATCH 006/113] enable DEBUG_LIST by default
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ lib/Kconfig.debug | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
+index c789b39ed527..89c9d6aebf77 100644
+--- a/lib/Kconfig.debug
++++ b/lib/Kconfig.debug
+@@ -1471,6 +1471,7 @@ menu "Debug kernel data structures"
+ 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.
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0007-enable-BUG_ON_DATA_CORRUPTION-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0007-enable-BUG_ON_DATA_CORRUPTION-by-default.patch
new file mode 100644
index 000000000000..df35827929f9
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0007-enable-BUG_ON_DATA_CORRUPTION-by-default.patch
@@ -0,0 +1,25 @@
+From f5fa582231e90e6bb094e05a8604cc10bb0a793e Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Mon, 29 May 2017 12:21:21 -0400
+Subject: [PATCH 007/113] enable BUG_ON_DATA_CORRUPTION by default
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ lib/Kconfig.debug | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
+index 89c9d6aebf77..11068e77d146 100644
+--- a/lib/Kconfig.debug
++++ b/lib/Kconfig.debug
+@@ -1511,6 +1511,7 @@ config DEBUG_NOTIFIERS
+ 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
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0008-enable-ARM64_SW_TTBR0_PAN-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0008-enable-ARM64_SW_TTBR0_PAN-by-default.patch
new file mode 100644
index 000000000000..cd7aef62607d
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0008-enable-ARM64_SW_TTBR0_PAN-by-default.patch
@@ -0,0 +1,24 @@
+From 935268b79a412174ac7343954e2adfc10902459e Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Sun, 25 Feb 2018 01:39:32 -0500
+Subject: [PATCH 008/113] enable ARM64_SW_TTBR0_PAN by default
+
+---
+ arch/arm64/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
+index a6b5b7ef40ae..a145245ec5e7 100644
+--- a/arch/arm64/Kconfig
++++ b/arch/arm64/Kconfig
+@@ -1199,6 +1199,7 @@ config RODATA_FULL_DEFAULT_ENABLED
+
+ 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
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0009-arm64-enable-RANDOMIZE_BASE-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0009-arm64-enable-RANDOMIZE_BASE-by-default.patch
new file mode 100644
index 000000000000..b547e6ec6e22
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0009-arm64-enable-RANDOMIZE_BASE-by-default.patch
@@ -0,0 +1,24 @@
+From f99493c13116246e9ba06383824cce6e856d4e5d Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Sun, 25 Feb 2018 01:33:48 -0500
+Subject: [PATCH 009/113] arm64: enable RANDOMIZE_BASE by default
+
+---
+ arch/arm64/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
+index a145245ec5e7..21088a6532d8 100644
+--- a/arch/arm64/Kconfig
++++ b/arch/arm64/Kconfig
+@@ -1790,6 +1790,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
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0010-enable-SLAB_FREELIST_RANDOM-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0010-enable-SLAB_FREELIST_RANDOM-by-default.patch
new file mode 100644
index 000000000000..da841868f26d
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0010-enable-SLAB_FREELIST_RANDOM-by-default.patch
@@ -0,0 +1,25 @@
+From ff368e2ff05808d37dec571568c0f50287e4d77c Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Wed, 3 May 2017 19:43:38 -0400
+Subject: [PATCH 010/113] enable SLAB_FREELIST_RANDOM by default
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ init/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/init/Kconfig b/init/Kconfig
+index 0872a5a2e759..dcbcb4243316 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -1929,6 +1929,7 @@ config SLAB_MERGE_DEFAULT
+ config SLAB_FREELIST_RANDOM
+ bool "Randomize slab freelist"
+ depends on SLAB || SLUB
++ default y
+ help
+ Randomizes the freelist order used on creating new pages. This
+ security feature reduces the predictability of the kernel slab
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0011-enable-SLAB_FREELIST_HARDENED-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0011-enable-SLAB_FREELIST_HARDENED-by-default.patch
new file mode 100644
index 000000000000..7d55ca97f37e
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0011-enable-SLAB_FREELIST_HARDENED-by-default.patch
@@ -0,0 +1,24 @@
+From b59aebba3ceef4122584686d3a2f82b7e7e34176 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Sun, 20 Aug 2017 15:39:25 -0400
+Subject: [PATCH 011/113] enable SLAB_FREELIST_HARDENED by default
+
+---
+ init/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/init/Kconfig b/init/Kconfig
+index dcbcb4243316..667d1c6c021b 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -1938,6 +1938,7 @@ config SLAB_FREELIST_RANDOM
+ config SLAB_FREELIST_HARDENED
+ bool "Harden slab freelist metadata"
+ depends on SLAB || SLUB
++ default y
+ help
+ Many kernel heap attacks try to target slab cache metadata and
+ other infrastructure. This options makes minor performance
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0012-disable-SLAB_MERGE_DEFAULT-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0012-disable-SLAB_MERGE_DEFAULT-by-default.patch
new file mode 100644
index 000000000000..b42f315b54de
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0012-disable-SLAB_MERGE_DEFAULT-by-default.patch
@@ -0,0 +1,24 @@
+From 97af255a10ce384d48a18cdb397bedf852dbe749 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Sat, 8 Jul 2017 02:38:54 -0400
+Subject: [PATCH 012/113] disable SLAB_MERGE_DEFAULT by default
+
+---
+ init/Kconfig | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/init/Kconfig b/init/Kconfig
+index 667d1c6c021b..859ab5ae66ff 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -1914,7 +1914,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.
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0013-enable-FORTIFY_SOURCE-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0013-enable-FORTIFY_SOURCE-by-default.patch
new file mode 100644
index 000000000000..d50416cabd0e
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0013-enable-FORTIFY_SOURCE-by-default.patch
@@ -0,0 +1,25 @@
+From 90dc8c5eb2ff066f12771c539f71c2b9cf87b273 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Mon, 8 May 2017 12:51:54 -0400
+Subject: [PATCH 013/113] enable FORTIFY_SOURCE by default
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ security/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/security/Kconfig b/security/Kconfig
+index 428ad7622370..3a2c68c7b50f 100644
+--- a/security/Kconfig
++++ b/security/Kconfig
+@@ -191,6 +191,7 @@ 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.
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0014-enable-PANIC_ON_OOPS-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0014-enable-PANIC_ON_OOPS-by-default.patch
new file mode 100644
index 000000000000..7a26f3e4bcaf
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0014-enable-PANIC_ON_OOPS-by-default.patch
@@ -0,0 +1,34 @@
+From 9e0cedb9a03ca4f234554676ae91a47dc2148e09 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Wed, 3 May 2017 12:09:17 -0400
+Subject: [PATCH 014/113] enable PANIC_ON_OOPS by default
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ lib/Kconfig.debug | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
+index 11068e77d146..45b169177fb9 100644
+--- a/lib/Kconfig.debug
++++ b/lib/Kconfig.debug
+@@ -894,6 +894,7 @@ menu "Debug Oops, 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
+@@ -903,7 +904,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
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0015-stop-hiding-SLUB_DEBUG-behind-EXPERT.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0015-stop-hiding-SLUB_DEBUG-behind-EXPERT.patch
new file mode 100644
index 000000000000..841b15deb76f
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0015-stop-hiding-SLUB_DEBUG-behind-EXPERT.patch
@@ -0,0 +1,26 @@
+From e355335e289287e665b996c16df84c007636df2e Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Sun, 14 May 2017 22:39:34 -0400
+Subject: [PATCH 015/113] stop hiding SLUB_DEBUG behind EXPERT
+
+It can make sense to disable this to reduce attack surface / complexity.
+---
+ init/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/init/Kconfig b/init/Kconfig
+index 859ab5ae66ff..74680a15ceb4 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -1843,7 +1843,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
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0016-stop-hiding-X86_16BIT-behind-EXPERT.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0016-stop-hiding-X86_16BIT-behind-EXPERT.patch
new file mode 100644
index 000000000000..ab3cc0ae988d
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0016-stop-hiding-X86_16BIT-behind-EXPERT.patch
@@ -0,0 +1,25 @@
+From da8913e5cd8444478e81fc0199eea97667bd2070 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Thu, 4 May 2017 18:11:31 -0400
+Subject: [PATCH 016/113] stop hiding X86_16BIT behind EXPERT
+
+---
+ arch/x86/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
+index 3a5ecb1039bf..d2d5e0cbf85c 100644
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -1194,7 +1194,7 @@ config VM86
+ default X86_LEGACY_VM86
+
+ config X86_16BIT
+- bool "Enable support for 16-bit segments" if EXPERT
++ bool "Enable support for 16-bit segments"
+ default y
+ depends on MODIFY_LDT_SYSCALL
+ help
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0017-disable-X86_16BIT-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0017-disable-X86_16BIT-by-default.patch
new file mode 100644
index 000000000000..d1ff728f0d80
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0017-disable-X86_16BIT-by-default.patch
@@ -0,0 +1,25 @@
+From 04b55cd1dcace045623c8a6f9b8895c88ef84fc9 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Thu, 4 May 2017 18:11:52 -0400
+Subject: [PATCH 017/113] disable X86_16BIT by default
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ arch/x86/Kconfig | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
+index d2d5e0cbf85c..ab6e7e2d3cf0 100644
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -1195,7 +1195,6 @@ config VM86
+
+ config X86_16BIT
+ bool "Enable support for 16-bit segments"
+- default y
+ depends on MODIFY_LDT_SYSCALL
+ help
+ This option is required by programs like Wine to run 16-bit
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0018-stop-hiding-MODIFY_LDT_SYSCALL-behind-EXPERT.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0018-stop-hiding-MODIFY_LDT_SYSCALL-behind-EXPERT.patch
new file mode 100644
index 000000000000..1922a8338bf4
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0018-stop-hiding-MODIFY_LDT_SYSCALL-behind-EXPERT.patch
@@ -0,0 +1,25 @@
+From 9aad5f717e78e14e27f51daef922f86bb8ff3008 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Thu, 4 May 2017 18:15:52 -0400
+Subject: [PATCH 018/113] stop hiding MODIFY_LDT_SYSCALL behind EXPERT
+
+---
+ arch/x86/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
+index ab6e7e2d3cf0..7b9df510469b 100644
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -2392,7 +2392,7 @@ config CMDLINE_OVERRIDE
+ be set to 'N' under normal conditions.
+
+ config MODIFY_LDT_SYSCALL
+- bool "Enable the LDT (local descriptor table)" if EXPERT
++ bool "Enable the LDT (local descriptor table)"
+ default y
+ help
+ Linux can allow user programs to install a per-process x86
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0019-disable-MODIFY_LDT_SYSCALL-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0019-disable-MODIFY_LDT_SYSCALL-by-default.patch
new file mode 100644
index 000000000000..7f1d4061b693
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0019-disable-MODIFY_LDT_SYSCALL-by-default.patch
@@ -0,0 +1,26 @@
+From 62ab31d8233198ce7f059ef4aa7ad33b36b0bbe7 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Thu, 4 May 2017 18:16:16 -0400
+Subject: [PATCH 019/113] disable MODIFY_LDT_SYSCALL by default
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+Signed-off-by: Levente Polyak <levente@leventepolyak.net>
+---
+ arch/x86/Kconfig | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
+index 7b9df510469b..63e1e9fc18dd 100644
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -2393,7 +2393,6 @@ config CMDLINE_OVERRIDE
+
+ config MODIFY_LDT_SYSCALL
+ bool "Enable the LDT (local descriptor table)"
+- default y
+ help
+ Linux can allow user programs to install a per-process x86
+ Local Descriptor Table (LDT) using the modify_ldt(2) system
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0020-set-LEGACY_VSYSCALL_NONE-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0020-set-LEGACY_VSYSCALL_NONE-by-default.patch
new file mode 100644
index 000000000000..b36fe7105d80
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0020-set-LEGACY_VSYSCALL_NONE-by-default.patch
@@ -0,0 +1,25 @@
+From ac50dc84da87a3894df39d03be2747b57c749fad Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Mon, 29 May 2017 07:08:42 -0400
+Subject: [PATCH 020/113] set LEGACY_VSYSCALL_NONE by default
+
+---
+ arch/x86/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
+index 63e1e9fc18dd..4fd082de7420 100644
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -2296,7 +2296,7 @@ config COMPAT_VDSO
+ choice
+ prompt "vsyscall table for legacy applications"
+ depends on X86_64
+- default LEGACY_VSYSCALL_XONLY
++ 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
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0021-stop-hiding-AIO-behind-EXPERT.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0021-stop-hiding-AIO-behind-EXPERT.patch
new file mode 100644
index 000000000000..fbfc43d136ba
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0021-stop-hiding-AIO-behind-EXPERT.patch
@@ -0,0 +1,25 @@
+From c918ded1d65dce93c974c5b06a96664a9f88221e Mon Sep 17 00:00:00 2001
+From: Bernhard40 <32568352+Bernhard40@users.noreply.github.com>
+Date: Fri, 6 Oct 2017 10:21:50 +0000
+Subject: [PATCH 021/113] stop hiding AIO behind EXPERT
+
+---
+ init/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/init/Kconfig b/init/Kconfig
+index 74680a15ceb4..8605f3e78e47 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -1591,7 +1591,7 @@ config SHMEM
+ which may be appropriate on small systems without swap.
+
+ config AIO
+- bool "Enable AIO support" if EXPERT
++ bool "Enable AIO support"
+ default y
+ help
+ This option enables POSIX asynchronous I/O which may by used
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0022-disable-AIO-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0022-disable-AIO-by-default.patch
new file mode 100644
index 000000000000..05c3bee7b5ba
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0022-disable-AIO-by-default.patch
@@ -0,0 +1,24 @@
+From 756ecd7b6e3c0fb46d8bf89a2013327b27da668d Mon Sep 17 00:00:00 2001
+From: Bernhard40 <32568352+Bernhard40@users.noreply.github.com>
+Date: Fri, 6 Oct 2017 10:24:10 +0000
+Subject: [PATCH 022/113] disable AIO by default
+
+---
+ init/Kconfig | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/init/Kconfig b/init/Kconfig
+index 8605f3e78e47..21f0b6926cf3 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -1592,7 +1592,6 @@ config SHMEM
+
+ config AIO
+ bool "Enable AIO support"
+- default y
+ help
+ This option enables POSIX asynchronous I/O which may by used
+ by some high performance threaded applications. Disabling
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0023-remove-SYSVIPC-from-arm64-x86_64-defconfigs.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0023-remove-SYSVIPC-from-arm64-x86_64-defconfigs.patch
new file mode 100644
index 000000000000..fe358e24e5bb
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0023-remove-SYSVIPC-from-arm64-x86_64-defconfigs.patch
@@ -0,0 +1,32 @@
+From 97969c017205cbf4060c1786c521724a833f95f2 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Sun, 25 Feb 2018 02:08:49 -0500
+Subject: [PATCH 023/113] remove SYSVIPC from arm64/x86_64 defconfigs
+
+---
+ arch/arm64/configs/defconfig | 1 -
+ arch/x86/configs/x86_64_defconfig | 1 -
+ 2 files changed, 2 deletions(-)
+
+diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
+index 5cfe3cf6f2ac..f25871361bdc 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/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig
+index 9936528e1939..981ee8c0e330 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_AUDIT=y
+ CONFIG_NO_HZ=y
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0024-disable-DEVPORT-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0024-disable-DEVPORT-by-default.patch
new file mode 100644
index 000000000000..892cc5d4a63f
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0024-disable-DEVPORT-by-default.patch
@@ -0,0 +1,24 @@
+From 0b9b844d33431c8cc5ee572342fa783a144e2f9f Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Sat, 27 May 2017 07:28:10 -0400
+Subject: [PATCH 024/113] disable DEVPORT by default
+
+---
+ drivers/char/Kconfig | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
+index d229a2d0c017..68178c3a25de 100644
+--- a/drivers/char/Kconfig
++++ b/drivers/char/Kconfig
+@@ -391,7 +391,6 @@ config MAX_RAW_DEVS
+ 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.
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0025-disable-PROC_VMCORE-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0025-disable-PROC_VMCORE-by-default.patch
new file mode 100644
index 000000000000..79c6cb420f0f
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0025-disable-PROC_VMCORE-by-default.patch
@@ -0,0 +1,24 @@
+From 333c60e37e16b27149c5af06b91eddba8eae3e40 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Sat, 27 May 2017 07:29:45 -0400
+Subject: [PATCH 025/113] disable PROC_VMCORE by default
+
+---
+ fs/proc/Kconfig | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/fs/proc/Kconfig b/fs/proc/Kconfig
+index c930001056f9..6a0a51b3f593 100644
+--- a/fs/proc/Kconfig
++++ b/fs/proc/Kconfig
+@@ -41,7 +41,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.
+
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0026-disable-NFS_DEBUG-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0026-disable-NFS_DEBUG-by-default.patch
new file mode 100644
index 000000000000..dbf48be81e75
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0026-disable-NFS_DEBUG-by-default.patch
@@ -0,0 +1,24 @@
+From 957e4171bbb0432c97b10872c51e84fa121997ce Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Sun, 28 May 2017 03:03:46 -0400
+Subject: [PATCH 026/113] disable NFS_DEBUG by default
+
+---
+ fs/nfs/Kconfig | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig
+index e2a488d403a6..ce54c1c693a8 100644
+--- a/fs/nfs/Kconfig
++++ b/fs/nfs/Kconfig
+@@ -195,7 +195,6 @@ config NFS_DEBUG
+ bool
+ depends on NFS_FS && SUNRPC_DEBUG
+ select CRC32
+- default y
+
+ config NFS_DISABLE_UDP_SUPPORT
+ bool "NFS: Disable NFS UDP protocol support"
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0027-enable-DEBUG_WX-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0027-enable-DEBUG_WX-by-default.patch
new file mode 100644
index 000000000000..bc4c4099f7dd
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0027-enable-DEBUG_WX-by-default.patch
@@ -0,0 +1,25 @@
+From caea72027aca57069470dc5218ace236188b8f0b Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Mon, 29 May 2017 12:11:11 -0400
+Subject: [PATCH 027/113] enable DEBUG_WX by default
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ mm/Kconfig.debug | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/mm/Kconfig.debug b/mm/Kconfig.debug
+index 864f129f1937..929d585bd267 100644
+--- a/mm/Kconfig.debug
++++ b/mm/Kconfig.debug
+@@ -126,6 +126,7 @@ config DEBUG_WX
+ depends on ARCH_HAS_DEBUG_WX
+ depends on MMU
+ select PTDUMP_CORE
++ default y
+ help
+ Generate a warning if any W+X mappings are found at boot.
+
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0028-disable-LEGACY_PTYS-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0028-disable-LEGACY_PTYS-by-default.patch
new file mode 100644
index 000000000000..38e02cb2f77e
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0028-disable-LEGACY_PTYS-by-default.patch
@@ -0,0 +1,24 @@
+From c7a6d86985eda3812758d07f7c2ffc54b076478f Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Fri, 5 Jan 2018 13:21:16 -0500
+Subject: [PATCH 028/113] disable LEGACY_PTYS by default
+
+---
+ drivers/tty/Kconfig | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig
+index 93fd984eb2f5..d9086484d2de 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
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0029-disable-DEVMEM-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0029-disable-DEVMEM-by-default.patch
new file mode 100644
index 000000000000..29e9479fc76b
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0029-disable-DEVMEM-by-default.patch
@@ -0,0 +1,24 @@
+From bffed3709c1980aab2e55b2d8397e948b4a29762 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Fri, 5 Jan 2018 12:41:42 -0500
+Subject: [PATCH 029/113] disable DEVMEM by default
+
+---
+ drivers/char/Kconfig | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
+index 68178c3a25de..2fd45f01e7a2 100644
+--- a/drivers/char/Kconfig
++++ b/drivers/char/Kconfig
+@@ -327,7 +327,6 @@ config NSC_GPIO
+
+ 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
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0030-enable-IO_STRICT_DEVMEM-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0030-enable-IO_STRICT_DEVMEM-by-default.patch
new file mode 100644
index 000000000000..476697f069c6
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0030-enable-IO_STRICT_DEVMEM-by-default.patch
@@ -0,0 +1,24 @@
+From 8b568dd1513a5b69cd9d378868291c358c4a0b71 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Fri, 5 Jan 2018 12:43:49 -0500
+Subject: [PATCH 030/113] enable IO_STRICT_DEVMEM by default
+
+---
+ lib/Kconfig.debug | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
+index 45b169177fb9..a46f21a56125 100644
+--- a/lib/Kconfig.debug
++++ b/lib/Kconfig.debug
+@@ -1668,6 +1668,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
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0031-disable-COMPAT_BRK-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0031-disable-COMPAT_BRK-by-default.patch
new file mode 100644
index 000000000000..52e28d4db2b7
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0031-disable-COMPAT_BRK-by-default.patch
@@ -0,0 +1,24 @@
+From 48c45c757acdd747ab5b1c47100b0476b9b9869e Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Sun, 7 May 2017 18:28:33 -0400
+Subject: [PATCH 031/113] disable COMPAT_BRK by default
+
+---
+ init/Kconfig | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/init/Kconfig b/init/Kconfig
+index 21f0b6926cf3..4f5827e10be3 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -1866,7 +1866,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).
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0032-use-maximum-supported-mmap-rnd-entropy-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0032-use-maximum-supported-mmap-rnd-entropy-by-default.patch
new file mode 100644
index 000000000000..f931f28343e3
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0032-use-maximum-supported-mmap-rnd-entropy-by-default.patch
@@ -0,0 +1,35 @@
+From ff5211c87bb6c691cedcec47acbca66339d8e113 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Sun, 7 May 2017 16:16:39 -0400
+Subject: [PATCH 032/113] use maximum supported mmap rnd entropy by default
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ arch/Kconfig | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/Kconfig b/arch/Kconfig
+index 69fe7133c765..8b5c346d5dd8 100644
+--- a/arch/Kconfig
++++ b/arch/Kconfig
+@@ -752,7 +752,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
+@@ -786,7 +786,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
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0033-enable-protected_-symlinks-hardlinks-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0033-enable-protected_-symlinks-hardlinks-by-default.patch
new file mode 100644
index 000000000000..cdd2322e5d6a
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0033-enable-protected_-symlinks-hardlinks-by-default.patch
@@ -0,0 +1,27 @@
+From 81e0ac7582c94a0a3e95ca71dae0a3a832b54aa1 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Tue, 30 May 2017 10:47:23 -0400
+Subject: [PATCH 033/113] enable protected_{symlinks,hardlinks} by default
+
+---
+ fs/namei.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/fs/namei.c b/fs/namei.c
+index d4a6dd772303..59ff3ce21026 100644
+--- a/fs/namei.c
++++ b/fs/namei.c
+@@ -932,8 +932,8 @@ 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_symlinks __read_mostly = 1;
++int sysctl_protected_hardlinks __read_mostly = 1;
+ int sysctl_protected_fifos __read_mostly;
+ int sysctl_protected_regular __read_mostly;
+
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0034-enable-SECURITY-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0034-enable-SECURITY-by-default.patch
new file mode 100644
index 000000000000..9198fcc8b9d0
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0034-enable-SECURITY-by-default.patch
@@ -0,0 +1,24 @@
+From 4fee8ec7986f701856c13fc257b6a73ecf1adc1b Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Sun, 25 Feb 2018 02:13:48 -0500
+Subject: [PATCH 034/113] enable SECURITY by default
+
+---
+ security/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/security/Kconfig b/security/Kconfig
+index 3a2c68c7b50f..fa037a250821 100644
+--- a/security/Kconfig
++++ b/security/Kconfig
+@@ -23,6 +23,7 @@ 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.
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0035-enable-SECURITY_YAMA-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0035-enable-SECURITY_YAMA-by-default.patch
new file mode 100644
index 000000000000..dfe54cd72d5a
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0035-enable-SECURITY_YAMA-by-default.patch
@@ -0,0 +1,25 @@
+From c9064201bf14d83ccbd5e6fb674b106dc45117c7 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Mon, 29 May 2017 06:17:59 -0400
+Subject: [PATCH 035/113] enable SECURITY_YAMA by default
+
+---
+ security/yama/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/security/yama/Kconfig b/security/yama/Kconfig
+index a810304123ca..b809050b25d2 100644
+--- a/security/yama/Kconfig
++++ b/security/yama/Kconfig
+@@ -2,7 +2,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
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0036-enable-SECURITY_NETWORK-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0036-enable-SECURITY_NETWORK-by-default.patch
new file mode 100644
index 000000000000..20cb373b0412
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0036-enable-SECURITY_NETWORK-by-default.patch
@@ -0,0 +1,24 @@
+From c1bffc520a3493d1457463be0be28fca3c9d995b Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Sun, 25 Feb 2018 02:14:02 -0500
+Subject: [PATCH 036/113] enable SECURITY_NETWORK by default
+
+---
+ security/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/security/Kconfig b/security/Kconfig
+index fa037a250821..81d0a08736aa 100644
+--- a/security/Kconfig
++++ b/security/Kconfig
+@@ -49,6 +49,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
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0037-enable-AUDIT-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0037-enable-AUDIT-by-default.patch
new file mode 100644
index 000000000000..fb630a62b55d
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0037-enable-AUDIT-by-default.patch
@@ -0,0 +1,24 @@
+From 50995ff90f3b4c0646cf088cfa5bc32b7bea7554 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Sun, 25 Feb 2018 02:15:24 -0500
+Subject: [PATCH 037/113] enable AUDIT by default
+
+---
+ init/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/init/Kconfig b/init/Kconfig
+index 4f5827e10be3..9b75a4921575 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -419,6 +419,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
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0038-enable-SECURITY_SELINUX-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0038-enable-SECURITY_SELINUX-by-default.patch
new file mode 100644
index 000000000000..c45be54530b6
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0038-enable-SECURITY_SELINUX-by-default.patch
@@ -0,0 +1,25 @@
+From 3ba7070144172d142f4126950485ca597c6939a3 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Sun, 25 Feb 2018 02:16:49 -0500
+Subject: [PATCH 038/113] enable SECURITY_SELINUX by default
+
+---
+ security/selinux/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/security/selinux/Kconfig b/security/selinux/Kconfig
+index 9e921fc72538..76d7ed11513c 100644
+--- a/security/selinux/Kconfig
++++ b/security/selinux/Kconfig
+@@ -3,7 +3,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.
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0039-enable-SYN_COOKIES-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0039-enable-SYN_COOKIES-by-default.patch
new file mode 100644
index 000000000000..672a1ec5a491
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0039-enable-SYN_COOKIES-by-default.patch
@@ -0,0 +1,24 @@
+From 0a5d70a559e9754652239f57ca2aadb5b6585bfe Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Sat, 6 Jan 2018 13:41:11 -0500
+Subject: [PATCH 039/113] enable SYN_COOKIES by default
+
+---
+ net/ipv4/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
+index 87983e70f03f..989e005bf698 100644
+--- a/net/ipv4/Kconfig
++++ b/net/ipv4/Kconfig
+@@ -267,6 +267,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
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0040-enable-INIT_ON_ALLOC_DEFAULT_ON-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0040-enable-INIT_ON_ALLOC_DEFAULT_ON-by-default.patch
new file mode 100644
index 000000000000..df9832e31583
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0040-enable-INIT_ON_ALLOC_DEFAULT_ON-by-default.patch
@@ -0,0 +1,24 @@
+From 18f719b5161dddc75f318861005ff1e4a4ef2db7 Mon Sep 17 00:00:00 2001
+From: Levente Polyak <levente@leventepolyak.net>
+Date: Thu, 19 Sep 2019 19:02:23 +0200
+Subject: [PATCH 040/113] enable INIT_ON_ALLOC_DEFAULT_ON by default
+
+---
+ security/Kconfig.hardening | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/security/Kconfig.hardening b/security/Kconfig.hardening
+index 269967c4fc1b..1e279f6d7633 100644
+--- a/security/Kconfig.hardening
++++ b/security/Kconfig.hardening
+@@ -190,6 +190,7 @@ config STACKLEAK_RUNTIME_DISABLE
+
+ config INIT_ON_ALLOC_DEFAULT_ON
+ bool "Enable heap memory zeroing on allocation by default"
++ default yes
+ help
+ This has the effect of setting "init_on_alloc=1" on the kernel
+ command line. This can be disabled with "init_on_alloc=0".
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0041-enable-INIT_ON_FREE_DEFAULT_ON-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0041-enable-INIT_ON_FREE_DEFAULT_ON-by-default.patch
new file mode 100644
index 000000000000..4e982d9b4435
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0041-enable-INIT_ON_FREE_DEFAULT_ON-by-default.patch
@@ -0,0 +1,24 @@
+From 4f0609d264254471d8f2e8127d8b78bdca19624b Mon Sep 17 00:00:00 2001
+From: Levente Polyak <levente@leventepolyak.net>
+Date: Thu, 19 Sep 2019 19:03:01 +0200
+Subject: [PATCH 041/113] enable INIT_ON_FREE_DEFAULT_ON by default
+
+---
+ security/Kconfig.hardening | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/security/Kconfig.hardening b/security/Kconfig.hardening
+index 1e279f6d7633..2fa447823405 100644
+--- a/security/Kconfig.hardening
++++ b/security/Kconfig.hardening
+@@ -203,6 +203,7 @@ config INIT_ON_ALLOC_DEFAULT_ON
+
+ config INIT_ON_FREE_DEFAULT_ON
+ bool "Enable heap memory zeroing on free by default"
++ default yes
+ help
+ This has the effect of setting "init_on_free=1" on the kernel
+ command line. This can be disabled with "init_on_free=0".
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0042-kconfig-select-DEBUG_FS_ALLOW_NONE-by-default-if-DEB.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0042-kconfig-select-DEBUG_FS_ALLOW_NONE-by-default-if-DEB.patch
new file mode 100644
index 000000000000..5417d9c2c1ec
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0042-kconfig-select-DEBUG_FS_ALLOW_NONE-by-default-if-DEB.patch
@@ -0,0 +1,27 @@
+From b700b765dd26ebe26b35b301399942a244a921d3 Mon Sep 17 00:00:00 2001
+From: Levente Polyak <levente@leventepolyak.net>
+Date: Sun, 27 Sep 2020 00:43:48 +0200
+Subject: [PATCH 042/113] kconfig: select DEBUG_FS_ALLOW_NONE by default if
+ DEBUG_FS is enabled
+
+Signed-off-by: Levente Polyak <levente@leventepolyak.net>
+---
+ lib/Kconfig.debug | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
+index a46f21a56125..4a1a32a059f4 100644
+--- a/lib/Kconfig.debug
++++ b/lib/Kconfig.debug
+@@ -488,7 +488,7 @@ config DEBUG_FS
+ choice
+ prompt "Debugfs default access"
+ depends on DEBUG_FS
+- default DEBUG_FS_ALLOW_ALL
++ default DEBUG_FS_ALLOW_NONE
+ help
+ This selects the default access restrictions for debugfs.
+ It can be overridden with kernel command line option
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0043-stop-hiding-SYSFS_SYSCALL-behind-EXPERT.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0043-stop-hiding-SYSFS_SYSCALL-behind-EXPERT.patch
new file mode 100644
index 000000000000..0516071630e9
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0043-stop-hiding-SYSFS_SYSCALL-behind-EXPERT.patch
@@ -0,0 +1,25 @@
+From 6a7dfafae70e0305fc3d75f579386934276df8c8 Mon Sep 17 00:00:00 2001
+From: Levente Polyak <levente@leventepolyak.net>
+Date: Tue, 22 Dec 2020 23:35:53 +0100
+Subject: [PATCH 043/113] stop hiding SYSFS_SYSCALL behind EXPERT
+
+---
+ init/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/init/Kconfig b/init/Kconfig
+index 9b75a4921575..006d4d41e3af 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -1434,7 +1434,7 @@ config SGETMASK_SYSCALL
+ If unsure, leave the default option here.
+
+ config SYSFS_SYSCALL
+- bool "Sysfs syscall support" if EXPERT
++ bool "Sysfs syscall support"
+ default y
+ help
+ sys_sysfs is an obsolete system call no longer supported in libc.
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0044-disable-SYSFS_SYSCALL-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0044-disable-SYSFS_SYSCALL-by-default.patch
new file mode 100644
index 000000000000..fc26dc353954
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0044-disable-SYSFS_SYSCALL-by-default.patch
@@ -0,0 +1,31 @@
+From 96339bb02ae66fd7ed944364d2d2d60937fdc16a Mon Sep 17 00:00:00 2001
+From: Levente Polyak <levente@leventepolyak.net>
+Date: Tue, 22 Dec 2020 23:36:54 +0100
+Subject: [PATCH 044/113] disable SYSFS_SYSCALL by default
+
+---
+ init/Kconfig | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/init/Kconfig b/init/Kconfig
+index 006d4d41e3af..3d6b1b23e2db 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -1435,13 +1435,12 @@ config SGETMASK_SYSCALL
+
+ config SYSFS_SYSCALL
+ bool "Sysfs syscall support"
+- default y
+ help
+ sys_sysfs is an obsolete system call no longer supported in libc.
+ Note that disabling this option is more secure but might break
+ compatibility with some systems.
+
+- If unsure say Y here.
++ If unsure say N here.
+
+ config FHANDLE
+ bool "open by fhandle syscalls" if EXPERT
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0045-stop-hiding-UID16-behind-EXPERT.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0045-stop-hiding-UID16-behind-EXPERT.patch
new file mode 100644
index 000000000000..72da549d2c6e
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0045-stop-hiding-UID16-behind-EXPERT.patch
@@ -0,0 +1,25 @@
+From 784df6727e4ffa2e0eac2fa16cb35564abe3ffec Mon Sep 17 00:00:00 2001
+From: Levente Polyak <levente@leventepolyak.net>
+Date: Tue, 22 Dec 2020 23:40:09 +0100
+Subject: [PATCH 045/113] stop hiding UID16 behind EXPERT
+
+---
+ init/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/init/Kconfig b/init/Kconfig
+index 3d6b1b23e2db..2b6d0492def5 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -1403,7 +1403,7 @@ menuconfig EXPERT
+ Only use this if you really know what you are doing.
+
+ config UID16
+- bool "Enable 16-bit UID system calls" if EXPERT
++ bool "Enable 16-bit UID system calls"
+ depends on HAVE_UID16 && MULTIUSER
+ default y
+ help
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0046-disable-UID16-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0046-disable-UID16-by-default.patch
new file mode 100644
index 000000000000..aac19b55adb0
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0046-disable-UID16-by-default.patch
@@ -0,0 +1,24 @@
+From 9a68e972e38347a1927e8fbb22611c222a4cbb75 Mon Sep 17 00:00:00 2001
+From: Levente Polyak <levente@leventepolyak.net>
+Date: Tue, 22 Dec 2020 23:41:32 +0100
+Subject: [PATCH 046/113] disable UID16 by default
+
+---
+ init/Kconfig | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/init/Kconfig b/init/Kconfig
+index 2b6d0492def5..58df4930995f 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -1405,7 +1405,6 @@ menuconfig EXPERT
+ config UID16
+ bool "Enable 16-bit UID system calls"
+ depends on HAVE_UID16 && MULTIUSER
+- default y
+ help
+ This enables the legacy 16-bit UID syscall wrappers.
+
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0047-add-__read_only-for-non-init-related-usage.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0047-add-__read_only-for-non-init-related-usage.patch
new file mode 100644
index 000000000000..4a9800a8e873
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0047-add-__read_only-for-non-init-related-usage.patch
@@ -0,0 +1,25 @@
+From c5c4ff5a56e02bd16c034d568f9c60b876822ae4 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Sun, 7 May 2017 00:28:23 -0400
+Subject: [PATCH 047/113] add __read_only for non-init related usage
+
+---
+ include/linux/cache.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/include/linux/cache.h b/include/linux/cache.h
+index d742c57eaee5..f0222c070458 100644
+--- a/include/linux/cache.h
++++ b/include/linux/cache.h
+@@ -37,6 +37,8 @@
+ #define __ro_after_init __section(".data..ro_after_init")
+ #endif
+
++#define __read_only __ro_after_init
++
+ #ifndef ____cacheline_aligned
+ #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
+ #endif
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0048-make-sysctl-constants-read-only.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0048-make-sysctl-constants-read-only.patch
new file mode 100644
index 000000000000..b02bff45353b
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0048-make-sysctl-constants-read-only.patch
@@ -0,0 +1,108 @@
+From 2a61c23a99cf6547dab8335378dadfe41e7418cb Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Sun, 7 May 2017 00:43:03 -0400
+Subject: [PATCH 048/113] make sysctl constants read-only
+
+Most of this is extracted from the last publicly available version of
+the PaX patches where it's part of KERNEXEC as __read_only. It has been
+extended to a few more of these constants.
+---
+ kernel/sysctl.c | 54 ++++++++++++++++++++++++-------------------------
+ 1 file changed, 27 insertions(+), 27 deletions(-)
+
+diff --git a/kernel/sysctl.c b/kernel/sysctl.c
+index afad085960b8..b2cd3dbbb17a 100644
+--- a/kernel/sysctl.c
++++ b/kernel/sysctl.c
+@@ -108,33 +108,33 @@
+
+ /* Constants used for minimum and maximum */
+ #ifdef CONFIG_LOCKUP_DETECTOR
+-static int sixty = 60;
+-#endif
+-
+-static int __maybe_unused neg_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 two_hundred = 200;
+-static int one_thousand = 1000;
++static int sixty __read_only = 60;
++#endif
++
++static int __maybe_unused neg_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 two_hundred __read_only = 200;
++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;
+
+ /*
+@@ -142,7 +142,7 @@ 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
+
+ #ifdef CONFIG_INOTIFY_USER
+@@ -185,19 +185,19 @@ int sysctl_legacy_va_layout;
+ #endif
+
+ #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
+
+ #endif /* CONFIG_SYSCTL */
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0049-mark-kernel_set_to_readonly-as-__ro_after_init.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0049-mark-kernel_set_to_readonly-as-__ro_after_init.patch
new file mode 100644
index 000000000000..0254ae87e99c
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0049-mark-kernel_set_to_readonly-as-__ro_after_init.patch
@@ -0,0 +1,67 @@
+From 754920c103a3ab1c579a3241f16f0e74221cd94f Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Fri, 12 May 2017 03:22:00 -0400
+Subject: [PATCH 049/113] mark kernel_set_to_readonly as __ro_after_init
+
+This change was extracted from PaX where it's part of KERNEXEC.
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ arch/x86/mm/init_32.c | 5 ++---
+ arch/x86/mm/init_64.c | 5 ++---
+ 2 files changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
+index 7c055259de3a..77192cbc1dd7 100644
+--- a/arch/x86/mm/init_32.c
++++ b/arch/x86/mm/init_32.c
+@@ -828,7 +828,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;
+
+ static void mark_nxdata_nx(void)
+ {
+@@ -852,12 +852,11 @@ void mark_rodata_ro(void)
+ unsigned long start = PFN_ALIGN(_text);
+ unsigned long size = (unsigned long)__end_rodata - start;
+
++ kernel_set_to_readonly = 1;
+ set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT);
+ pr_info("Write protecting kernel text and read-only data: %luk\n",
+ size >> 10);
+
+- kernel_set_to_readonly = 1;
+-
+ #ifdef CONFIG_CPA_DEBUG
+ pr_info("Testing CPA: Reverting %lx-%lx\n", start, start + size);
+ set_pages_rw(virt_to_page(start), size >> PAGE_SHIFT);
+diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
+index b5a3fa4033d3..63a0f8097d0a 100644
+--- a/arch/x86/mm/init_64.c
++++ b/arch/x86/mm/init_64.c
+@@ -1322,7 +1322,7 @@ int __init deferred_page_init_max_threads(const struct cpumask *node_cpumask)
+ }
+ #endif
+
+-int kernel_set_to_readonly;
++int kernel_set_to_readonly __ro_after_init;
+
+ void mark_rodata_ro(void)
+ {
+@@ -1335,9 +1335,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!)
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0050-Revert-mark-kernel_set_to_readonly-as-__ro_after_ini.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0050-Revert-mark-kernel_set_to_readonly-as-__ro_after_ini.patch
new file mode 100644
index 000000000000..ab744a1e00d8
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0050-Revert-mark-kernel_set_to_readonly-as-__ro_after_ini.patch
@@ -0,0 +1,70 @@
+From 2405e1d6c15fc42cea726aad766b543ea50e6241 Mon Sep 17 00:00:00 2001
+From: Levente Polyak <levente@leventepolyak.net>
+Date: Sun, 13 Jan 2019 21:42:45 +0100
+Subject: [PATCH 050/113] Revert "mark kernel_set_to_readonly as
+ __ro_after_init"
+
+ This commit causes CPA conflicts, cf.
+ https://github.com/anthraxx/linux-hardened/issues/4.
+
+ Signed-off-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
+---
+ arch/x86/mm/init_32.c | 5 +++--
+ arch/x86/mm/init_64.c | 5 +++--
+ 2 files changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
+index 77192cbc1dd7..7c055259de3a 100644
+--- a/arch/x86/mm/init_32.c
++++ b/arch/x86/mm/init_32.c
+@@ -828,7 +828,7 @@ void arch_remove_memory(int nid, u64 start, u64 size,
+ }
+ #endif
+
+-int kernel_set_to_readonly __ro_after_init;
++int kernel_set_to_readonly __read_mostly;
+
+ static void mark_nxdata_nx(void)
+ {
+@@ -852,11 +852,12 @@ void mark_rodata_ro(void)
+ unsigned long start = PFN_ALIGN(_text);
+ unsigned long size = (unsigned long)__end_rodata - start;
+
+- kernel_set_to_readonly = 1;
+ set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT);
+ pr_info("Write protecting kernel text and read-only data: %luk\n",
+ size >> 10);
+
++ kernel_set_to_readonly = 1;
++
+ #ifdef CONFIG_CPA_DEBUG
+ pr_info("Testing CPA: Reverting %lx-%lx\n", start, start + size);
+ set_pages_rw(virt_to_page(start), size >> PAGE_SHIFT);
+diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
+index 63a0f8097d0a..b5a3fa4033d3 100644
+--- a/arch/x86/mm/init_64.c
++++ b/arch/x86/mm/init_64.c
+@@ -1322,7 +1322,7 @@ int __init deferred_page_init_max_threads(const struct cpumask *node_cpumask)
+ }
+ #endif
+
+-int kernel_set_to_readonly __ro_after_init;
++int kernel_set_to_readonly;
+
+ void mark_rodata_ro(void)
+ {
+@@ -1335,9 +1335,10 @@ void mark_rodata_ro(void)
+
+ printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n",
+ (end - start) >> 10);
+- kernel_set_to_readonly = 1;
+ set_memory_ro(start, (end - start) >> PAGE_SHIFT);
+
++ kernel_set_to_readonly = 1;
++
+ /*
+ * The rodata/data/bss/brk section (but not the kernel text!)
+ * should also be not-executable.
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0051-mark-slub-runtime-configuration-as-__ro_after_init.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0051-mark-slub-runtime-configuration-as-__ro_after_init.patch
new file mode 100644
index 000000000000..8714f3f736ed
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0051-mark-slub-runtime-configuration-as-__ro_after_init.patch
@@ -0,0 +1,57 @@
+From 959e911bb724b2b0fae06af0f70d87562347ac6e Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Sun, 14 May 2017 19:01:58 -0400
+Subject: [PATCH 051/113] mark slub runtime configuration as __ro_after_init
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ mm/slub.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/mm/slub.c b/mm/slub.c
+index 3f4303f4b657..7a8d4d37cffb 100644
+--- a/mm/slub.c
++++ b/mm/slub.c
+@@ -486,13 +486,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_string;
+-static int disable_higher_order_debug;
++static char *slub_debug_string __ro_after_init;
++static int disable_higher_order_debug __ro_after_init;
+
+ /*
+ * slub is about to manipulate internal object metadata. This memory lies
+@@ -3363,9 +3363,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.
+@@ -4883,7 +4883,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)
+ {
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0052-add-__ro_after_init-to-slab_nomerge-and-slab_state.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0052-add-__ro_after_init-to-slab_nomerge-and-slab_state.patch
new file mode 100644
index 000000000000..e511665a8393
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0052-add-__ro_after_init-to-slab_nomerge-and-slab_state.patch
@@ -0,0 +1,38 @@
+From 2ce9b3abeee44fe91a0d1a4b437d6b82b3ec5807 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Wed, 3 May 2017 11:35:35 -0400
+Subject: [PATCH 052/113] add __ro_after_init to slab_nomerge and slab_state
+
+This was extracted from the PaX patch where it's part of the KERNEXEC
+feature as __read_only.
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ mm/slab_common.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/mm/slab_common.c b/mm/slab_common.c
+index f9ccd5dc13f3..bff04048559f 100644
+--- a/mm/slab_common.c
++++ b/mm/slab_common.c
+@@ -30,7 +30,7 @@
+
+ #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;
+@@ -61,7 +61,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)
+ {
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0053-mark-kmem_cache-as-__ro_after_init.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0053-mark-kmem_cache-as-__ro_after_init.patch
new file mode 100644
index 000000000000..e68384a3eded
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0053-mark-kmem_cache-as-__ro_after_init.patch
@@ -0,0 +1,25 @@
+From f2da4d4a6b9a51404dbdedc96a31afc679aa4c76 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Sun, 28 May 2017 18:51:30 -0400
+Subject: [PATCH 053/113] mark kmem_cache as __ro_after_init
+
+---
+ mm/slab_common.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/mm/slab_common.c b/mm/slab_common.c
+index bff04048559f..2b73c12d8fce 100644
+--- a/mm/slab_common.c
++++ b/mm/slab_common.c
+@@ -33,7 +33,7 @@
+ 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 =
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0054-mark-__supported_pte_mask-as-__ro_after_init.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0054-mark-__supported_pte_mask-as-__ro_after_init.patch
new file mode 100644
index 000000000000..7c638945b1e7
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0054-mark-__supported_pte_mask-as-__ro_after_init.patch
@@ -0,0 +1,49 @@
+From 2ac41cc0030d5f7d390784265ae75f373d2f2b7b Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Fri, 12 May 2017 00:06:16 -0400
+Subject: [PATCH 054/113] mark __supported_pte_mask as __ro_after_init
+
+These changes were extracted from PaX where it was part of KERNEXEC as
+__read_only.
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ arch/x86/mm/init_32.c | 4 ++--
+ arch/x86/mm/init_64.c | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
+index 7c055259de3a..291b7b4476a9 100644
+--- a/arch/x86/mm/init_32.c
++++ b/arch/x86/mm/init_32.c
+@@ -546,9 +546,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);
+diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
+index b5a3fa4033d3..c3d771ffc178 100644
+--- a/arch/x86/mm/init_64.c
++++ b/arch/x86/mm/init_64.c
+@@ -97,9 +97,9 @@ DEFINE_ENTRY(pte, pte, init)
+ */
+
+ /* 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);
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0055-mark-kobj_ns_type_register-as-only-used-for-init.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0055-mark-kobj_ns_type_register-as-only-used-for-init.patch
new file mode 100644
index 000000000000..330bc26f13fa
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0055-mark-kobj_ns_type_register-as-only-used-for-init.patch
@@ -0,0 +1,45 @@
+From d53e0cfc0aefc1a7d0897c5724c61437b8ab01f6 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Tue, 4 Jul 2017 01:24:28 -0400
+Subject: [PATCH 055/113] mark kobj_ns_type_register as only used for init
+
+This allows kobj_ns_ops_tbl to be __ro_after_init.
+
+Extracted from PaX.
+---
+ include/linux/kobject_ns.h | 2 +-
+ lib/kobject.c | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/include/linux/kobject_ns.h b/include/linux/kobject_ns.h
+index 2b5b64256cf4..8cdce21dce0f 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/lib/kobject.c b/lib/kobject.c
+index ea53b30cf483..5343bbeea5f8 100644
+--- a/lib/kobject.c
++++ b/lib/kobject.c
+@@ -1023,9 +1023,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;
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0056-mark-open_softirq-as-only-used-for-init.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0056-mark-open_softirq-as-only-used-for-init.patch
new file mode 100644
index 000000000000..ed508d5f5d73
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0056-mark-open_softirq-as-only-used-for-init.patch
@@ -0,0 +1,39 @@
+From ff1b1e591088960b026c1dbba863260fd1bf5bcc Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Tue, 4 Jul 2017 01:32:30 -0400
+Subject: [PATCH 056/113] mark open_softirq as only used for init
+
+---
+ include/linux/interrupt.h | 2 +-
+ kernel/softirq.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
+index ee8299eb1f52..f03b78ae5f0a 100644
+--- a/include/linux/interrupt.h
++++ b/include/linux/interrupt.h
+@@ -569,7 +569,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)(struct softirq_action *));
+ extern void softirq_init(void);
+ extern void __raise_softirq_irqoff(unsigned int nr);
+
+diff --git a/kernel/softirq.c b/kernel/softirq.c
+index 09229ad82209..0595a8248c4a 100644
+--- a/kernel/softirq.c
++++ b/kernel/softirq.c
+@@ -486,7 +486,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)(struct softirq_action *))
+ {
+ softirq_vec[nr].action = action;
+ }
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0057-remove-unused-softirq_action-callback-parameter.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0057-remove-unused-softirq_action-callback-parameter.patch
new file mode 100644
index 000000000000..ca059d7d7591
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0057-remove-unused-softirq_action-callback-parameter.patch
@@ -0,0 +1,208 @@
+From 02a23dd9c7a518ccee1067f4fd7be7246075ddf3 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Tue, 4 Jul 2017 01:41:11 -0400
+Subject: [PATCH 057/113] remove unused softirq_action callback parameter
+
+Extracted from PaX.
+---
+ block/blk-mq.c | 2 +-
+ include/linux/interrupt.h | 4 ++--
+ kernel/rcu/tiny.c | 2 +-
+ kernel/rcu/tree.c | 2 +-
+ kernel/sched/fair.c | 2 +-
+ kernel/softirq.c | 15 +++++++--------
+ kernel/time/hrtimer.c | 2 +-
+ kernel/time/timer.c | 2 +-
+ lib/irq_poll.c | 2 +-
+ net/core/dev.c | 4 ++--
+ 10 files changed, 18 insertions(+), 19 deletions(-)
+
+diff --git a/block/blk-mq.c b/block/blk-mq.c
+index 2a1eff60c797..75a0077ea1a9 100644
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -569,7 +569,7 @@ EXPORT_SYMBOL(blk_mq_end_request);
+ * 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/include/linux/interrupt.h b/include/linux/interrupt.h
+index f03b78ae5f0a..4381b79f76cf 100644
+--- a/include/linux/interrupt.h
++++ b/include/linux/interrupt.h
+@@ -554,7 +554,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);
+@@ -569,7 +569,7 @@ static inline void do_softirq_own_stack(void)
+ }
+ #endif
+
+-extern void __init 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/kernel/rcu/tiny.c b/kernel/rcu/tiny.c
+index aa897c3f2e92..d8976886fd68 100644
+--- a/kernel/rcu/tiny.c
++++ b/kernel/rcu/tiny.c
+@@ -101,7 +101,7 @@ static inline bool rcu_reclaim_tiny(struct rcu_head *head)
+ }
+
+ /* Invoke the RCU callbacks whose grace period has elapsed. */
+-static __latent_entropy void rcu_process_callbacks(struct softirq_action *unused)
++static __latent_entropy void rcu_process_callbacks(void)
+ {
+ struct rcu_head *next, *list;
+ unsigned long flags;
+diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
+index 593df7edfe97..3285d81d8a26 100644
+--- a/kernel/rcu/tree.c
++++ b/kernel/rcu/tree.c
+@@ -2722,7 +2722,7 @@ static __latent_entropy void rcu_core(void)
+ queue_work_on(rdp->cpu, rcu_gp_wq, &rdp->strict_work);
+ }
+
+-static void rcu_core_si(struct softirq_action *h)
++static void rcu_core_si(void)
+ {
+ rcu_core();
+ }
+diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
+index ae7ceba8fd4f..d118be5f18b8 100644
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -10628,7 +10628,7 @@ static int newidle_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 0595a8248c4a..3a21b22227c1 100644
+--- a/kernel/softirq.c
++++ b/kernel/softirq.c
+@@ -295,7 +295,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",
+@@ -486,7 +486,7 @@ void __raise_softirq_irqoff(unsigned int nr)
+ or_softirq_pending(1UL << nr);
+ }
+
+-void __init open_softirq(int nr, void (*action)(struct softirq_action *))
++void __init open_softirq(int nr, void (*action)(void))
+ {
+ softirq_vec[nr].action = action;
+ }
+@@ -532,8 +532,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;
+@@ -573,14 +572,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_setup(struct tasklet_struct *t,
+diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
+index 387b4bef7dd1..8fe28c28a906 100644
+--- a/kernel/time/hrtimer.c
++++ b/kernel/time/hrtimer.c
+@@ -1587,7 +1587,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 c3ad64fb9d8b..217bc49a3856 100644
+--- a/kernel/time/timer.c
++++ b/kernel/time/timer.c
+@@ -1753,7 +1753,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/lib/irq_poll.c b/lib/irq_poll.c
+index 2f17b488d58e..b6e7996a0058 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/net/core/dev.c b/net/core/dev.c
+index 38412e70f761..c3cd49e04b7b 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -4856,7 +4856,7 @@ int netif_rx_any_context(struct sk_buff *skb)
+ }
+ EXPORT_SYMBOL(netif_rx_any_context);
+
+-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);
+
+@@ -6803,7 +6803,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 +
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0058-mark-softirq_vec-as-__ro_after_init.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0058-mark-softirq_vec-as-__ro_after_init.patch
new file mode 100644
index 000000000000..d7521ab21f83
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0058-mark-softirq_vec-as-__ro_after_init.patch
@@ -0,0 +1,28 @@
+From 5897eb27d1526693a60422b1fc35f227bab3f6de Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Tue, 4 Jul 2017 01:42:33 -0400
+Subject: [PATCH 058/113] mark softirq_vec as __ro_after_init
+
+Note: __cacheline_aligned_in_smp conflicts with __ro_after_init on x86.
+
+Extracted from PaX.
+---
+ kernel/softirq.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/softirq.c b/kernel/softirq.c
+index 3a21b22227c1..6a02d63b135a 100644
+--- a/kernel/softirq.c
++++ b/kernel/softirq.c
+@@ -52,7 +52,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);
+
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0059-mm-slab-trigger-BUG-if-requested-object-is-not-a-sla.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0059-mm-slab-trigger-BUG-if-requested-object-is-not-a-sla.patch
new file mode 100644
index 000000000000..a8566bf164b1
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0059-mm-slab-trigger-BUG-if-requested-object-is-not-a-sla.patch
@@ -0,0 +1,34 @@
+From 28200a5f9b0475dff1ae77082b8c93a0d54dd8b0 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Tue, 17 Sep 2019 18:00:54 +0200
+Subject: [PATCH 059/113] mm: slab: trigger BUG if requested object is not a
+ slab page
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+Signed-off-by: Levente Polyak <levente@leventepolyak.net>
+Signed-off-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
+---
+ mm/slab.h | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/mm/slab.h b/mm/slab.h
+index f9977d6613d6..5adb48bb2e68 100644
+--- a/mm/slab.h
++++ b/mm/slab.h
+@@ -435,9 +435,13 @@ static inline struct kmem_cache *virt_to_cache(const void *obj)
+ struct page *page;
+
+ page = virt_to_head_page(obj);
++#ifdef CONFIG_BUG_ON_DATA_CORRUPTION
++ BUG_ON(!PageSlab(page));
++#else
+ if (WARN_ONCE(!PageSlab(page), "%s: Object is not a Slab page!\n",
+ __func__))
+ return NULL;
++#endif
+ return page->slab_cache;
+ }
+
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0060-bug-on-kmem_cache_free-with-the-wrong-cache.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0060-bug-on-kmem_cache_free-with-the-wrong-cache.patch
new file mode 100644
index 000000000000..620f5cad9ede
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0060-bug-on-kmem_cache_free-with-the-wrong-cache.patch
@@ -0,0 +1,40 @@
+From c2b5b02ca3a38a17b536a74e4b1530fbdd669164 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Wed, 3 May 2017 11:50:53 -0400
+Subject: [PATCH 060/113] bug on kmem_cache_free with the wrong cache
+
+At least when CONFIG_BUG_ON_DATA_CORRUPTION is enabled.
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+Signed-off-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
+Signed-off-by: Levente Polyak <levente@leventepolyak.net>
+---
+ mm/slab.h | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/mm/slab.h b/mm/slab.h
+index 5adb48bb2e68..9fef4285514a 100644
+--- a/mm/slab.h
++++ b/mm/slab.h
+@@ -471,10 +471,15 @@ static inline struct kmem_cache *cache_from_obj(struct kmem_cache *s, void *x)
+ return s;
+
+ cachep = virt_to_cache(x);
+- if (WARN(cachep && cachep != s,
+- "%s: Wrong slab cache. %s but object is from %s\n",
+- __func__, s->name, cachep->name))
++ if (cachep && cachep != s) {
++#ifdef CONFIG_BUG_ON_DATA_CORRUPTION
++ BUG();
++#else
++ WARN(1, "%s: Wrong slab cache. %s but object is from %s\n",
++ __func__, s->name, cachep->name);
++#endif
+ print_tracking(cachep, x);
++ }
+ return cachep;
+ }
+
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0061-bug-on-PageSlab-PageCompound-in-ksize.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0061-bug-on-PageSlab-PageCompound-in-ksize.patch
new file mode 100644
index 000000000000..0a3cc38b1c4c
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0061-bug-on-PageSlab-PageCompound-in-ksize.patch
@@ -0,0 +1,31 @@
+From 4088d6038cb1378f391dd956e2e5431c95334781 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Wed, 3 May 2017 11:57:35 -0400
+Subject: [PATCH 061/113] bug on !PageSlab && !PageCompound in ksize
+
+At least when CONFIG_BUG_ON_DATA_CORRUPTION is enabled.
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ mm/slub.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/mm/slub.c b/mm/slub.c
+index 7a8d4d37cffb..391880ea7445 100644
+--- a/mm/slub.c
++++ b/mm/slub.c
+@@ -4092,7 +4092,11 @@ 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(page);
+ }
+
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0062-mm-add-support-for-verifying-page-sanitization.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0062-mm-add-support-for-verifying-page-sanitization.patch
new file mode 100644
index 000000000000..807950b20955
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0062-mm-add-support-for-verifying-page-sanitization.patch
@@ -0,0 +1,70 @@
+From 1e25cf9c966b3d9ad2045d8b24fff3626c4466c8 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Wed, 3 May 2017 21:54:56 -0400
+Subject: [PATCH 062/113] mm: add support for verifying page sanitization
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+Signed-off-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
+Signed-off-by: Levente Polyak <levente@leventepolyak.net>
+---
+ include/linux/highmem.h | 7 +++++++
+ mm/page_alloc.c | 6 ++++++
+ security/Kconfig.hardening | 7 +++++++
+ 3 files changed, 20 insertions(+)
+
+diff --git a/include/linux/highmem.h b/include/linux/highmem.h
+index 14e6202ce47f..4348ad7f5c50 100644
+--- a/include/linux/highmem.h
++++ b/include/linux/highmem.h
+@@ -284,6 +284,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/mm/page_alloc.c b/mm/page_alloc.c
+index 14b9e83ff9da..84070ae3885e 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -2284,6 +2284,12 @@ 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) && want_init_on_free()) {
++ int i;
++ for (i = 0; i < (1 << order); i++)
++ verify_zero_highpage(page + i);
++ }
++
+ if (!free_pages_prezeroed() && want_init_on_alloc(gfp_flags))
+ kernel_init_free_pages(page, 1 << order);
+
+diff --git a/security/Kconfig.hardening b/security/Kconfig.hardening
+index 2fa447823405..83ad70ae6bc3 100644
+--- a/security/Kconfig.hardening
++++ b/security/Kconfig.hardening
+@@ -219,6 +219,13 @@ config INIT_ON_FREE_DEFAULT_ON
+ touching "cold" memory areas. Most cases see 3-5% impact. Some
+ synthetic workloads have measured as high as 8%.
+
++config PAGE_SANITIZE_VERIFY
++ bool "Verify sanitized pages"
++ default y
++ help
++ When init_on_free is enabled, verify that newly allocated pages
++ are zeroed to detect write-after-free bugs.
++
+ endmenu
+
+ endmenu
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0063-slub-Extend-init_on_free-to-slab-caches-with-constru.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0063-slub-Extend-init_on_free-to-slab-caches-with-constru.patch
new file mode 100644
index 000000000000..b8d33136a582
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0063-slub-Extend-init_on_free-to-slab-caches-with-constru.patch
@@ -0,0 +1,75 @@
+From 985d592a0130e9256059ffab878e5b4048b60e9a Mon Sep 17 00:00:00 2001
+From: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
+Date: Fri, 20 Sep 2019 14:02:42 +0200
+Subject: [PATCH 063/113] slub: Extend init_on_free to slab caches with
+ constructors
+
+This is the remaining non-upstream part of SLAB_SANITIZE, which was a
+partial port, from Daniel Micay, of the feature from PaX without the
+default fast mode based on passing SLAB_NO_SANITIZE in
+performance-critical cases that are not particularly security sensitive.
+
+Signed-off-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
+---
+ mm/slab.h | 12 +++++++++---
+ mm/slub.c | 14 +++++++++++++-
+ 2 files changed, 22 insertions(+), 4 deletions(-)
+
+diff --git a/mm/slab.h b/mm/slab.h
+index 9fef4285514a..0fcd97a4eb6f 100644
+--- a/mm/slab.h
++++ b/mm/slab.h
+@@ -641,9 +641,15 @@ static inline bool slab_want_init_on_alloc(gfp_t flags, struct kmem_cache *c)
+
+ static inline bool slab_want_init_on_free(struct kmem_cache *c)
+ {
+- if (static_branch_unlikely(&init_on_free))
+- return !(c->ctor ||
+- (c->flags & (SLAB_TYPESAFE_BY_RCU | SLAB_POISON)));
++ if (static_branch_unlikely(&init_on_free)) {
++#ifndef CONFIG_SLUB
++ if (c->ctor)
++ return false;
++#endif
++ if (c->flags & (SLAB_TYPESAFE_BY_RCU | SLAB_POISON))
++ return false;
++ return true;
++ }
+ return false;
+ }
+
+diff --git a/mm/slub.c b/mm/slub.c
+index 391880ea7445..3c2c22488439 100644
+--- a/mm/slub.c
++++ b/mm/slub.c
+@@ -1571,7 +1571,8 @@ static inline bool slab_free_freelist_hook(struct kmem_cache *s,
+ : 0;
+ memset((char *)object + s->inuse, 0,
+ s->size - s->inuse - rsize);
+-
++ if (s->ctor)
++ s->ctor(object);
+ }
+ /* If object's reuse doesn't have to be delayed */
+ if (!slab_free_hook(s, object)) {
+@@ -1580,6 +1581,17 @@ static inline bool slab_free_freelist_hook(struct kmem_cache *s,
+ *head = object;
+ if (!*tail)
+ *tail = object;
++ } else if (slab_want_init_on_free(s) && s->ctor) {
++ /* Objects that are put into quarantine by KASAN will
++ * still undergo free_consistency_checks() and thus
++ * need to show a valid freepointer to check_object().
++ *
++ * Note that doing this for all caches (not just ctor
++ * ones, which have s->offset != NULL)) causes a GPF,
++ * due to KASAN poisoning and the way set_freepointer()
++ * eventually dereferences the freepointer.
++ */
++ set_freepointer(s, object, NULL);
+ }
+ } while (object != old_tail);
+
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0064-slub-Add-support-for-verifying-slab-sanitization.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0064-slub-Add-support-for-verifying-slab-sanitization.patch
new file mode 100644
index 000000000000..3cc95809cde1
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0064-slub-Add-support-for-verifying-slab-sanitization.patch
@@ -0,0 +1,116 @@
+From f362f6adb22cf03806adfd3994da8a21ddcbc597 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Thu, 4 May 2017 15:58:57 -0400
+Subject: [PATCH 064/113] slub: Add support for verifying slab sanitization
+
+This is an extension to the sanitization feature in PaX for when
+sacricifing more performance for security is acceptable.
+
+The initial version from Daniel Micay was relying on PAGE_SANITIZE. It
+now relies on upstream's init_on_free.
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+Signed-off-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
+Signed-off-by: Levente Polyak <levente@leventepolyak.net>
+---
+ mm/slub.c | 36 ++++++++++++++++++++++++++++++++----
+ security/Kconfig.hardening | 8 ++++++++
+ 2 files changed, 40 insertions(+), 4 deletions(-)
+
+diff --git a/mm/slub.c b/mm/slub.c
+index 3c2c22488439..d5427ead7d74 100644
+--- a/mm/slub.c
++++ b/mm/slub.c
+@@ -127,6 +127,12 @@ static inline bool kmem_cache_debug(struct kmem_cache *s)
+ return kmem_cache_debug_flags(s, SLAB_DEBUG_FLAGS);
+ }
+
++static inline bool has_sanitize_verify(struct kmem_cache *s)
++{
++ return IS_ENABLED(CONFIG_SLAB_SANITIZE_VERIFY) &&
++ slab_want_init_on_free(s);
++}
++
+ void *fixup_red_left(struct kmem_cache *s, void *p)
+ {
+ if (kmem_cache_debug_flags(s, SLAB_RED_ZONE))
+@@ -1571,7 +1577,7 @@ static inline bool slab_free_freelist_hook(struct kmem_cache *s,
+ : 0;
+ memset((char *)object + s->inuse, 0,
+ s->size - s->inuse - rsize);
+- if (s->ctor)
++ if (!IS_ENABLED(CONFIG_SLAB_SANITIZE_VERIFY) && s->ctor)
+ s->ctor(object);
+ }
+ /* If object's reuse doesn't have to be delayed */
+@@ -1606,7 +1612,7 @@ static void *setup_object(struct kmem_cache *s, struct page *page,
+ {
+ setup_object_debug(s, page, object);
+ object = 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);
+@@ -2897,7 +2903,16 @@ static __always_inline void *slab_alloc_node(struct kmem_cache *s,
+
+ maybe_wipe_obj_freeptr(s, object);
+
+- if (unlikely(slab_want_init_on_alloc(gfpflags, s)) && object)
++ if (has_sanitize_verify(s) && object) {
++ /* KASAN hasn't unpoisoned the object yet (this is done in the
++ * post-alloc hook), so let's do it temporarily.
++ */
++ kasan_unpoison_object_data(s, object);
++ BUG_ON(memchr_inv(object, 0, s->object_size));
++ if (s->ctor)
++ s->ctor(object);
++ kasan_poison_object_data(s, object);
++ } else if (unlikely(slab_want_init_on_alloc(gfpflags, s)) && object)
+ memset(object, 0, s->object_size);
+
+ slab_post_alloc_hook(s, objcg, gfpflags, 1, &object);
+@@ -3337,7 +3352,20 @@ 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(slab_want_init_on_alloc(flags, s))) {
++ if (has_sanitize_verify(s)) {
++ int j;
++
++ for (j = 0; j < i; j++) {
++ /* KASAN hasn't unpoisoned the object yet (this is done
++ * in the post-alloc hook), so let's do it temporarily.
++ */
++ kasan_unpoison_object_data(s, p[j]);
++ BUG_ON(memchr_inv(p[j], 0, s->object_size));
++ if (s->ctor)
++ s->ctor(p[j]);
++ kasan_poison_object_data(s, p[j]);
++ }
++ } else if (unlikely(slab_want_init_on_alloc(flags, s))) {
+ int j;
+
+ for (j = 0; j < i; j++)
+diff --git a/security/Kconfig.hardening b/security/Kconfig.hardening
+index 83ad70ae6bc3..7dede18f1074 100644
+--- a/security/Kconfig.hardening
++++ b/security/Kconfig.hardening
+@@ -226,6 +226,14 @@ config PAGE_SANITIZE_VERIFY
+ When init_on_free is enabled, verify that newly allocated pages
+ are zeroed to detect write-after-free bugs.
+
++config SLAB_SANITIZE_VERIFY
++ bool "Verify sanitized SLAB allocations"
++ default y
++ depends on !KASAN
++ help
++ When init_on_free is enabled, verify that newly allocated slab
++ objects are zeroed to detect write-after-free bugs.
++
+ endmenu
+
+ endmenu
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0065-slub-add-multi-purpose-random-canaries.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0065-slub-add-multi-purpose-random-canaries.patch
new file mode 100644
index 000000000000..14a729677948
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0065-slub-add-multi-purpose-random-canaries.patch
@@ -0,0 +1,264 @@
+From e14734f36f6835f5371fab894bfb445056bfa670 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Wed, 3 May 2017 16:16:58 -0400
+Subject: [PATCH 065/113] slub: add multi-purpose random canaries
+
+From the configuration option:
+
+ 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.
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ include/linux/slub_def.h | 5 +++
+ init/Kconfig | 17 ++++++++++
+ mm/slab.h | 2 +-
+ mm/slub.c | 69 ++++++++++++++++++++++++++++++++++++++--
+ 4 files changed, 89 insertions(+), 4 deletions(-)
+
+diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h
+index 1be0ed5befa1..c71cf30b5987 100644
+--- a/include/linux/slub_def.h
++++ b/include/linux/slub_def.h
+@@ -113,6 +113,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/init/Kconfig b/init/Kconfig
+index 58df4930995f..2af6689d9e71 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -1943,6 +1943,23 @@ config SLAB_FREELIST_HARDENED
+ sanity-checking than others. This option is most effective with
+ CONFIG_SLUB.
+
++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 SHUFFLE_PAGE_ALLOCATOR
+ bool "Page allocator randomization"
+ default SLAB_FREELIST_RANDOM && ACPI_NUMA
+diff --git a/mm/slab.h b/mm/slab.h
+index 0fcd97a4eb6f..105dba485a7e 100644
+--- a/mm/slab.h
++++ b/mm/slab.h
+@@ -504,7 +504,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/slub.c b/mm/slub.c
+index d5427ead7d74..a06d34be763a 100644
+--- a/mm/slub.c
++++ b/mm/slub.c
+@@ -569,6 +569,33 @@ static inline unsigned int get_info_end(struct kmem_cache *s)
+ return s->inuse;
+ }
+
++#ifdef CONFIG_SLAB_CANARY
++static inline unsigned long *get_canary(struct kmem_cache *s, void *object)
++{
++ return object + get_info_end(s);
++}
++
++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
++
+ static struct track *get_track(struct kmem_cache *s, void *object,
+ enum track_item alloc)
+ {
+@@ -576,6 +603,9 @@ static struct track *get_track(struct kmem_cache *s, void *object,
+
+ p = object + get_info_end(s);
+
++ if (IS_ENABLED(CONFIG_SLAB_CANARY))
++ p = (void *)p + sizeof(void *);
++
+ return p + alloc;
+ }
+
+@@ -717,6 +747,9 @@ static void print_trailer(struct kmem_cache *s, struct page *page, u8 *p)
+
+ off = get_info_end(s);
+
++ if (IS_ENABLED(CONFIG_SLAB_CANARY))
++ off += sizeof(void *);
++
+ if (s->flags & SLAB_STORE_USER)
+ off += 2 * sizeof(struct track);
+
+@@ -825,8 +858,9 @@ static int check_bytes_and_report(struct kmem_cache *s, struct page *page,
+ * Meta data starts here.
+ *
+ * A. Free pointer (if we cannot overwrite object on free)
+- * B. Tracking data for SLAB_STORE_USER
+- * C. Padding to reach required alignment boundary or at mininum
++ * B. Canary for SLAB_CANARY
++ * C. Tracking data for SLAB_STORE_USER
++ * D. Padding to reach required alignment boundary or at mininum
+ * one word if debugging is on to be able to detect writes
+ * before the word boundary.
+ *
+@@ -844,6 +878,9 @@ static int check_pad_bytes(struct kmem_cache *s, struct page *page, u8 *p)
+ {
+ unsigned long off = get_info_end(s); /* The end of info */
+
++ 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);
+@@ -1567,6 +1604,8 @@ static inline bool slab_free_freelist_hook(struct kmem_cache *s,
+ object = next;
+ next = get_freepointer(s, object);
+
++ check_canary(s, object, s->random_active);
++
+ if (slab_want_init_on_free(s)) {
+ /*
+ * Clear the object and the metadata, but don't touch
+@@ -1580,6 +1619,9 @@ static inline bool slab_free_freelist_hook(struct kmem_cache *s,
+ if (!IS_ENABLED(CONFIG_SLAB_SANITIZE_VERIFY) && s->ctor)
+ s->ctor(object);
+ }
++
++ set_canary(s, object, s->random_inactive);
++
+ /* If object's reuse doesn't have to be delayed */
+ if (!slab_free_hook(s, object)) {
+ /* Move object to the new freelist */
+@@ -1611,6 +1653,7 @@ 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);
+ object = kasan_init_slab_obj(s, object);
+ if (unlikely(s->ctor) && !has_sanitize_verify(s)) {
+ kasan_unpoison_object_data(s, object);
+@@ -2915,6 +2958,11 @@ static __always_inline void *slab_alloc_node(struct kmem_cache *s,
+ } else if (unlikely(slab_want_init_on_alloc(gfpflags, s)) && 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, objcg, gfpflags, 1, &object);
+
+ return object;
+@@ -3302,7 +3350,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;
+ struct obj_cgroup *objcg = NULL;
+
+ /* memcg and kmem_cache debug support */
+@@ -3372,6 +3420,11 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size,
+ 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, objcg, flags, size, p);
+ return i;
+@@ -3573,6 +3626,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);
+ n = kasan_kmalloc(kmem_cache_node, n, sizeof(struct kmem_cache_node),
+ GFP_KERNEL);
+ page->freelist = get_freepointer(kmem_cache_node, n);
+@@ -3753,6 +3807,9 @@ static int calculate_sizes(struct kmem_cache *s, int forced_order)
+ s->offset = ALIGN(freepointer_area / 2, sizeof(void *));
+ }
+
++ if (IS_ENABLED(CONFIG_SLAB_CANARY))
++ size += sizeof(void *);
++
+ #ifdef CONFIG_SLUB_DEBUG
+ if (flags & SLAB_STORE_USER)
+ /*
+@@ -3826,6 +3883,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;
+@@ -4099,6 +4160,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 &&
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0066-security-perf-Allow-further-restriction-of-perf_even.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0066-security-perf-Allow-further-restriction-of-perf_even.patch
new file mode 100644
index 000000000000..b21bf0ca48b9
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0066-security-perf-Allow-further-restriction-of-perf_even.patch
@@ -0,0 +1,122 @@
+From 4448c1ad8e8ba581e5cde9343479c9140c370f40 Mon Sep 17 00:00:00 2001
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Mon, 11 Jan 2016 15:23:55 +0000
+Subject: [PATCH 066/113] security,perf: Allow further restriction of
+ perf_event_open
+
+When kernel.perf_event_open is set to 3 (or greater), disallow all
+access to performance events by users without CAP_SYS_ADMIN.
+Add a Kconfig symbol CONFIG_SECURITY_PERF_EVENTS_RESTRICT that
+makes this value the default.
+
+This is based on a similar feature in grsecurity
+(CONFIG_GRKERNSEC_PERF_HARDEN). This version doesn't include making
+the variable read-only. It also allows enabling further restriction
+at run-time regardless of whether the default is changed.
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Levente Polyak <levente@leventepolyak.net>
+[thibaut.sautereau@ssi.gouv.fr: Adapt to work with the new CAP_PERFMON capability]
+Signed-off-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
+---
+ Documentation/admin-guide/sysctl/kernel.rst | 2 ++
+ include/linux/perf_event.h | 8 ++++++++
+ kernel/events/core.c | 7 ++++++-
+ security/Kconfig | 9 +++++++++
+ tools/perf/Documentation/security.txt | 1 +
+ 5 files changed, 26 insertions(+), 1 deletion(-)
+
+diff --git a/Documentation/admin-guide/sysctl/kernel.rst b/Documentation/admin-guide/sysctl/kernel.rst
+index d4b32cc32bb7..4c20e6ded0af 100644
+--- a/Documentation/admin-guide/sysctl/kernel.rst
++++ b/Documentation/admin-guide/sysctl/kernel.rst
+@@ -860,6 +860,8 @@ with respect to CAP_PERFMON use cases.
+ >=1 Disallow CPU event access by users without ``CAP_PERFMON``.
+
+ >=2 Disallow kernel profiling by users without ``CAP_PERFMON``.
++
++>=3 Disallow use of any event by users without ``CAP_PERFMON``.
+ === ==================================================================
+
+
+diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
+index 96450f6fb1de..d020c26b612a 100644
+--- a/include/linux/perf_event.h
++++ b/include/linux/perf_event.h
+@@ -1312,6 +1312,14 @@ static inline int perf_is_paranoid(void)
+ return sysctl_perf_event_paranoid > -1;
+ }
+
++static inline int perf_allow_open(struct perf_event_attr *attr)
++{
++ if (sysctl_perf_event_paranoid > 2 && !perfmon_capable())
++ return -EACCES;
++
++ return security_perf_event_open(attr, PERF_SECURITY_OPEN);
++}
++
+ static inline int perf_allow_kernel(struct perf_event_attr *attr)
+ {
+ if (sysctl_perf_event_paranoid > 1 && !perfmon_capable())
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index c3ba29d058b7..6efbf92763b1 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -407,8 +407,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 */
+@@ -11638,7 +11643,7 @@ SYSCALL_DEFINE5(perf_event_open,
+ return -EINVAL;
+
+ /* Do we allow access to perf_event_open(2) ? */
+- err = security_perf_event_open(&attr, PERF_SECURITY_OPEN);
++ err = perf_allow_open(&attr);
+ if (err)
+ return err;
+
+diff --git a/security/Kconfig b/security/Kconfig
+index 81d0a08736aa..c797326308f1 100644
+--- a/security/Kconfig
++++ b/security/Kconfig
+@@ -19,6 +19,15 @@ 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
++ 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
+ bool "Enable different security models"
+ depends on SYSFS
+diff --git a/tools/perf/Documentation/security.txt b/tools/perf/Documentation/security.txt
+index 4fe3b8b1958f..a7d88cc23a70 100644
+--- a/tools/perf/Documentation/security.txt
++++ b/tools/perf/Documentation/security.txt
+@@ -148,6 +148,7 @@ Perf tool provides a message similar to the one below:
+ >= 0: Disallow raw and ftrace function tracepoint access
+ >= 1: Disallow CPU event access
+ >= 2: Disallow kernel profiling
++ >= 3: Disallow use of any event
+ To make the adjusted perf_event_paranoid setting permanent preserve it
+ in /etc/sysctl.conf (e.g. kernel.perf_event_paranoid = <setting>)
+
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0067-enable-SECURITY_PERF_EVENTS_RESTRICT-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0067-enable-SECURITY_PERF_EVENTS_RESTRICT-by-default.patch
new file mode 100644
index 000000000000..dd345e6b4081
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0067-enable-SECURITY_PERF_EVENTS_RESTRICT-by-default.patch
@@ -0,0 +1,25 @@
+From 7fe66b1e27064b49bcc1e4c0e96ab13698346f73 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Thu, 4 May 2017 14:45:59 -0400
+Subject: [PATCH 067/113] enable SECURITY_PERF_EVENTS_RESTRICT by default
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ security/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/security/Kconfig b/security/Kconfig
+index c797326308f1..2348ff7d4e1d 100644
+--- a/security/Kconfig
++++ b/security/Kconfig
+@@ -22,6 +22,7 @@ config SECURITY_DMESG_RESTRICT
+ 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
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0068-add-sysctl-to-disallow-unprivileged-CLONE_NEWUSER-by.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0068-add-sysctl-to-disallow-unprivileged-CLONE_NEWUSER-by.patch
new file mode 100644
index 000000000000..e7710605ba1a
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0068-add-sysctl-to-disallow-unprivileged-CLONE_NEWUSER-by.patch
@@ -0,0 +1,124 @@
+From bbe1a03db5c12911149ce15253f622196fc95612 Mon Sep 17 00:00:00 2001
+From: Serge Hallyn <serge.hallyn@canonical.com>
+Date: Fri, 31 May 2013 19:12:12 +0100
+Subject: [PATCH 068/113] add sysctl to disallow unprivileged CLONE_NEWUSER by
+ default
+
+Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
+[bwh: Remove unneeded binary sysctl bits]
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+[thibaut.sautereau@ssi.gouv.fr: Adapt to sysctl code refactoring]
+Signed-off-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
+Signed-off-by: Levente Polyak <levente@leventepolyak.net>
+---
+ include/linux/user_namespace.h | 4 ++++
+ kernel/fork.c | 11 +++++++++++
+ kernel/sysctl.c | 12 ++++++++++++
+ kernel/user_namespace.c | 3 +++
+ 4 files changed, 30 insertions(+)
+
+diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
+index 6ef1c7109fc4..2140091b0b8d 100644
+--- a/include/linux/user_namespace.h
++++ b/include/linux/user_namespace.h
+@@ -106,6 +106,8 @@ void dec_ucount(struct ucounts *ucounts, enum ucount_type type);
+
+ #ifdef CONFIG_USER_NS
+
++extern int unprivileged_userns_clone;
++
+ static inline struct user_namespace *get_user_ns(struct user_namespace *ns)
+ {
+ if (ns)
+@@ -139,6 +141,8 @@ extern bool current_in_userns(const struct user_namespace *target_ns);
+ struct ns_common *ns_get_owner(struct ns_common *ns);
+ #else
+
++#define unprivileged_userns_clone 0
++
+ static inline struct user_namespace *get_user_ns(struct user_namespace *ns)
+ {
+ return &init_user_ns;
+diff --git a/kernel/fork.c b/kernel/fork.c
+index c675fdbd3dce..cba344194fba 100644
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -82,6 +82,7 @@
+ #include <linux/perf_event.h>
+ #include <linux/posix-timers.h>
+ #include <linux/user-return-notifier.h>
++#include <linux/user_namespace.h>
+ #include <linux/oom.h>
+ #include <linux/khugepaged.h>
+ #include <linux/signalfd.h>
+@@ -1863,6 +1864,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.
+@@ -2928,6 +2933,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/sysctl.c b/kernel/sysctl.c
+index b2cd3dbbb17a..fccf24a08c8a 100644
+--- a/kernel/sysctl.c
++++ b/kernel/sysctl.c
+@@ -103,6 +103,9 @@
+ #ifdef CONFIG_LOCKUP_DETECTOR
+ #include <linux/nmi.h>
+ #endif
++#ifdef CONFIG_USER_NS
++#include <linux/user_namespace.h>
++#endif
+
+ #if defined(CONFIG_SYSCTL)
+
+@@ -1902,6 +1905,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",
+diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
+index e703d5d9cbe8..29a30cff5e60 100644
+--- a/kernel/user_namespace.c
++++ b/kernel/user_namespace.c
+@@ -21,6 +21,9 @@
+ #include <linux/bsearch.h>
+ #include <linux/sort.h>
+
++/* sysctl */
++int unprivileged_userns_clone;
++
+ static struct kmem_cache *user_ns_cachep __read_mostly;
+ static DEFINE_MUTEX(userns_state_mutex);
+
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0069-add-CONFIG-for-unprivileged_userns_clone.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0069-add-CONFIG-for-unprivileged_userns_clone.patch
new file mode 100644
index 000000000000..bb7d710106cb
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0069-add-CONFIG-for-unprivileged_userns_clone.patch
@@ -0,0 +1,66 @@
+From e22af80c2327bdb0558e73c0e456904f2da1b95a Mon Sep 17 00:00:00 2001
+From: Levente Polyak <levente@leventepolyak.net>
+Date: Wed, 31 Jul 2019 20:50:48 +0100
+Subject: [PATCH 069/113] add CONFIG for unprivileged_userns_clone
+
+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.
+
+By default unprivileged user namespaces are disabled.
+
+Authored-by: Jan Alexander Steffens (heftig) <jan.steffens@gmail.com>
+Edited-by: Levente Polyak (anthraxx) <levente@leventepolyak.net>
+---
+ init/Kconfig | 16 ++++++++++++++++
+ kernel/user_namespace.c | 4 ++++
+ 2 files changed, 20 insertions(+)
+
+diff --git a/init/Kconfig b/init/Kconfig
+index 2af6689d9e71..a7b5a4cb7939 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -1174,6 +1174,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
+diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
+index 29a30cff5e60..5758274feaee 100644
+--- a/kernel/user_namespace.c
++++ b/kernel/user_namespace.c
+@@ -22,7 +22,11 @@
+ #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);
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0070-add-kmalloc-krealloc-alloc_size-attributes.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0070-add-kmalloc-krealloc-alloc_size-attributes.patch
new file mode 100644
index 000000000000..b2c09bb68f1c
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0070-add-kmalloc-krealloc-alloc_size-attributes.patch
@@ -0,0 +1,65 @@
+From 8e9daa30852f8a399d6a1c6de2d5bb6902a0b6f6 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Wed, 3 May 2017 12:02:56 -0400
+Subject: [PATCH 070/113] add kmalloc/krealloc alloc_size attributes
+
+Note that this is overly strict when combined with ksize users accessing
+beyond the requested data size.
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ include/linux/slab.h | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/include/linux/slab.h b/include/linux/slab.h
+index dd6897f62010..78f99835b91b 100644
+--- a/include/linux/slab.h
++++ b/include/linux/slab.h
+@@ -181,7 +181,7 @@ int kmem_cache_shrink(struct kmem_cache *);
+ /*
+ * 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) __attribute((alloc_size(2)));
+ void kfree(const void *);
+ void kfree_sensitive(const void *);
+ size_t __ksize(const void *);
+@@ -386,7 +386,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 *);
+
+@@ -410,7 +410,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)
+@@ -535,7 +535,7 @@ static __always_inline void *kmalloc_large(size_t size, gfp_t flags)
+ * Try really hard to succeed the allocation but fail
+ * eventually.
+ */
+-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)) {
+ #ifndef CONFIG_SLOB
+@@ -557,7 +557,7 @@ static __always_inline void *kmalloc(size_t size, gfp_t flags)
+ return __kmalloc(size, flags);
+ }
+
+-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) &&
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0071-add-vmalloc-alloc_size-attributes.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0071-add-vmalloc-alloc_size-attributes.patch
new file mode 100644
index 000000000000..4f0f9ed7d94d
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0071-add-vmalloc-alloc_size-attributes.patch
@@ -0,0 +1,47 @@
+From 95fa24be751c5fc7febc66ee3d36d67e5c0515db Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Wed, 3 May 2017 12:04:03 -0400
+Subject: [PATCH 071/113] add vmalloc alloc_size attributes
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+Signed-off-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
+Signed-off-by: Levente Polyak <levente@leventepolyak.net>
+---
+ include/linux/vmalloc.h | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
+index 938eaf9517e2..7c069063c20d 100644
+--- a/include/linux/vmalloc.h
++++ b/include/linux/vmalloc.h
+@@ -102,18 +102,18 @@ static inline void vmalloc_init(void)
+ static inline unsigned long vmalloc_nr_pages(void) { return 0; }
+ #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_32(unsigned long size);
+-extern void *vmalloc_32_user(unsigned long size);
+-extern void *__vmalloc(unsigned long size, gfp_t gfp_mask);
++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_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) __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)));
+ void *__vmalloc_node(unsigned long size, unsigned long align, gfp_t gfp_mask,
+ int node, const void *caller);
+
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0072-add-kvmalloc-alloc_size-attribute.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0072-add-kvmalloc-alloc_size-attribute.patch
new file mode 100644
index 000000000000..d157ea4b3bc5
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0072-add-kvmalloc-alloc_size-attribute.patch
@@ -0,0 +1,26 @@
+From f550e63d8cc9eec15dca68c8499df45ebacf4bcb Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Tue, 4 Jul 2017 00:51:33 -0400
+Subject: [PATCH 072/113] add kvmalloc alloc_size attribute
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ include/linux/mm.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/linux/mm.h b/include/linux/mm.h
+index cd5c313729ea..746f6d05bd81 100644
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -759,7 +759,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);
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0073-add-percpu-alloc_size-attributes.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0073-add-percpu-alloc_size-attributes.patch
new file mode 100644
index 000000000000..6612f8f70a48
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0073-add-percpu-alloc_size-attributes.patch
@@ -0,0 +1,37 @@
+From 8dae82a90632982a88a5e745858f2e10a1862319 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Sun, 14 May 2017 16:39:36 -0400
+Subject: [PATCH 073/113] add percpu alloc_size attributes
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ include/linux/percpu.h | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/include/linux/percpu.h b/include/linux/percpu.h
+index 5e76af742c80..9a6c682ec127 100644
+--- a/include/linux/percpu.h
++++ b/include/linux/percpu.h
+@@ -123,7 +123,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);
+
+@@ -131,8 +131,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);
+
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0074-add-alloc_pages_exact-alloc_size-attributes.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0074-add-alloc_pages_exact-alloc_size-attributes.patch
new file mode 100644
index 000000000000..10f484ee0ad4
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0074-add-alloc_pages_exact-alloc_size-attributes.patch
@@ -0,0 +1,30 @@
+From 2a79cb5f248d05bd79f440343a7b4e95c2a079b2 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Sun, 14 May 2017 16:53:59 -0400
+Subject: [PATCH 074/113] add alloc_pages_exact alloc_size attributes
+
+Edited-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ include/linux/gfp.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/include/linux/gfp.h b/include/linux/gfp.h
+index c603237e006c..893378b0262e 100644
+--- a/include/linux/gfp.h
++++ b/include/linux/gfp.h
+@@ -568,9 +568,9 @@ static inline struct page *alloc_pages(gfp_t gfp_mask, unsigned 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)
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0075-Add-the-extra_latent_entropy-kernel-parameter.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0075-Add-the-extra_latent_entropy-kernel-parameter.patch
new file mode 100644
index 000000000000..c8dc717493ed
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0075-Add-the-extra_latent_entropy-kernel-parameter.patch
@@ -0,0 +1,104 @@
+From c4f1400051880e1e85db4753894a5eaa37919a79 Mon Sep 17 00:00:00 2001
+From: Emese Revfy <re.emese@gmail.com>
+Date: Tue, 31 May 2016 01:34:02 +0200
+Subject: [PATCH 075/113] Add the extra_latent_entropy kernel parameter
+
+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.
+
+Based on work created by the PaX Team.
+
+Signed-off-by: Emese Revfy <re.emese@gmail.com>
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ .../admin-guide/kernel-parameters.txt | 5 ++++
+ mm/page_alloc.c | 25 +++++++++++++++++++
+ scripts/gcc-plugins/Kconfig | 5 ++++
+ 3 files changed, 35 insertions(+)
+
+diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
+index f6a1513dfb76..f399208c873a 100644
+--- a/Documentation/admin-guide/kernel-parameters.txt
++++ b/Documentation/admin-guide/kernel-parameters.txt
+@@ -3566,6 +3566,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/mm/page_alloc.c b/mm/page_alloc.c
+index 84070ae3885e..ded9e8536285 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -70,6 +70,7 @@
+ #include <linux/psi.h>
+ #include <linux/padata.h>
+ #include <linux/khugepaged.h>
++#include <linux/random.h>
+
+ #include <asm/sections.h>
+ #include <asm/tlbflush.h>
+@@ -136,6 +137,15 @@ struct pcpu_drain {
+ static DEFINE_MUTEX(pcpu_drain_mutex);
+ static DEFINE_PER_CPU(struct pcpu_drain, 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);
+@@ -1549,6 +1559,21 @@ void __free_pages_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
++ }
++
+ atomic_long_add(nr_pages, &page_zone(page)->managed_pages);
+
+ /*
+diff --git a/scripts/gcc-plugins/Kconfig b/scripts/gcc-plugins/Kconfig
+index ae19fb0243b9..ad78375ece5e 100644
+--- a/scripts/gcc-plugins/Kconfig
++++ b/scripts/gcc-plugins/Kconfig
+@@ -53,6 +53,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!
+
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0076-ata-avoid-null-pointer-dereference-on-bug.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0076-ata-avoid-null-pointer-dereference-on-bug.patch
new file mode 100644
index 000000000000..5d6d8b671d38
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0076-ata-avoid-null-pointer-dereference-on-bug.patch
@@ -0,0 +1,37 @@
+From 76d2e699fca89323e7f8318d3b84928c81e6ddd3 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Mon, 15 May 2017 23:45:34 -0400
+Subject: [PATCH 076/113] ata: avoid null pointer dereference on bug
+
+Extracted from PaX.
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ drivers/ata/libata-core.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
+index 61c762961ca8..02a83039c25b 100644
+--- a/drivers/ata/libata-core.c
++++ b/drivers/ata/libata-core.c
+@@ -4540,7 +4540,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;
+@@ -4557,7 +4557,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;
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0077-sanity-check-for-negative-length-in-nla_memcpy.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0077-sanity-check-for-negative-length-in-nla_memcpy.patch
new file mode 100644
index 000000000000..e0651a45c162
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0077-sanity-check-for-negative-length-in-nla_memcpy.patch
@@ -0,0 +1,28 @@
+From a1e40a045158cacd7edd2c5a1affbd5a32ee17ca Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Mon, 15 May 2017 23:51:12 -0400
+Subject: [PATCH 077/113] sanity check for negative length in nla_memcpy
+
+Extracted from PaX.
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ lib/nlattr.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/lib/nlattr.c b/lib/nlattr.c
+index 74019c8ebf6b..c480b4e7ffef 100644
+--- a/lib/nlattr.c
++++ b/lib/nlattr.c
+@@ -778,6 +778,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);
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0078-add-page-destructor-sanity-check.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0078-add-page-destructor-sanity-check.patch
new file mode 100644
index 000000000000..585d2db063c2
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0078-add-page-destructor-sanity-check.patch
@@ -0,0 +1,71 @@
+From 58595d383421defffcae5c0c1b75bfa05555db44 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Mon, 15 May 2017 23:59:18 -0400
+Subject: [PATCH 078/113] add page destructor sanity check
+
+Taken from the public PaX patches.
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+[thibaut.sautereau@ssi.gouv.fr: Restore get_compound_page_dtor()]
+Signed-off-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
+Reviewd-by: Levente Polyak <levente@leventepolyak.net>
+---
+ include/linux/mm.h | 9 +++++++--
+ mm/swap.c | 12 +++++++++++-
+ 2 files changed, 18 insertions(+), 3 deletions(-)
+
+diff --git a/include/linux/mm.h b/include/linux/mm.h
+index 746f6d05bd81..a463ffe84eb4 100644
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -894,10 +894,15 @@ static inline void set_compound_page_dtor(struct page *page,
+ page[1].compound_dtor = compound_dtor;
+ }
+
+-static inline void destroy_compound_page(struct page *page)
++static inline compound_page_dtor *get_compound_page_dtor(struct page *page)
+ {
+ VM_BUG_ON_PAGE(page[1].compound_dtor >= NR_COMPOUND_DTORS, page);
+- compound_page_dtors[page[1].compound_dtor](page);
++ return compound_page_dtors[page[1].compound_dtor];
++}
++
++static inline void destroy_compound_page(struct page *page)
++{
++ (*get_compound_page_dtor(page))(page);
+ }
+
+ static inline unsigned int compound_order(struct page *page)
+diff --git a/mm/swap.c b/mm/swap.c
+index 47a47681c86b..762095d95092 100644
+--- a/mm/swap.c
++++ b/mm/swap.c
+@@ -102,6 +102,8 @@ static void __put_single_page(struct page *page)
+
+ static void __put_compound_page(struct page *page)
+ {
++ compound_page_dtor *dtor;
++
+ /*
+ * __page_cache_release() is supposed to be called for thp, not for
+ * hugetlb. This is because hugetlb page does never have PageLRU set
+@@ -110,7 +112,15 @@ static void __put_compound_page(struct page *page)
+ */
+ if (!PageHuge(page))
+ __page_cache_release(page);
+- destroy_compound_page(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);
+ }
+
+ void __put_page(struct page *page)
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0079-PaX-shadow-cr4-sanity-check-essentially-a-revert.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0079-PaX-shadow-cr4-sanity-check-essentially-a-revert.patch
new file mode 100644
index 000000000000..1139bfcdee94
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0079-PaX-shadow-cr4-sanity-check-essentially-a-revert.patch
@@ -0,0 +1,52 @@
+From a1f711d5c9c22a3ecb704269ab0053fb87f20b6b Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Tue, 16 May 2017 00:59:48 -0400
+Subject: [PATCH 079/113] PaX shadow cr4 sanity check (essentially a revert)
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+Signed-off-by: Levente Polyak <levente@leventepolyak.net>
+---
+ arch/x86/kernel/cpu/common.c | 1 +
+ arch/x86/kernel/process.c | 1 +
+ arch/x86/mm/tlb.c | 1 +
+ 3 files changed, 3 insertions(+)
+
+diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
+index 35ad8480c464..edaeeab9df4b 100644
+--- a/arch/x86/kernel/cpu/common.c
++++ b/arch/x86/kernel/cpu/common.c
+@@ -399,6 +399,7 @@ EXPORT_SYMBOL_GPL(native_write_cr4);
+ void cr4_update_irqsoff(unsigned long set, unsigned long clear)
+ {
+ unsigned long newval, cr4 = this_cpu_read(cpu_tlbstate.cr4);
++ BUG_ON(cr4 != __read_cr4());
+
+ lockdep_assert_irqs_disabled();
+
+diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
+index 145a7ac0c19a..058941e9ae40 100644
+--- a/arch/x86/kernel/process.c
++++ b/arch/x86/kernel/process.c
+@@ -596,6 +596,7 @@ void speculation_ctrl_update_current(void)
+ static inline void cr4_toggle_bits_irqsoff(unsigned long mask)
+ {
+ unsigned long newval, cr4 = this_cpu_read(cpu_tlbstate.cr4);
++ BUG_ON(cr4 != __read_cr4());
+
+ newval = cr4 ^ mask;
+ if (newval != cr4) {
+diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
+index 569ac1d57f55..044d88da4aee 100644
+--- a/arch/x86/mm/tlb.c
++++ b/arch/x86/mm/tlb.c
+@@ -1066,6 +1066,7 @@ STATIC_NOPV 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 */
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0080-add-writable-function-pointer-detection.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0080-add-writable-function-pointer-detection.patch
new file mode 100644
index 000000000000..2e32f8a36092
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0080-add-writable-function-pointer-detection.patch
@@ -0,0 +1,98 @@
+From af9386b3db772d9d09972ca34530fd1a9d3d9ab1 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Sun, 9 Jul 2017 17:53:23 -0400
+Subject: [PATCH 080/113] add writable function pointer detection
+
+Taken from the public PaX patches.
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ scripts/mod/modpost.c | 28 +++++++++++++++++++++++++---
+ 1 file changed, 25 insertions(+), 3 deletions(-)
+
+diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
+index f882ce0d9327..50e9baefc4e7 100644
+--- a/scripts/mod/modpost.c
++++ b/scripts/mod/modpost.c
+@@ -34,6 +34,7 @@ static int external_module = 0;
+ 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_fatal = 0;
+ /* ignore missing files */
+ static int ignore_missing_files;
+@@ -1007,6 +1008,7 @@ enum mismatch {
+ ANY_EXIT_TO_ANY_INIT,
+ EXPORT_TO_INIT_EXIT,
+ EXTABLE_TO_NON_TEXT,
++ DATA_TO_TEXT
+ };
+
+ /**
+@@ -1133,6 +1135,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
+ }
+ };
+
+@@ -1320,10 +1328,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) {
+@@ -1458,7 +1466,10 @@ 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++;
+
+ get_pretty_name(from_is_func, &from, &from_p);
+ get_pretty_name(to_is_func, &to, &to_p);
+@@ -1580,6 +1591,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");
+ }
+@@ -2670,6 +2689,9 @@ int main(int argc, char **argv)
+ }
+
+ free(buf.p);
++ if (writable_fptr_count)
++ warn("modpost: Found %d writable function pointer(s).\n",
++ writable_fptr_count);
+
+ return err;
+ }
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0081-support-overriding-early-audit-kernel-cmdline.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0081-support-overriding-early-audit-kernel-cmdline.patch
new file mode 100644
index 000000000000..be8c63e3b291
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0081-support-overriding-early-audit-kernel-cmdline.patch
@@ -0,0 +1,26 @@
+From e69f0ae05bcdffc733a1ae6857ccfcdd3405bcf8 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Sun, 9 Jul 2017 17:20:29 -0400
+Subject: [PATCH 081/113] support overriding early audit kernel cmdline
+
+---
+ kernel/audit.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/kernel/audit.c b/kernel/audit.c
+index 68cee3bc8cfe..2059c66f7c9b 100644
+--- a/kernel/audit.c
++++ b/kernel/audit.c
+@@ -1693,6 +1693,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);
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0082-FORTIFY_SOURCE-intra-object-overflow-checking.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0082-FORTIFY_SOURCE-intra-object-overflow-checking.patch
new file mode 100644
index 000000000000..8417f43c08da
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0082-FORTIFY_SOURCE-intra-object-overflow-checking.patch
@@ -0,0 +1,135 @@
+From cd183c69bbc5c9815e04e78a1c9ab8de0985e706 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Sat, 3 Jun 2017 17:34:13 -0400
+Subject: [PATCH 082/113] FORTIFY_SOURCE intra-object overflow checking
+
+This adds supporting for detecting buffer overflows from inner objects
+for the fortified string family functions. It's comparable to the
+_FORTIFY_SOURCE=2 feature in glibc with the additional coverage of
+intra-object read overflows for supported functions.
+
+The mem* family functions are left with only the inter-object overflow
+checks as is the case with glibc _FORTIFY_SOURCE=2.
+
+This feature is currently hidden behind CONFIG_EXPERT because it's a lot
+more likely to uncover benign / intended issues and will need a lot of
+runtime testing. It's already useful for finding bugs but it may not yet
+be a good idea to use it for hardening unless panics for benign issues
+are seen as a lesser evil than the vulnerabilities it can catch.
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ include/linux/string.h | 26 ++++++++++++++++----------
+ security/Kconfig | 10 ++++++++++
+ 2 files changed, 26 insertions(+), 10 deletions(-)
+
+diff --git a/include/linux/string.h b/include/linux/string.h
+index b1f3894a0a3e..4c5564a6ad80 100644
+--- a/include/linux/string.h
++++ b/include/linux/string.h
+@@ -264,6 +264,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
+@@ -292,7 +298,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)
+@@ -302,7 +308,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)
+@@ -313,7 +319,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 ||
+@@ -328,7 +334,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__);
+@@ -340,8 +346,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);
+@@ -361,8 +367,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);
+@@ -475,8 +481,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/security/Kconfig b/security/Kconfig
+index 2348ff7d4e1d..f3c995bd79cf 100644
+--- a/security/Kconfig
++++ b/security/Kconfig
+@@ -208,6 +208,16 @@ config FORTIFY_SOURCE
+ 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 STATIC_USERMODEHELPER
+ bool "Force all usermode helper calls through a single binary"
+ help
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0083-Revert-mm-revert-x86_64-and-arm64-ELF_ET_DYN_BASE-ba.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0083-Revert-mm-revert-x86_64-and-arm64-ELF_ET_DYN_BASE-ba.patch
new file mode 100644
index 000000000000..25b46addd6cd
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0083-Revert-mm-revert-x86_64-and-arm64-ELF_ET_DYN_BASE-ba.patch
@@ -0,0 +1,54 @@
+From 076b37f37b0ff591c58f0d73ef6da6e79a3b3d1f Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Sat, 26 Aug 2017 20:16:03 -0400
+Subject: [PATCH 083/113] Revert "mm: revert x86_64 and arm64 ELF_ET_DYN_BASE
+ base changes"
+
+This reverts commit aab425db4279aeb83b7911693f0cccbd3644c9fd.
+---
+ arch/arm64/include/asm/elf.h | 8 ++------
+ arch/x86/include/asm/elf.h | 4 ++--
+ 2 files changed, 4 insertions(+), 8 deletions(-)
+
+diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
+index 8d1c8dcb87fd..26d27c7a2c2e 100644
+--- a/arch/arm64/include/asm/elf.h
++++ b/arch/arm64/include/asm/elf.h
+@@ -124,14 +124,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.
+ */
+-#ifdef CONFIG_ARM64_FORCE_52BIT
+-#define ELF_ET_DYN_BASE (2 * TASK_SIZE_64 / 3)
+-#else
+-#define ELF_ET_DYN_BASE (2 * DEFAULT_MAP_WINDOW_64 / 3)
+-#endif /* CONFIG_ARM64_FORCE_52BIT */
++#define ELF_ET_DYN_BASE 0x100000000UL
+
+ #ifndef __ASSEMBLY__
+
+diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
+index b9a5d488f1a5..b55054566ece 100644
+--- a/arch/x86/include/asm/elf.h
++++ b/arch/x86/include/asm/elf.h
+@@ -246,11 +246,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,
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0084-x86_64-move-vdso-to-mmap-region-from-stack-region.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0084-x86_64-move-vdso-to-mmap-region-from-stack-region.patch
new file mode 100644
index 000000000000..e42daa3bc863
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0084-x86_64-move-vdso-to-mmap-region-from-stack-region.patch
@@ -0,0 +1,118 @@
+From 02274e27e971f3bfd099ee7b938d0531dc7a1fca Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Thu, 11 May 2017 16:52:00 -0400
+Subject: [PATCH 084/113] x86_64: move vdso to mmap region from stack region
+
+This removes the only executable code from the stack region and gives
+the vdso the same randomized base as other mmap mappings including the
+linker and other shared objects. It results in a sane amount of entropy
+being provided and there's little to no advantage in separating this
+from the existing executable code there.
+
+It's sensible for userspace to reserve the initial mmap base as a region
+for executable code with a random gap for other mmap allocations, along
+with providing randomization within that region. However, there isn't
+much the kernel can do to help due to how dynamic linkers load the
+shared objects.
+
+This was extracted from the PaX RANDMMAP feature.
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ arch/x86/entry/vdso/vma.c | 48 +-----------------------------------
+ arch/x86/include/asm/elf.h | 1 -
+ arch/x86/kernel/sys_x86_64.c | 7 ------
+ 3 files changed, 1 insertion(+), 55 deletions(-)
+
+diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c
+index 9185cb1d13b9..543912071557 100644
+--- a/arch/x86/entry/vdso/vma.c
++++ b/arch/x86/entry/vdso/vma.c
+@@ -315,55 +315,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 b55054566ece..58292600112d 100644
+--- a/arch/x86/include/asm/elf.h
++++ b/arch/x86/include/asm/elf.h
+@@ -398,5 +398,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/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
+index 504fa5425bce..c4e35a3b3733 100644
+--- a/arch/x86/kernel/sys_x86_64.c
++++ b/arch/x86/kernel/sys_x86_64.c
+@@ -52,13 +52,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 */
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0085-x86-determine-stack-entropy-based-on-mmap-entropy.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0085-x86-determine-stack-entropy-based-on-mmap-entropy.patch
new file mode 100644
index 000000000000..510c352ac943
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0085-x86-determine-stack-entropy-based-on-mmap-entropy.patch
@@ -0,0 +1,60 @@
+From ad88f96ed3ec9394614f2a43a184158e838bbd2b Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Sun, 21 May 2017 20:30:44 -0400
+Subject: [PATCH 085/113] x86: determine stack entropy based on mmap entropy
+
+Stack mapping entropy is currently hard-wired to 11 bits of entropy on
+32-bit and 22 bits of entropy on 64-bit. The stack itself gains an extra
+8 bits of entropy from lower bit randomization within 16 byte alignment
+constraints. The argument block could have all lower bits randomized but
+it currently only gets the mapping randomization.
+
+Rather than hard-wiring values this switches to using the mmap entropy
+configuration like the mmap base and executable base, resulting in a
+range of 8 to 16 bits on 32-bit and 28 to 32 bits on 64-bit depending on
+kernel configuration and overridable via the sysctl entries.
+
+It's worth noting that since these kernel configuration options default
+to the minimum supported entropy value, the entropy on 32-bit will drop
+from 11 to 8 bits for builds using the defaults. However, following the
+configuration seems like the right thing to do regardless. At the very
+least, changing the defaults for COMPAT (32-bit processes on 64-bit)
+should be considered due to the larger address space compared to real
+32-bit.
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ arch/x86/include/asm/elf.h | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
+index 58292600112d..608cca19cf8c 100644
+--- a/arch/x86/include/asm/elf.h
++++ b/arch/x86/include/asm/elf.h
+@@ -330,8 +330,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
+
+@@ -340,7 +340,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 \
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0086-arm64-determine-stack-entropy-based-on-mmap-entropy.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0086-arm64-determine-stack-entropy-based-on-mmap-entropy.patch
new file mode 100644
index 000000000000..664cbb9d96dc
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0086-arm64-determine-stack-entropy-based-on-mmap-entropy.patch
@@ -0,0 +1,51 @@
+From b755a10376071bb32f3b0707c2c72aad777da3c9 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Mon, 22 May 2017 05:06:20 -0400
+Subject: [PATCH 086/113] arm64: determine stack entropy based on mmap entropy
+
+Stack mapping entropy is currently hard-wired to 11 bits of entropy on
+32-bit and 18 bits of entropy on 64-bit. The stack itself gains an extra
+8 bits of entropy from lower bit randomization within 16 byte alignment
+constraints. The argument block could have all lower bits randomized but
+it currently only gets the mapping randomization.
+
+Rather than hard-wiring values this switches to using the mmap entropy
+configuration like the mmap base and executable base, resulting in a
+range of 8 to 16 bits on 32-bit and 18 to 24 bits on 64-bit (with 4k
+pages and 3 level page tables) depending on kernel configuration and
+overridable via the sysctl entries.
+
+It's worth noting that since these kernel configuration options default
+to the minimum supported entropy value, the entropy on 32-bit will drop
+from 11 to 8 bits for builds using the defaults. However, following the
+configuration seems like the right thing to do regardless. At the very
+least, changing the defaults for COMPAT (32-bit processes on 64-bit)
+should be considered due to the larger address space compared to real
+32-bit.
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ arch/arm64/include/asm/elf.h | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
+index 26d27c7a2c2e..32c1609a1158 100644
+--- a/arch/arm64/include/asm/elf.h
++++ b/arch/arm64/include/asm/elf.h
+@@ -185,10 +185,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__
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0087-randomize-lower-bits-of-the-argument-block.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0087-randomize-lower-bits-of-the-argument-block.patch
new file mode 100644
index 000000000000..f6674fee0909
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0087-randomize-lower-bits-of-the-argument-block.patch
@@ -0,0 +1,47 @@
+From 45445659726dba25e10f19f31ee9d4fdaca6ba69 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Thu, 11 May 2017 16:02:49 -0400
+Subject: [PATCH 087/113] randomize lower bits of the argument block
+
+This was based on the PaX RANDUSTACK feature in grsecurity, where all of
+the lower bits are randomized. PaX keeps 16-byte alignment.
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+[levente@leventepolyak.net: do not randomize with ADDR_NO_RANDOMIZE personality]
+Signed-off-by: Levente Polyak <levente@leventepolyak.net>
+---
+ fs/exec.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/fs/exec.c b/fs/exec.c
+index ca89e0e3ef10..d2a03d32e195 100644
+--- a/fs/exec.c
++++ b/fs/exec.c
+@@ -34,6 +34,7 @@
+ #include <linux/swap.h>
+ #include <linux/string.h>
+ #include <linux/init.h>
++#include <linux/sched.h>
+ #include <linux/sched/mm.h>
+ #include <linux/sched/coredump.h>
+ #include <linux/sched/signal.h>
+@@ -64,6 +65,7 @@
+ #include <linux/compat.h>
+ #include <linux/vmalloc.h>
+ #include <linux/io_uring.h>
++#include <linux/random.h>
+
+ #include <linux/uaccess.h>
+ #include <asm/mmu_context.h>
+@@ -280,6 +282,8 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
+ mm->stack_vm = mm->total_vm = 1;
+ mmap_write_unlock(mm);
+ bprm->p = vma->vm_end - sizeof(void *);
++ if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
++ bprm->p ^= get_random_int() & ~PAGE_MASK;
+ return 0;
+ err:
+ mmap_write_unlock(mm);
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0088-x86_64-match-arm64-brk-randomization-entropy.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0088-x86_64-match-arm64-brk-randomization-entropy.patch
new file mode 100644
index 000000000000..34aaa04326f5
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0088-x86_64-match-arm64-brk-randomization-entropy.patch
@@ -0,0 +1,38 @@
+From 10bc4e5a26427743e381be6ced0732f5403e933a Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Tue, 30 May 2017 07:19:48 -0400
+Subject: [PATCH 088/113] x86_64: match arm64 brk randomization entropy
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ arch/x86/kernel/process.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
+index 058941e9ae40..61460d55dd72 100644
+--- a/arch/x86/kernel/process.c
++++ b/arch/x86/kernel/process.c
+@@ -43,6 +43,8 @@
+ #include <asm/io_bitmap.h>
+ #include <asm/proto.h>
+ #include <asm/frame.h>
++#include <asm/elf.h>
++#include <linux/sizes.h>
+
+ #include "process.h"
+
+@@ -906,7 +908,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 randomize_page(mm->brk, SZ_32M);
++ else
++ return randomize_page(mm->brk, SZ_1G);
+ }
+
+ /*
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0089-support-randomizing-the-lower-bits-of-brk.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0089-support-randomizing-the-lower-bits-of-brk.patch
new file mode 100644
index 000000000000..ddcaf2565baf
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0089-support-randomizing-the-lower-bits-of-brk.patch
@@ -0,0 +1,42 @@
+From faaa4cd5a2c92491cbb7c437b1d6e132e2aa0764 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Tue, 30 May 2017 18:03:30 -0400
+Subject: [PATCH 089/113] support randomizing the lower bits of brk
+
+This adds support for arch_randomize_brk implementations not performing
+page alignment in order to randomize the lower bits of the brk heap.
+
+This idea is taken from PaX but the approach is different. This reuses
+the existing code and avoids forcing early creation of the heap mapping,
+avoiding mapping it if it's not used which is the case with many modern
+allocators based solely on mmap.
+
+The malloc implementation can be relied upon to align this as needed to
+the requirements it has, so using 16 byte alignment here is unnecessary.
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ mm/mmap.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/mm/mmap.c b/mm/mmap.c
+index 5c8b4485860d..0e26c225bb53 100644
+--- a/mm/mmap.c
++++ b/mm/mmap.c
+@@ -231,6 +231,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) {
+ mm->brk = brk;
+ goto success;
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0090-mm-randomize-lower-bits-of-brk.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0090-mm-randomize-lower-bits-of-brk.patch
new file mode 100644
index 000000000000..317899e25acc
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0090-mm-randomize-lower-bits-of-brk.patch
@@ -0,0 +1,31 @@
+From 6d2ebb7e809172288d8e45412edf5424f38fc4a8 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Thu, 1 Jun 2017 03:22:38 -0400
+Subject: [PATCH 090/113] mm: randomize lower bits of brk
+
+Per PaX, but for this alternate brk randomization approach.
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ mm/util.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/mm/util.c b/mm/util.c
+index 4ddb6e186dd5..4ca72f952329 100644
+--- a/mm/util.c
++++ b/mm/util.c
+@@ -336,9 +336,9 @@ unsigned long arch_randomize_brk(struct mm_struct *mm)
+ {
+ /* Is the current task 32bit ? */
+ if (!IS_ENABLED(CONFIG_64BIT) || is_compat_task())
+- return randomize_page(mm->brk, SZ_32M);
++ return mm->brk + get_random_long() % SZ_32M;
+
+- return randomize_page(mm->brk, SZ_1G);
++ return mm->brk + get_random_long() % SZ_1G;
+ }
+
+ unsigned long arch_mmap_rnd(void)
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0091-x86-randomize-lower-bits-of-brk.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0091-x86-randomize-lower-bits-of-brk.patch
new file mode 100644
index 000000000000..15e58b0ce70a
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0091-x86-randomize-lower-bits-of-brk.patch
@@ -0,0 +1,31 @@
+From 6db87dd4450d75558fee95d84c6c7cef7481ef41 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Thu, 1 Jun 2017 03:23:06 -0400
+Subject: [PATCH 091/113] x86: randomize lower bits of brk
+
+Per PaX, but for this alternate brk randomization approach.
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ arch/x86/kernel/process.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
+index 61460d55dd72..0d4c3887229d 100644
+--- a/arch/x86/kernel/process.c
++++ b/arch/x86/kernel/process.c
+@@ -909,9 +909,9 @@ unsigned long arch_align_stack(unsigned long sp)
+ unsigned long arch_randomize_brk(struct mm_struct *mm)
+ {
+ if (mmap_is_ia32())
+- return randomize_page(mm->brk, SZ_32M);
++ return mm->brk + get_random_long() % SZ_32M;
+ else
+- return randomize_page(mm->brk, SZ_1G);
++ return mm->brk + get_random_long() % SZ_1G;
+ }
+
+ /*
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0092-mm-guarantee-brk-gap-is-at-least-one-page.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0092-mm-guarantee-brk-gap-is-at-least-one-page.patch
new file mode 100644
index 000000000000..f43463bd9ce3
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0092-mm-guarantee-brk-gap-is-at-least-one-page.patch
@@ -0,0 +1,31 @@
+From 48afdc21481c65eaa8b56238e0e983f0c2635e65 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Thu, 1 Jun 2017 03:23:39 -0400
+Subject: [PATCH 092/113] mm: guarantee brk gap is at least one page
+
+Per PaX, but for this alternate brk randomization approach.
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ mm/util.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/mm/util.c b/mm/util.c
+index 4ca72f952329..62ed34dfceb7 100644
+--- a/mm/util.c
++++ b/mm/util.c
+@@ -336,9 +336,9 @@ unsigned long arch_randomize_brk(struct mm_struct *mm)
+ {
+ /* Is the current task 32bit ? */
+ if (!IS_ENABLED(CONFIG_64BIT) || is_compat_task())
+- return mm->brk + get_random_long() % SZ_32M;
++ return mm->brk + get_random_long() % SZ_32M + PAGE_SIZE;
+
+- return mm->brk + get_random_long() % SZ_1G;
++ return mm->brk + get_random_long() % SZ_1G + PAGE_SIZE;
+ }
+
+ unsigned long arch_mmap_rnd(void)
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0093-x86-guarantee-brk-gap-is-at-least-one-page.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0093-x86-guarantee-brk-gap-is-at-least-one-page.patch
new file mode 100644
index 000000000000..6e2712a21c54
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0093-x86-guarantee-brk-gap-is-at-least-one-page.patch
@@ -0,0 +1,31 @@
+From 7a7856e97e9e0a8ca341107a8a9d593787687cd4 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Thu, 1 Jun 2017 03:23:48 -0400
+Subject: [PATCH 093/113] x86: guarantee brk gap is at least one page
+
+Per PaX, but for this alternate brk randomization approach.
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ arch/x86/kernel/process.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
+index 0d4c3887229d..161e25d02fd5 100644
+--- a/arch/x86/kernel/process.c
++++ b/arch/x86/kernel/process.c
+@@ -909,9 +909,9 @@ unsigned long arch_align_stack(unsigned long sp)
+ unsigned long arch_randomize_brk(struct mm_struct *mm)
+ {
+ if (mmap_is_ia32())
+- return mm->brk + get_random_long() % SZ_32M;
++ return mm->brk + get_random_long() % SZ_32M + PAGE_SIZE;
+ else
+- return mm->brk + get_random_long() % SZ_1G;
++ return mm->brk + get_random_long() % SZ_1G + PAGE_SIZE;
+ }
+
+ /*
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0094-x86_64-bound-mmap-between-legacy-modern-bases.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0094-x86_64-bound-mmap-between-legacy-modern-bases.patch
new file mode 100644
index 000000000000..0c4b52905e2f
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0094-x86_64-bound-mmap-between-legacy-modern-bases.patch
@@ -0,0 +1,37 @@
+From c30867dd77734d7b2b894878719358c026ee0d05 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Tue, 4 Jul 2017 14:50:54 -0400
+Subject: [PATCH 094/113] x86_64: bound mmap between legacy/modern bases
+
+---
+ arch/x86/kernel/sys_x86_64.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
+index c4e35a3b3733..e30ec4c750d1 100644
+--- a/arch/x86/kernel/sys_x86_64.c
++++ b/arch/x86/kernel/sys_x86_64.c
+@@ -113,10 +113,7 @@ static void find_start_end(unsigned long addr, unsigned long flags,
+ }
+
+ *begin = get_mmap_base(1);
+- if (in_32bit_syscall())
+- *end = task_size_32bit();
+- else
+- *end = task_size_64bit(addr > DEFAULT_MAP_WINDOW);
++ *end = get_mmap_base(0);
+ }
+
+ unsigned long
+@@ -193,7 +190,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);
+
+ /*
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0095-restrict-device-timing-side-channels.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0095-restrict-device-timing-side-channels.patch
new file mode 100644
index 000000000000..1de38f564c76
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0095-restrict-device-timing-side-channels.patch
@@ -0,0 +1,174 @@
+From 92277813dcd237bafd1ccf1eec8d4ed67d7144b8 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Tue, 16 May 2017 18:26:10 -0400
+Subject: [PATCH 095/113] restrict device timing side channels
+
+Based on the public grsecurity patches.
+
+Signed-off-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
+Signed-off-by: Levente Polyak <levente@leventepolyak.net>
+---
+ fs/inode.c | 4 ++++
+ fs/stat.c | 20 +++++++++++++++-----
+ include/linux/capability.h | 5 +++++
+ include/linux/fs.h | 11 +++++++++++
+ include/linux/fsnotify.h | 4 ++++
+ kernel/capability.c | 6 ++++++
+ kernel/sysctl.c | 9 +++++++++
+ 7 files changed, 54 insertions(+), 5 deletions(-)
+
+diff --git a/fs/inode.c b/fs/inode.c
+index 5eea9912a0b9..f86f383a3e1d 100644
+--- a/fs/inode.c
++++ b/fs/inode.c
+@@ -116,6 +116,10 @@ int proc_nr_inodes(struct ctl_table *table, int write,
+ }
+ #endif
+
++/* sysctl */
++int device_sidechannel_restrict __read_mostly = 1;
++EXPORT_SYMBOL(device_sidechannel_restrict);
++
+ static int no_open(struct inode *inode, struct file *file)
+ {
+ return -ENXIO;
+diff --git a/fs/stat.c b/fs/stat.c
+index dacecdda2e79..14173d0f777d 100644
+--- a/fs/stat.c
++++ b/fs/stat.c
+@@ -43,8 +43,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;
+@@ -83,9 +88,14 @@ int vfs_getattr_nosec(const struct path *path, struct kstat *stat,
+ if (IS_DAX(inode))
+ stat->attributes |= STATX_ATTR_DAX;
+
+- 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/include/linux/capability.h b/include/linux/capability.h
+index 1e7fe311cabe..a5b6d4c9acf5 100644
+--- a/include/linux/capability.h
++++ b/include/linux/capability.h
+@@ -208,6 +208,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);
+ extern bool ns_capable_setid(struct user_namespace *ns, int cap);
+@@ -234,6 +235,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 8bde32cf9711..83d50b0a2a18 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -3475,4 +3475,15 @@ static inline int inode_drain_writes(struct inode *inode)
+ return filemap_write_and_wait(inode->i_mapping);
+ }
+
++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 f8acddcf54fb..7b109980327f 100644
+--- a/include/linux/fsnotify.h
++++ b/include/linux/fsnotify.h
+@@ -83,10 +83,14 @@ static inline void fsnotify_dentry(struct dentry *dentry, __u32 mask)
+ static inline int fsnotify_file(struct file *file, __u32 mask)
+ {
+ const struct path *path = &file->f_path;
++ struct inode *inode = file_inode(file);
+
+ if (file->f_mode & FMODE_NONOTIFY)
+ return 0;
+
++ if (mask & (FS_ACCESS | FS_MODIFY) && is_sidechannel_device(inode))
++ return 0;
++
+ return fsnotify_parent(path->dentry, mask, path, FSNOTIFY_EVENT_PATH);
+ }
+
+diff --git a/kernel/capability.c b/kernel/capability.c
+index de7eac903a2a..5602178f3d21 100644
+--- a/kernel/capability.c
++++ b/kernel/capability.c
+@@ -449,6 +449,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/sysctl.c b/kernel/sysctl.c
+index fccf24a08c8a..7fda9f61ea1a 100644
+--- a/kernel/sysctl.c
++++ b/kernel/sysctl.c
+@@ -2272,6 +2272,15 @@ static struct ctl_table kern_table[] = {
+ .extra2 = &two,
+ },
+ #endif
++ {
++ .procname = "device_sidechannel_restrict",
++ .data = &device_sidechannel_restrict,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = proc_dointvec_minmax_sysadmin,
++ .extra1 = SYSCTL_ZERO,
++ .extra2 = SYSCTL_ONE,
++ },
+ {
+ .procname = "ngroups_max",
+ .data = &ngroups_max,
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0096-sysctl-expose-proc_dointvec_minmax_sysadmin-as-API-f.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0096-sysctl-expose-proc_dointvec_minmax_sysadmin-as-API-f.patch
new file mode 100644
index 000000000000..6b5657c5ab6c
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0096-sysctl-expose-proc_dointvec_minmax_sysadmin-as-API-f.patch
@@ -0,0 +1,95 @@
+From d3e518ec4d7ab8115d77a2305b5d50abba3a6808 Mon Sep 17 00:00:00 2001
+From: Levente Polyak <levente@leventepolyak.net>
+Date: Sun, 6 Sep 2020 20:28:32 +0200
+Subject: [PATCH 096/113] sysctl: expose proc_dointvec_minmax_sysadmin as API
+ function
+
+Orthogonal to the other sysctl proc functions expose the variant that is
+checking CAP_SYS_ADMIN on write for consumption in external subsystem's
+sysctl tables.
+
+Signed-off-by: Levente Polyak <levente@leventepolyak.net>
+---
+ include/linux/sysctl.h | 2 ++
+ kernel/sysctl.c | 31 ++++++++++++++++++++++++++++---
+ 2 files changed, 30 insertions(+), 3 deletions(-)
+
+diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
+index 51298a4f4623..b835c57330f2 100644
+--- a/include/linux/sysctl.h
++++ b/include/linux/sysctl.h
+@@ -53,6 +53,8 @@ int proc_douintvec(struct ctl_table *, int, void *, size_t *, loff_t *);
+ int proc_dointvec_minmax(struct ctl_table *, int, void *, size_t *, loff_t *);
+ int proc_douintvec_minmax(struct ctl_table *table, int write, void *buffer,
+ size_t *lenp, loff_t *ppos);
++int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write,
++ void *buffer, size_t *lenp, loff_t *ppos);
+ int proc_dointvec_jiffies(struct ctl_table *, int, void *, size_t *, loff_t *);
+ int proc_dointvec_userhz_jiffies(struct ctl_table *, int, void *, size_t *,
+ loff_t *);
+diff --git a/kernel/sysctl.c b/kernel/sysctl.c
+index 7fda9f61ea1a..13b619e46ade 100644
+--- a/kernel/sysctl.c
++++ b/kernel/sysctl.c
+@@ -890,8 +890,27 @@ static int proc_taint(struct ctl_table *table, int write,
+ return err;
+ }
+
+-#ifdef CONFIG_PRINTK
+-static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write,
++/**
++ * proc_dointvec_minmax_sysadmin - read a vector of integers with min/max values
++ * checking CAP_SYS_ADMIN on write
++ * @table: the sysctl table
++ * @write: %TRUE if this is a write to the sysctl file
++ * @buffer: the user buffer
++ * @lenp: the size of the user buffer
++ * @ppos: file position
++ *
++ * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
++ * values from/to the user buffer, treated as an ASCII string.
++ *
++ * This routine will ensure the values are within the range specified by
++ * table->extra1 (min) and table->extra2 (max).
++ *
++ * Writing is only allowed when root has CAP_SYS_ADMIN.
++ *
++ * Returns 0 on success, -EPERM on permission failure or -EINVAL on write
++ * when the range check fails.
++ */
++int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write,
+ void *buffer, size_t *lenp, loff_t *ppos)
+ {
+ if (write && !capable(CAP_SYS_ADMIN))
+@@ -899,7 +918,6 @@ static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write,
+
+ return proc_dointvec_minmax(table, write, buffer, lenp, ppos);
+ }
+-#endif
+
+ /**
+ * struct do_proc_dointvec_minmax_conv_param - proc_dointvec_minmax() range checking structure
+@@ -1585,6 +1603,12 @@ int proc_douintvec_minmax(struct ctl_table *table, int write,
+ return -ENOSYS;
+ }
+
++int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write,
++ void *buffer, size_t *lenp, loff_t *ppos)
++{
++ return -ENOSYS;
++}
++
+ int proc_dointvec_jiffies(struct ctl_table *table, int write,
+ void *buffer, size_t *lenp, loff_t *ppos)
+ {
+@@ -3436,6 +3460,7 @@ EXPORT_SYMBOL(proc_douintvec);
+ EXPORT_SYMBOL(proc_dointvec_jiffies);
+ EXPORT_SYMBOL(proc_dointvec_minmax);
+ EXPORT_SYMBOL_GPL(proc_douintvec_minmax);
++EXPORT_SYMBOL(proc_dointvec_minmax_sysadmin);
+ EXPORT_SYMBOL(proc_dointvec_userhz_jiffies);
+ EXPORT_SYMBOL(proc_dointvec_ms_jiffies);
+ EXPORT_SYMBOL(proc_dostring);
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0097-usb-add-toggle-for-disabling-newly-added-USB-devices.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0097-usb-add-toggle-for-disabling-newly-added-USB-devices.patch
new file mode 100644
index 000000000000..dd7c0b3ee84d
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0097-usb-add-toggle-for-disabling-newly-added-USB-devices.patch
@@ -0,0 +1,92 @@
+From 8c4c088f58564e86db268b29dadcff06bc744e60 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Tue, 16 May 2017 17:51:48 -0400
+Subject: [PATCH 097/113] usb: add toggle for disabling newly added USB devices
+
+Based on the public grsecurity patches.
+
+[thibaut.sautereau@ssi.gouv.fr: Adapt to sysctl code refactoring]
+Signed-off-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
+Signed-off-by: Levente Polyak <levente@leventepolyak.net>
+---
+ drivers/usb/core/hub.c | 9 +++++++++
+ include/linux/usb.h | 3 +++
+ kernel/sysctl.c | 14 ++++++++++++++
+ 3 files changed, 26 insertions(+)
+
+diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
+index 17202b2ee063..9385c745d55e 100644
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -5054,6 +5054,9 @@ static int descriptors_changed(struct usb_device *udev,
+ return changed;
+ }
+
++/* sysctl */
++int deny_new_usb __read_mostly = 0;
++
+ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
+ u16 portchange)
+ {
+@@ -5114,6 +5117,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/include/linux/usb.h b/include/linux/usb.h
+index 7d72c4e0713c..8e7549e3012a 100644
+--- a/include/linux/usb.h
++++ b/include/linux/usb.h
+@@ -2035,6 +2035,9 @@ extern void usb_led_activity(enum usb_led_event ev);
+ static inline void usb_led_activity(enum usb_led_event ev) {}
+ #endif
+
++/* sysctl */
++extern int deny_new_usb;
++
+ #endif /* __KERNEL__ */
+
+ #endif
+diff --git a/kernel/sysctl.c b/kernel/sysctl.c
+index 13b619e46ade..f867606fbd80 100644
+--- a/kernel/sysctl.c
++++ b/kernel/sysctl.c
+@@ -106,6 +106,9 @@
+ #ifdef CONFIG_USER_NS
+ #include <linux/user_namespace.h>
+ #endif
++#if IS_ENABLED(CONFIG_USB)
++#include <linux/usb.h>
++#endif
+
+ #if defined(CONFIG_SYSCTL)
+
+@@ -2305,6 +2308,17 @@ static struct ctl_table kern_table[] = {
+ .extra1 = SYSCTL_ZERO,
+ .extra2 = SYSCTL_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 = SYSCTL_ZERO,
++ .extra2 = SYSCTL_ONE,
++ },
++#endif
+ {
+ .procname = "ngroups_max",
+ .data = &ngroups_max,
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0098-usb-implement-dedicated-subsystem-sysctl-tables.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0098-usb-implement-dedicated-subsystem-sysctl-tables.patch
new file mode 100644
index 000000000000..a65ede25d17a
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0098-usb-implement-dedicated-subsystem-sysctl-tables.patch
@@ -0,0 +1,195 @@
+From 9a1b998f367a932a484bc9e14e027ceb6e3db4eb Mon Sep 17 00:00:00 2001
+From: Levente Polyak <levente@leventepolyak.net>
+Date: Sun, 6 Sep 2020 21:08:16 +0200
+Subject: [PATCH 098/113] usb: implement dedicated subsystem sysctl tables
+
+This moves the usb related sysctl knobs to an own usb local sysctl table
+in order to clean up the global sysctl as well as allow the knob to be
+exported and referenced appropriately when building the usb components
+as dedicated modules.
+
+Signed-off-by: Levente Polyak <levente@leventepolyak.net>
+---
+ drivers/usb/core/Makefile | 1 +
+ drivers/usb/core/hub.c | 3 ---
+ drivers/usb/core/sysctl.c | 44 +++++++++++++++++++++++++++++++++++++++
+ drivers/usb/core/usb.c | 9 ++++++++
+ include/linux/usb.h | 10 ++++++++-
+ kernel/sysctl.c | 14 -------------
+ 6 files changed, 63 insertions(+), 18 deletions(-)
+ create mode 100644 drivers/usb/core/sysctl.c
+
+diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
+index 18e874b0441e..fc7a3a9aa72a 100644
+--- a/drivers/usb/core/Makefile
++++ b/drivers/usb/core/Makefile
+@@ -11,6 +11,7 @@ usbcore-y += phy.o port.o
+ usbcore-$(CONFIG_OF) += of.o
+ usbcore-$(CONFIG_USB_PCI) += hcd-pci.o
+ usbcore-$(CONFIG_ACPI) += usb-acpi.o
++usbcore-$(CONFIG_SYSCTL) += sysctl.o
+
+ obj-$(CONFIG_USB) += usbcore.o
+
+diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
+index 9385c745d55e..b62b3da81ac4 100644
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -5054,9 +5054,6 @@ static int descriptors_changed(struct usb_device *udev,
+ return changed;
+ }
+
+-/* sysctl */
+-int deny_new_usb __read_mostly = 0;
+-
+ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
+ u16 portchange)
+ {
+diff --git a/drivers/usb/core/sysctl.c b/drivers/usb/core/sysctl.c
+new file mode 100644
+index 000000000000..3fa188ac8f67
+--- /dev/null
++++ b/drivers/usb/core/sysctl.c
+@@ -0,0 +1,44 @@
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/kmemleak.h>
++#include <linux/sysctl.h>
++#include <linux/usb.h>
++
++static struct ctl_table usb_table[] = {
++ {
++ .procname = "deny_new_usb",
++ .data = &deny_new_usb,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = proc_dointvec_minmax_sysadmin,
++ .extra1 = SYSCTL_ZERO,
++ .extra2 = SYSCTL_ONE,
++ },
++ { }
++};
++
++static struct ctl_table usb_root_table[] = {
++ { .procname = "kernel",
++ .mode = 0555,
++ .child = usb_table },
++ { }
++};
++
++static struct ctl_table_header *usb_table_header;
++
++int __init usb_init_sysctl(void)
++{
++ usb_table_header = register_sysctl_table(usb_root_table);
++ if (!usb_table_header) {
++ pr_warn("usb: sysctl registration failed\n");
++ return -ENOMEM;
++ }
++
++ kmemleak_not_leak(usb_table_header);
++ return 0;
++}
++
++void usb_exit_sysctl(void)
++{
++ unregister_sysctl_table(usb_table_header);
++}
+diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
+index 9b4ac4415f1a..93b4b798bdcc 100644
+--- a/drivers/usb/core/usb.c
++++ b/drivers/usb/core/usb.c
+@@ -72,6 +72,9 @@ MODULE_PARM_DESC(autosuspend, "default autosuspend delay");
+ #define usb_autosuspend_delay 0
+ #endif
+
++int deny_new_usb __read_mostly = 0;
++EXPORT_SYMBOL(deny_new_usb);
++
+ static bool match_endpoint(struct usb_endpoint_descriptor *epd,
+ struct usb_endpoint_descriptor **bulk_in,
+ struct usb_endpoint_descriptor **bulk_out,
+@@ -978,6 +981,9 @@ static int __init usb_init(void)
+ usb_debugfs_init();
+
+ usb_acpi_register();
++ retval = usb_init_sysctl();
++ if (retval)
++ goto sysctl_init_failed;
+ retval = bus_register(&usb_bus_type);
+ if (retval)
+ goto bus_register_failed;
+@@ -1012,6 +1018,8 @@ static int __init usb_init(void)
+ bus_notifier_failed:
+ bus_unregister(&usb_bus_type);
+ bus_register_failed:
++ usb_exit_sysctl();
++sysctl_init_failed:
+ usb_acpi_unregister();
+ usb_debugfs_cleanup();
+ out:
+@@ -1035,6 +1043,7 @@ static void __exit usb_exit(void)
+ usb_hub_cleanup();
+ bus_unregister_notifier(&usb_bus_type, &usb_bus_nb);
+ bus_unregister(&usb_bus_type);
++ usb_exit_sysctl();
+ usb_acpi_unregister();
+ usb_debugfs_cleanup();
+ idr_destroy(&usb_bus_idr);
+diff --git a/include/linux/usb.h b/include/linux/usb.h
+index 8e7549e3012a..653265115e56 100644
+--- a/include/linux/usb.h
++++ b/include/linux/usb.h
+@@ -2035,8 +2035,16 @@ extern void usb_led_activity(enum usb_led_event ev);
+ static inline void usb_led_activity(enum usb_led_event ev) {}
+ #endif
+
+-/* sysctl */
++/* sysctl.c */
+ extern int deny_new_usb;
++#ifdef CONFIG_SYSCTL
++extern int usb_init_sysctl(void);
++extern void usb_exit_sysctl(void);
++#else
++static inline int usb_init_sysctl(void) { return 0; }
++static inline void usb_exit_sysctl(void) { }
++#endif /* CONFIG_SYSCTL */
++
+
+ #endif /* __KERNEL__ */
+
+diff --git a/kernel/sysctl.c b/kernel/sysctl.c
+index f867606fbd80..13b619e46ade 100644
+--- a/kernel/sysctl.c
++++ b/kernel/sysctl.c
+@@ -106,9 +106,6 @@
+ #ifdef CONFIG_USER_NS
+ #include <linux/user_namespace.h>
+ #endif
+-#if IS_ENABLED(CONFIG_USB)
+-#include <linux/usb.h>
+-#endif
+
+ #if defined(CONFIG_SYSCTL)
+
+@@ -2308,17 +2305,6 @@ static struct ctl_table kern_table[] = {
+ .extra1 = SYSCTL_ZERO,
+ .extra2 = SYSCTL_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 = SYSCTL_ZERO,
+- .extra2 = SYSCTL_ONE,
+- },
+-#endif
+ {
+ .procname = "ngroups_max",
+ .data = &ngroups_max,
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0099-hard-wire-legacy-checkreqprot-option-to-0.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0099-hard-wire-legacy-checkreqprot-option-to-0.patch
new file mode 100644
index 000000000000..d7725a26281d
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0099-hard-wire-legacy-checkreqprot-option-to-0.patch
@@ -0,0 +1,133 @@
+From f2c881fc8b403d49a7b47a02c0252a2e030dc115 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Sun, 25 Feb 2018 03:26:45 -0500
+Subject: [PATCH 099/113] hard-wire legacy checkreqprot option to 0
+
+The userspace API is left intact for compatibility.
+
+Signed-off-by: Levente Polyak <levente@leventepolyak.net>
+---
+ .../admin-guide/kernel-parameters.txt | 11 ---------
+ security/selinux/Kconfig | 23 -------------------
+ security/selinux/hooks.c | 16 +------------
+ security/selinux/selinuxfs.c | 12 +---------
+ 4 files changed, 2 insertions(+), 60 deletions(-)
+
+diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
+index f399208c873a..282777d18d19 100644
+--- a/Documentation/admin-guide/kernel-parameters.txt
++++ b/Documentation/admin-guide/kernel-parameters.txt
+@@ -518,17 +518,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
+- /sys/fs/selinux/checkreqprot.
+- Setting checkreqprot to 1 is deprecated.
+-
+ cio_ignore= [S390]
+ See Documentation/s390/common_io.rst for details.
+ clk_ignore_unused
+diff --git a/security/selinux/Kconfig b/security/selinux/Kconfig
+index 76d7ed11513c..ae851a826c26 100644
+--- a/security/selinux/Kconfig
++++ b/security/selinux/Kconfig
+@@ -70,29 +70,6 @@ config SECURITY_SELINUX_AVC_STATS
+ /sys/fs/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 /sys/fs/selinux/checkreqprot if authorized by policy.
+-
+- WARNING: this option is deprecated and will be removed in a future
+- kernel release.
+-
+- If you are unsure how to answer this question, answer 0.
+-
+ config SECURITY_SELINUX_SIDTAB_HASH_BITS
+ int "NSA SELinux sidtab hashtable size"
+ depends on SECURITY_SELINUX
+diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
+index c46312710e73..541c65650c5e 100644
+--- a/security/selinux/hooks.c
++++ b/security/selinux/hooks.c
+@@ -136,21 +136,7 @@ static int __init selinux_enabled_setup(char *str)
+ __setup("selinux=", selinux_enabled_setup);
+ #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;
+- if (checkreqprot)
+- pr_warn("SELinux: checkreqprot set to 1 via kernel parameter. This is deprecated and will be rejected in a future kernel release.\n");
+- }
+- return 1;
+-}
+-__setup("checkreqprot=", checkreqprot_setup);
++static const unsigned int selinux_checkreqprot_boot;
+
+ /**
+ * selinux_secmark_enabled - Check to see if SECMARK is currently enabled
+diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
+index 4bde570d56a2..cc5caffc07fa 100644
+--- a/security/selinux/selinuxfs.c
++++ b/security/selinux/selinuxfs.c
+@@ -725,7 +725,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;
+@@ -749,18 +748,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;
+
+- if (new_value) {
+- char comm[sizeof(current->comm)];
+-
+- memcpy(comm, current->comm, sizeof(comm));
+- pr_warn_once("SELinux: %s (%d) set checkreqprot to 1. This is deprecated and will be rejected in a future kernel release.\n",
+- comm, current->pid);
+- }
+-
+- checkreqprot_set(fsi->state, (new_value ? 1 : 0));
+ length = count;
+ out:
+ kfree(page);
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0100-security-tty-Add-owner-user-namespace-to-tty_struct.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0100-security-tty-Add-owner-user-namespace-to-tty_struct.patch
new file mode 100644
index 000000000000..6ebf0b4afe2a
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0100-security-tty-Add-owner-user-namespace-to-tty_struct.patch
@@ -0,0 +1,70 @@
+From 0ace17837639e0479c20df2db8c990fdd644de43 Mon Sep 17 00:00:00 2001
+From: Matt Brown <matt@nmatt.com>
+Date: Mon, 29 May 2017 17:37:59 -0400
+Subject: [PATCH 100/113] security: tty: Add owner user namespace to tty_struct
+
+This patch adds struct user_namespace *owner_user_ns to the tty_struct.
+Then it is set to current_user_ns() in the alloc_tty_struct function.
+
+This is done to facilitate capability checks against the original user
+namespace that allocated the tty.
+
+E.g. ns_capable(tty->owner_user_ns,CAP_SYS_ADMIN)
+
+This combined with the use of user namespace's will allow hardening
+protections to be built to mitigate container escapes that utilize TTY
+ioctls such as TIOCSTI.
+
+See: https://bugzilla.redhat.com/show_bug.cgi?id=1411256
+
+Acked-by: Serge Hallyn <serge@hallyn.com>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Matt Brown <matt@nmatt.com>
+---
+ drivers/tty/tty_io.c | 2 ++
+ include/linux/tty.h | 2 ++
+ 2 files changed, 4 insertions(+)
+
+diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
+index 56ade99ef99f..557356504a81 100644
+--- a/drivers/tty/tty_io.c
++++ b/drivers/tty/tty_io.c
+@@ -174,6 +174,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);
+ }
+
+@@ -3014,6 +3015,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/include/linux/tty.h b/include/linux/tty.h
+index eb33d948788c..a205640b4c61 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>
+
+
+ /*
+@@ -342,6 +343,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 */
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0101-security-tty-make-TIOCSTI-ioctl-require-CAP_SYS_ADMI.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0101-security-tty-make-TIOCSTI-ioctl-require-CAP_SYS_ADMI.patch
new file mode 100644
index 000000000000..3fab49a7515d
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0101-security-tty-make-TIOCSTI-ioctl-require-CAP_SYS_ADMI.patch
@@ -0,0 +1,197 @@
+From 0125da50069de51a0c6baa3744057928bdc98377 Mon Sep 17 00:00:00 2001
+From: Matt Brown <matt@nmatt.com>
+Date: Mon, 29 May 2017 17:38:00 -0400
+Subject: [PATCH 101/113] security: tty: make TIOCSTI ioctl require
+ CAP_SYS_ADMIN
+
+This introduces the tiocsti_restrict sysctl, whose default is controlled
+via CONFIG_SECURITY_TIOCSTI_RESTRICT. When activated, this control
+restricts all TIOCSTI ioctl calls from non CAP_SYS_ADMIN users.
+
+This patch depends on patch 1/2
+
+This patch was inspired from GRKERNSEC_HARDEN_TTY.
+
+This patch would have prevented
+https://bugzilla.redhat.com/show_bug.cgi?id=1411256 under the following
+conditions:
+* non-privileged container
+* container run inside new user namespace
+
+Possible effects on userland:
+
+There could be a few user programs that would be effected by this
+change.
+See: <https://codesearch.debian.net/search?q=ioctl%5C%28.*TIOCSTI>
+notable programs are: agetty, csh, xemacs and tcsh
+
+However, I still believe that this change is worth it given that the
+Kconfig defaults to n. This will be a feature that is turned on for the
+same reason that people activate it when using grsecurity. Users of this
+opt-in feature will realize that they are choosing security over some OS
+features like unprivileged TIOCSTI ioctls, as should be clear in the
+Kconfig help message.
+
+Threat Model/Patch Rational:
+
+>From grsecurity's config for GRKERNSEC_HARDEN_TTY.
+
+ | There are very few legitimate uses for this functionality and it
+ | has made vulnerabilities in several 'su'-like programs possible in
+ | the past. Even without these vulnerabilities, it provides an
+ | attacker with an easy mechanism to move laterally among other
+ | processes within the same user's compromised session.
+
+So if one process within a tty session becomes compromised it can follow
+that additional processes, that are thought to be in different security
+boundaries, can be compromised as a result. When using a program like su
+or sudo, these additional processes could be in a tty session where TTY
+file descriptors are indeed shared over privilege boundaries.
+
+This is also an excellent writeup about the issue:
+<http://www.halfdog.net/Security/2012/TtyPushbackPrivilegeEscalation/>
+
+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.
+
+Acked-by: Serge Hallyn <serge@hallyn.com>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Matt Brown <matt@nmatt.com>
+Signed-off-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
+Signed-off-by: Levente Polyak <levente@leventepolyak.net>
+---
+ Documentation/admin-guide/sysctl/kernel.rst | 20 ++++++++++++++++++++
+ drivers/tty/tty_io.c | 8 ++++++++
+ include/linux/tty.h | 2 ++
+ kernel/sysctl.c | 14 ++++++++++++++
+ security/Kconfig | 13 +++++++++++++
+ 5 files changed, 57 insertions(+)
+
+diff --git a/Documentation/admin-guide/sysctl/kernel.rst b/Documentation/admin-guide/sysctl/kernel.rst
+index 4c20e6ded0af..3cd263f8ac46 100644
+--- a/Documentation/admin-guide/sysctl/kernel.rst
++++ b/Documentation/admin-guide/sysctl/kernel.rst
+@@ -1385,6 +1385,26 @@ If a value outside of this range is written to ``threads-max`` an
+ ``EINVAL`` error occurs.
+
+
++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.
++
++= ============================================================================
++0 No restriction, except the default one of only being able to inject commands
++ into one's own tty.
++1 Users must have ``CAP_SYS_ADMIN`` to use the ``TIOCSTI`` ioctl.
++= ============================================================================
++
++When user namespaces are in use, the check for ``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``.
++
++
+ traceoff_on_warning
+ ===================
+
+diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
+index 557356504a81..5670bd7442df 100644
+--- a/drivers/tty/tty_io.c
++++ b/drivers/tty/tty_io.c
+@@ -2182,11 +2182,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))
+diff --git a/include/linux/tty.h b/include/linux/tty.h
+index a205640b4c61..116138eb394c 100644
+--- a/include/linux/tty.h
++++ b/include/linux/tty.h
+@@ -353,6 +353,8 @@ struct tty_file_private {
+ struct list_head list;
+ };
+
++extern int tiocsti_restrict;
++
+ /* tty magic number */
+ #define TTY_MAGIC 0x5401
+
+diff --git a/kernel/sysctl.c b/kernel/sysctl.c
+index 13b619e46ade..8fd007fbec4c 100644
+--- a/kernel/sysctl.c
++++ b/kernel/sysctl.c
+@@ -106,6 +106,9 @@
+ #ifdef CONFIG_USER_NS
+ #include <linux/user_namespace.h>
+ #endif
++#if defined CONFIG_TTY
++#include <linux/tty.h>
++#endif
+
+ #if defined(CONFIG_SYSCTL)
+
+@@ -2295,6 +2298,17 @@ static struct ctl_table kern_table[] = {
+ .extra1 = SYSCTL_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 = SYSCTL_ZERO,
++ .extra2 = SYSCTL_ONE,
++ },
+ #endif
+ {
+ .procname = "device_sidechannel_restrict",
+diff --git a/security/Kconfig b/security/Kconfig
+index f3c995bd79cf..c8ea5a6ecce0 100644
+--- a/security/Kconfig
++++ b/security/Kconfig
+@@ -29,6 +29,19 @@ config SECURITY_PERF_EVENTS_RESTRICT
+ perf_event_open syscall will be permitted unless it is
+ changed.
+
++config SECURITY_TIOCSTI_RESTRICT
++ bool "Restrict unprivileged use of tiocsti command injection"
++ default n
++ 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
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0102-enable-SECURITY_TIOCSTI_RESTRICT-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0102-enable-SECURITY_TIOCSTI_RESTRICT-by-default.patch
new file mode 100644
index 000000000000..7bfcbfd3563e
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0102-enable-SECURITY_TIOCSTI_RESTRICT-by-default.patch
@@ -0,0 +1,26 @@
+From e8fa982737b4cf6b314c4b6d7fb3a51d58842af6 Mon Sep 17 00:00:00 2001
+From: Daniel Micay <danielmicay@gmail.com>
+Date: Wed, 3 May 2017 23:36:14 -0400
+Subject: [PATCH 102/113] enable SECURITY_TIOCSTI_RESTRICT by default
+
+Signed-off-by: Daniel Micay <danielmicay@gmail.com>
+---
+ security/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/security/Kconfig b/security/Kconfig
+index c8ea5a6ecce0..615205c0113b 100644
+--- a/security/Kconfig
++++ b/security/Kconfig
+@@ -31,7 +31,7 @@ config SECURITY_PERF_EVENTS_RESTRICT
+
+ config SECURITY_TIOCSTI_RESTRICT
+ bool "Restrict unprivileged use of tiocsti command injection"
+- default n
++ default y
+ help
+ This enforces restrictions on unprivileged users injecting commands
+ into other processes which share a tty session using the TIOCSTI
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0103-disable-unprivileged-eBPF-access-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0103-disable-unprivileged-eBPF-access-by-default.patch
new file mode 100644
index 000000000000..dbef18e9e1d9
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0103-disable-unprivileged-eBPF-access-by-default.patch
@@ -0,0 +1,25 @@
+From e3d2bd0527f2e3a9aca7dedd4eb8d5728cbb090f Mon Sep 17 00:00:00 2001
+From: Levente Polyak <levente@leventepolyak.net>
+Date: Mon, 7 May 2018 20:37:07 +0200
+Subject: [PATCH 103/113] disable unprivileged eBPF access by default
+
+---
+ kernel/bpf/syscall.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
+index 8f50c9c19f1b..a54c05624647 100644
+--- a/kernel/bpf/syscall.c
++++ b/kernel/bpf/syscall.c
+@@ -50,7 +50,7 @@ static DEFINE_SPINLOCK(map_idr_lock);
+ static DEFINE_IDR(link_idr);
+ static DEFINE_SPINLOCK(link_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, _name, prog_ctx_type, kern_ctx_type)
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0104-enable-BPF-JIT-hardening-by-default-if-available.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0104-enable-BPF-JIT-hardening-by-default-if-available.patch
new file mode 100644
index 000000000000..d196940dd48b
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0104-enable-BPF-JIT-hardening-by-default-if-available.patch
@@ -0,0 +1,25 @@
+From 53ca7668ae8d442d56c04eebf3f7ae7640d89d1e Mon Sep 17 00:00:00 2001
+From: Levente Polyak <levente@leventepolyak.net>
+Date: Mon, 7 May 2018 20:37:55 +0200
+Subject: [PATCH 104/113] enable BPF JIT hardening by default (if available)
+
+---
+ kernel/bpf/core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
+index 55454d2278b1..de02792dc2fc 100644
+--- a/kernel/bpf/core.c
++++ b/kernel/bpf/core.c
+@@ -524,7 +524,7 @@ void bpf_prog_kallsyms_del_all(struct bpf_prog *fp)
+ /* All BPF JIT sysctl knobs here. */
+ int bpf_jit_enable __read_mostly = IS_BUILTIN(CONFIG_BPF_JIT_DEFAULT_ON);
+ int bpf_jit_kallsyms __read_mostly = IS_BUILTIN(CONFIG_BPF_JIT_DEFAULT_ON);
+-int bpf_jit_harden __read_mostly;
++int bpf_jit_harden __read_mostly = 2;
+ long bpf_jit_limit __read_mostly;
+
+ static void
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0105-enable-protected_-fifos-regular-by-default.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0105-enable-protected_-fifos-regular-by-default.patch
new file mode 100644
index 000000000000..b2e06a406db3
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0105-enable-protected_-fifos-regular-by-default.patch
@@ -0,0 +1,27 @@
+From 645992427421dd1db5ed4d4b93eddb0a8fcf4dd2 Mon Sep 17 00:00:00 2001
+From: Levente Polyak <levente@leventepolyak.net>
+Date: Sun, 4 Nov 2018 18:48:53 +0100
+Subject: [PATCH 105/113] enable protected_{fifos,regular} by default
+
+---
+ fs/namei.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/fs/namei.c b/fs/namei.c
+index 59ff3ce21026..72f912c68975 100644
+--- a/fs/namei.c
++++ b/fs/namei.c
+@@ -934,8 +934,8 @@ static inline void put_link(struct nameidata *nd)
+
+ int sysctl_protected_symlinks __read_mostly = 1;
+ int sysctl_protected_hardlinks __read_mostly = 1;
+-int sysctl_protected_fifos __read_mostly;
+-int sysctl_protected_regular __read_mostly;
++int sysctl_protected_fifos __read_mostly = 2;
++int sysctl_protected_regular __read_mostly = 2;
+
+ /**
+ * may_follow_link - Check symlink following for unsafe situations
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0106-modpost-Add-CONFIG_DEBUG_WRITABLE_FUNCTION_POINTERS_.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0106-modpost-Add-CONFIG_DEBUG_WRITABLE_FUNCTION_POINTERS_.patch
new file mode 100644
index 000000000000..9d713d00c161
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0106-modpost-Add-CONFIG_DEBUG_WRITABLE_FUNCTION_POINTERS_.patch
@@ -0,0 +1,129 @@
+From e08ac98884b625a79ad558c0763db8674550a700 Mon Sep 17 00:00:00 2001
+From: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
+Date: Mon, 6 May 2019 17:07:11 +0200
+Subject: [PATCH 106/113] modpost: Add
+ CONFIG_DEBUG_WRITABLE_FUNCTION_POINTERS_VERBOSE
+
+With 46c7dd56d541 ("modpost: always show verbose warning for section
+mismatch"), sec_mismatch_verbose was removed which would have printed
+errors for all writable function pointers during compilation if it
+hadn't been "#if 0"ed out for quite some time now.
+
+Let's introduce a new DEBUG_WRITABLE_FUNCTION_POINTERS_VERBOSE Kconfig
+option to cleanly control this linux-hardened functionality.
+
+Signed-off-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
+Signed-off-by: Levente Polyak <levente@leventepolyak.net>
+---
+ lib/Kconfig.debug | 3 +++
+ scripts/Makefile.modpost | 1 +
+ scripts/mod/modpost.c | 25 ++++++++++++++++---------
+ 3 files changed, 20 insertions(+), 9 deletions(-)
+
+diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
+index 4a1a32a059f4..5fce84adc315 100644
+--- a/lib/Kconfig.debug
++++ b/lib/Kconfig.debug
+@@ -374,6 +374,9 @@ config DEBUG_FORCE_FUNCTION_ALIGN_32B
+
+ It is mainly for debug and performance tuning use.
+
++config DEBUG_WRITABLE_FUNCTION_POINTERS_VERBOSE
++ bool "Enable verbose reporting of writable function pointers"
++
+ #
+ # Select this config option from the architecture Kconfig, if it
+ # is preferred to always offer frame pointers as a config
+diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
+index f54b6ac37ac2..e53b3057d4cb 100644
+--- a/scripts/Makefile.modpost
++++ b/scripts/Makefile.modpost
+@@ -47,6 +47,7 @@ MODPOST = scripts/mod/modpost \
+ $(if $(CONFIG_MODVERSIONS),-m) \
+ $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a) \
+ $(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \
++ $(if $(CONFIG_DEBUG_WRITABLE_FUNCTION_POINTERS_VERBOSE),-f) \
+ $(if $(KBUILD_MODPOST_WARN),-w) \
+ -o $@
+
+diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
+index 50e9baefc4e7..2cbc4e8a6295 100644
+--- a/scripts/mod/modpost.c
++++ b/scripts/mod/modpost.c
+@@ -34,8 +34,9 @@ static int external_module = 0;
+ 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_fatal = 0;
++static int writable_fptr_count = 0;
++static int writable_fptr_verbose = 0;
+ /* ignore missing files */
+ static int ignore_missing_files;
+ /* If set to 1, only warn (instead of error) about missing ns imports */
+@@ -1466,10 +1467,13 @@ static void report_sec_mismatch(const char *modname,
+ char *prl_from;
+ char *prl_to;
+
+- if (mismatch->mismatch == DATA_TO_TEXT)
++ if (mismatch->mismatch == DATA_TO_TEXT) {
+ writable_fptr_count++;
+- else
++ if (!writable_fptr_verbose)
++ return;
++ } else {
+ sec_mismatch_count++;
++ }
+
+ get_pretty_name(from_is_func, &from, &from_p);
+ get_pretty_name(to_is_func, &to, &to_p);
+@@ -1592,12 +1596,10 @@ static void report_sec_mismatch(const char *modname,
+ "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");
+@@ -2578,7 +2580,7 @@ int main(int argc, char **argv)
+ struct dump_list *dump_read_start = NULL;
+ struct dump_list **dump_read_iter = &dump_read_start;
+
+- while ((opt = getopt(argc, argv, "ei:mnT:o:awENd:")) != -1) {
++ while ((opt = getopt(argc, argv, "ei:fmnT:o:awENd:")) != -1) {
+ switch (opt) {
+ case 'e':
+ external_module = 1;
+@@ -2589,6 +2591,9 @@ int main(int argc, char **argv)
+ (*dump_read_iter)->file = optarg;
+ dump_read_iter = &(*dump_read_iter)->next;
+ break;
++ case 'f':
++ writable_fptr_verbose = 1;
++ break;
+ case 'm':
+ modversions = 1;
+ break;
+@@ -2689,9 +2694,11 @@ int main(int argc, char **argv)
+ }
+
+ free(buf.p);
+- if (writable_fptr_count)
+- warn("modpost: Found %d writable function pointer(s).\n",
+- writable_fptr_count);
++ if (writable_fptr_count && !writable_fptr_verbose)
++ warn("modpost: Found %d writable function pointer%s.\n"
++ "To see full details build your kernel with:\n"
++ "'make CONFIG_DEBUG_WRITABLE_FUNCTION_POINTERS_VERBOSE=y'\n",
++ writable_fptr_count, (writable_fptr_count == 1 ? "" : "s"));
+
+ return err;
+ }
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0107-mm-Fix-extra_latent_entropy.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0107-mm-Fix-extra_latent_entropy.patch
new file mode 100644
index 000000000000..02142e2a38bc
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0107-mm-Fix-extra_latent_entropy.patch
@@ -0,0 +1,103 @@
+From c1e92a012a13de1fba54928d6b1a116cb92fb7e2 Mon Sep 17 00:00:00 2001
+From: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
+Date: Tue, 7 May 2019 11:46:21 +0200
+Subject: [PATCH 107/113] mm: Fix extra_latent_entropy
+
+Commit a9cd410a3d29 ("mm/page_alloc.c: memory hotplug: free pages as
+higher order") changed `static void __init __free_pages_boot_core()`
+into `void __free_pages_core()`, causing the following section mismatch
+warning at compile time:
+
+ WARNING: vmlinux.o(.text+0x180fe4): Section mismatch in reference from the function __free_pages_core() to the variable .meminit.data:extra_latent_entropy
+ The function __free_pages_core() references the variable __meminitdata extra_latent_entropy.
+ This is often because __free_pages_core lacks a __meminitdata annotation or the annotation of extra_latent_entropy is wrong.
+
+This commit is an attempt at fixing this issue. I'm not sure it's OK as
+we are accessing pages that are still managed by the bootmem allocator.
+The prefetching part is not an issue as it only affects struct pages.
+
+Signed-off-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
+---
+ mm/page_alloc.c | 38 ++++++++++++++++++++++----------------
+ 1 file changed, 22 insertions(+), 16 deletions(-)
+
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index ded9e8536285..8730ae4244b9 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -1539,6 +1539,25 @@ static void __free_pages_ok(struct page *page, unsigned int order,
+ local_irq_restore(flags);
+ }
+
++static void __init __gather_extra_latent_entropy(struct page *page,
++ unsigned int nr_pages)
++{
++ 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
++ }
++}
++
+ void __free_pages_core(struct page *page, unsigned int order)
+ {
+ unsigned int nr_pages = 1 << order;
+@@ -1558,22 +1577,6 @@ void __free_pages_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
+- }
+-
+ atomic_long_add(nr_pages, &page_zone(page)->managed_pages);
+
+ /*
+@@ -1632,6 +1635,7 @@ void __init memblock_free_pages(struct page *page, unsigned long pfn,
+ {
+ if (early_page_uninitialised(pfn))
+ return;
++ __gather_extra_latent_entropy(page, 1 << order);
+ __free_pages_core(page, order);
+ }
+
+@@ -1723,6 +1727,7 @@ static void __init deferred_free_range(unsigned long pfn,
+ if (nr_pages == pageblock_nr_pages &&
+ (pfn & (pageblock_nr_pages - 1)) == 0) {
+ set_pageblock_migratetype(page, MIGRATE_MOVABLE);
++ __gather_extra_latent_entropy(page, 1 << pageblock_order);
+ __free_pages_core(page, pageblock_order);
+ return;
+ }
+@@ -1730,6 +1735,7 @@ static void __init deferred_free_range(unsigned long pfn,
+ for (i = 0; i < nr_pages; i++, page++, pfn++) {
+ if ((pfn & (pageblock_nr_pages - 1)) == 0)
+ set_pageblock_migratetype(page, MIGRATE_MOVABLE);
++ __gather_extra_latent_entropy(page, 1);
+ __free_pages_core(page, 0);
+ }
+ }
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0108-add-CONFIG-for-unprivileged_userfaultfd.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0108-add-CONFIG-for-unprivileged_userfaultfd.patch
new file mode 100644
index 000000000000..135dd02aed87
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0108-add-CONFIG-for-unprivileged_userfaultfd.patch
@@ -0,0 +1,68 @@
+From 1069527de358d6210f21da324a9584c2b20b23e2 Mon Sep 17 00:00:00 2001
+From: Levente Polyak <levente@leventepolyak.net>
+Date: Wed, 2 Oct 2019 01:22:17 +0200
+Subject: [PATCH 108/113] add CONFIG for unprivileged_userfaultfd
+
+When disabled, unprivileged users will not be able to use the userfaultfd
+syscall. Userfaultfd provide attackers with a way to stall a kernel
+thread in the middle of memory accesses from userspace by initiating an
+access on an unmapped page. To avoid various heap grooming and heap
+spraying techniques for exploiting use-after-free flaws this should be
+disabled by default.
+
+This setting can be overridden at runtime via the
+vm.unprivileged_userfaultfd sysctl.
+
+Signed-off-by: Levente Polyak <levente@leventepolyak.net>
+---
+ fs/userfaultfd.c | 4 ++++
+ init/Kconfig | 17 +++++++++++++++++
+ 2 files changed, 21 insertions(+)
+
+diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
+index 000b457ad087..06d35ecdcbc8 100644
+--- a/fs/userfaultfd.c
++++ b/fs/userfaultfd.c
+@@ -28,7 +28,11 @@
+ #include <linux/security.h>
+ #include <linux/hugetlb.h>
+
++#ifdef CONFIG_USERFAULTFD_UNPRIVILEGED
+ int sysctl_unprivileged_userfaultfd __read_mostly = 1;
++#else
++int sysctl_unprivileged_userfaultfd __read_mostly;
++#endif
+
+ static struct kmem_cache *userfaultfd_ctx_cachep __read_mostly;
+
+diff --git a/init/Kconfig b/init/Kconfig
+index a7b5a4cb7939..2feea719cc25 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -1745,6 +1745,23 @@ config USERFAULTFD
+ Enable the userfaultfd() system call that allows to intercept and
+ handle page faults in userland.
+
++config USERFAULTFD_UNPRIVILEGED
++ bool "Allow unprivileged users to use the userfaultfd syscall"
++ depends on USERFAULTFD
++ default n
++ help
++ When disabled, unprivileged users will not be able to use the userfaultfd
++ syscall. Userfaultfd provide attackers with a way to stall a kernel
++ thread in the middle of memory accesses from userspace by initiating an
++ access on an unmapped page. To avoid various heap grooming and heap
++ spraying techniques for exploiting use-after-free flaws this should be
++ disabled by default.
++
++ This setting can be overridden at runtime via the
++ vm.unprivileged_userfaultfd sysctl.
++
++ If unsure, say N.
++
+ config ARCH_HAS_MEMBARRIER_CALLBACKS
+ bool
+
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0109-slub-Extend-init_on_alloc-to-slab-caches-with-constr.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0109-slub-Extend-init_on_alloc-to-slab-caches-with-constr.patch
new file mode 100644
index 000000000000..c1ef650f0d39
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0109-slub-Extend-init_on_alloc-to-slab-caches-with-constr.patch
@@ -0,0 +1,81 @@
+From bc963dada9a10f9d859f5585b9561fb7a5bfc26b Mon Sep 17 00:00:00 2001
+From: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
+Date: Fri, 29 Nov 2019 16:27:14 +0100
+Subject: [PATCH 109/113] slub: Extend init_on_alloc to slab caches with
+ constructors
+
+Signed-off-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
+Signed-off-by: Levente Polyak <levente@leventepolyak.net>
+---
+ mm/slab.h | 2 ++
+ mm/slub.c | 23 ++++++++++++++++++-----
+ 2 files changed, 20 insertions(+), 5 deletions(-)
+
+diff --git a/mm/slab.h b/mm/slab.h
+index 105dba485a7e..2138deacf719 100644
+--- a/mm/slab.h
++++ b/mm/slab.h
+@@ -630,8 +630,10 @@ static inline void cache_random_seq_destroy(struct kmem_cache *cachep) { }
+ static inline bool slab_want_init_on_alloc(gfp_t flags, struct kmem_cache *c)
+ {
+ if (static_branch_unlikely(&init_on_alloc)) {
++#ifndef CONFIG_SLUB
+ if (c->ctor)
+ return false;
++#endif
+ if (c->flags & (SLAB_TYPESAFE_BY_RCU | SLAB_POISON))
+ return flags & __GFP_ZERO;
+ return true;
+diff --git a/mm/slub.c b/mm/slub.c
+index a06d34be763a..32cc008ee278 100644
+--- a/mm/slub.c
++++ b/mm/slub.c
+@@ -1635,9 +1635,10 @@ static inline bool slab_free_freelist_hook(struct kmem_cache *s,
+ * need to show a valid freepointer to check_object().
+ *
+ * Note that doing this for all caches (not just ctor
+- * ones, which have s->offset != NULL)) causes a GPF,
+- * due to KASAN poisoning and the way set_freepointer()
+- * eventually dereferences the freepointer.
++ * ones, which have s->offset >= object_size)) causes a
++ * GPF, due to KASAN poisoning and the way
++ * set_freepointer() eventually dereferences the
++ * freepointer.
+ */
+ set_freepointer(s, object, NULL);
+ }
+@@ -2955,8 +2956,14 @@ static __always_inline void *slab_alloc_node(struct kmem_cache *s,
+ if (s->ctor)
+ s->ctor(object);
+ kasan_poison_object_data(s, object);
+- } else if (unlikely(slab_want_init_on_alloc(gfpflags, s)) && object)
++ } else if (unlikely(slab_want_init_on_alloc(gfpflags, s)) && object) {
+ memset(object, 0, s->object_size);
++ if (s->ctor) {
++ kasan_unpoison_object_data(s, object);
++ s->ctor(object);
++ kasan_poison_object_data(s, object);
++ }
++ }
+
+ if (object) {
+ check_canary(s, object, s->random_inactive);
+@@ -3416,8 +3423,14 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size,
+ } else if (unlikely(slab_want_init_on_alloc(flags, s))) {
+ int j;
+
+- for (j = 0; j < i; j++)
++ for (j = 0; j < i; j++) {
+ memset(p[j], 0, s->object_size);
++ if (s->ctor) {
++ kasan_unpoison_object_data(s, p[j]);
++ s->ctor(p[j]);
++ kasan_poison_object_data(s, p[j]);
++ }
++ }
+ }
+
+ for (k = 0; k < i; k++) {
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0110-net-tcp-add-option-to-disable-TCP-simultaneous-conne.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0110-net-tcp-add-option-to-disable-TCP-simultaneous-conne.patch
new file mode 100644
index 000000000000..c0ed4454afd3
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0110-net-tcp-add-option-to-disable-TCP-simultaneous-conne.patch
@@ -0,0 +1,151 @@
+From f461686078d2f472572e083400419a6af0938ad8 Mon Sep 17 00:00:00 2001
+From: madaidan <50278627+madaidan@users.noreply.github.com>
+Date: Sun, 9 Feb 2020 00:03:41 +0000
+Subject: [PATCH 110/113] net: tcp: add option to disable TCP simultaneous
+ connect
+
+This is modified from Brad Spengler/PaX Team's code in the last public
+patch of grsecurity/PaX based on my understanding of the code. Changes
+or omissions from the original code are mine and don't reflect the
+original grsecurity/PaX code.
+
+TCP simultaneous connect adds a weakness in Linux's 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.
+
+This creates a net.ipv4.tcp_simult_connect sysctl that when disabled,
+disables TCP simultaneous connect.
+
+Reviewd-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
+Reviewd-by: Levente Polyak <levente@leventepolyak.net>
+Signed-off-by: Levente Polyak <levente@leventepolyak.net>
+---
+ Documentation/networking/ip-sysctl.rst | 18 ++++++++++++++++++
+ include/net/tcp.h | 1 +
+ net/ipv4/Kconfig | 23 +++++++++++++++++++++++
+ net/ipv4/sysctl_net_ipv4.c | 9 +++++++++
+ net/ipv4/tcp_input.c | 3 ++-
+ 5 files changed, 53 insertions(+), 1 deletion(-)
+
+diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst
+index 25e6673a085a..76f1892d65ed 100644
+--- a/Documentation/networking/ip-sysctl.rst
++++ b/Documentation/networking/ip-sysctl.rst
+@@ -665,6 +665,24 @@ tcp_comp_sack_nr - INTEGER
+
+ Default : 44
+
++tcp_simult_connect - BOOLEAN
++ Enable TCP simultaneous connect that adds 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 disabling 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.
++
++ Disabling this may break TCP STUNT which is used by some applications for
++ NAT traversal.
++
++ Default: Value of CONFIG_TCP_SIMULT_CONNECT_DEFAULT_ON
++
+ tcp_slow_start_after_idle - BOOLEAN
+ If set, provide RFC2861 behavior and time out the congestion
+ window after an idle period. An idle period is defined at
+diff --git a/include/net/tcp.h b/include/net/tcp.h
+index d4ef5bf94168..34d0d5438108 100644
+--- a/include/net/tcp.h
++++ b/include/net/tcp.h
+@@ -245,6 +245,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo);
+ /* sysctl variables for tcp */
+ extern int sysctl_tcp_max_orphans;
+ extern long sysctl_tcp_mem[3];
++extern int sysctl_tcp_simult_connect;
+
+ #define TCP_RACK_LOSS_DETECTION 0x1 /* Use RACK to detect losses */
+ #define TCP_RACK_STATIC_REO_WND 0x2 /* Use static RACK reo wnd */
+diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
+index 989e005bf698..d1584b4b39f9 100644
+--- a/net/ipv4/Kconfig
++++ b/net/ipv4/Kconfig
+@@ -743,3 +743,26 @@ config TCP_MD5SIG
+ on the Internet.
+
+ If unsure, say N.
++
++config TCP_SIMULT_CONNECT_DEFAULT_ON
++ bool "Enable TCP simultaneous connect"
++ help
++ Enable TCP simultaneous connect that adds 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 disabling 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.
++
++ Disabling this may break TCP STUNT which is used by some applications
++ for NAT traversal.
++
++ This setting can be overridden at runtime via the
++ net.ipv4.tcp_simult_connect sysctl.
++
++ If unsure, say N.
+diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
+index 3e5f4f2e705e..791329c77dea 100644
+--- a/net/ipv4/sysctl_net_ipv4.c
++++ b/net/ipv4/sysctl_net_ipv4.c
+@@ -588,6 +588,15 @@ static struct ctl_table ipv4_table[] = {
+ .mode = 0644,
+ .proc_handler = proc_do_static_key,
+ },
++ {
++ .procname = "tcp_simult_connect",
++ .data = &sysctl_tcp_simult_connect,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = proc_dointvec_minmax,
++ .extra1 = SYSCTL_ZERO,
++ .extra2 = SYSCTL_ONE,
++ },
+ { }
+ };
+
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index ef4bdb038a4b..86967b09a8e2 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -82,6 +82,7 @@
+ #include <net/mptcp.h>
+
+ int sysctl_tcp_max_orphans __read_mostly = NR_FILE;
++int sysctl_tcp_simult_connect __read_mostly = IS_ENABLED(CONFIG_TCP_SIMULT_CONNECT_DEFAULT_ON);
+
+ #define FLAG_DATA 0x01 /* Incoming frame contained data. */
+ #define FLAG_WIN_UPDATE 0x02 /* Incoming ACK was a window update. */
+@@ -6195,7 +6196,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;
+
+- if (th->syn) {
++ if (th->syn && sysctl_tcp_simult_connect) {
+ /* We see SYN without ACK. It is attempt of
+ * simultaneous connect with crossed SYNs.
+ * Particularly, it can be connect to self.
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0111-dccp-ccid-move-timers-to-struct-dccp_sock.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0111-dccp-ccid-move-timers-to-struct-dccp_sock.patch
new file mode 100644
index 000000000000..afef30230712
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0111-dccp-ccid-move-timers-to-struct-dccp_sock.patch
@@ -0,0 +1,238 @@
+From 0149a4586f7ab88cd4feaeed1a6c2be46efaf47c Mon Sep 17 00:00:00 2001
+From: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
+Date: Tue, 13 Oct 2020 19:18:48 +0200
+Subject: [PATCH 111/113] dccp: ccid: move timers to struct dccp_sock
+
+When dccps_hc_tx_ccid is freed, ccid timers may still trigger. The reason
+del_timer_sync can't be used is because this relies on keeping a reference
+to struct sock. But as we keep a pointer to dccps_hc_tx_ccid and free that
+during disconnect, the timer should really belong to struct dccp_sock.
+
+This addresses CVE-2020-16119.
+
+Fixes: 839a6094140a (net: dccp: Convert timers to use timer_setup())
+Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
+Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
+---
+ include/linux/dccp.h | 2 ++
+ net/dccp/ccids/ccid2.c | 32 +++++++++++++++++++-------------
+ net/dccp/ccids/ccid3.c | 30 ++++++++++++++++++++----------
+ 3 files changed, 41 insertions(+), 23 deletions(-)
+
+diff --git a/include/linux/dccp.h b/include/linux/dccp.h
+index 07e547c02fd8..504afa1a4be6 100644
+--- a/include/linux/dccp.h
++++ b/include/linux/dccp.h
+@@ -259,6 +259,7 @@ struct dccp_ackvec;
+ * @dccps_sync_scheduled - flag which signals "send out-of-band message soon"
+ * @dccps_xmitlet - tasklet scheduled by the TX CCID to dequeue data packets
+ * @dccps_xmit_timer - used by the TX CCID to delay sending (rate-based pacing)
++ * @dccps_ccid_timer - used by the CCIDs
+ * @dccps_syn_rtt - RTT sample from Request/Response exchange (in usecs)
+ */
+ struct dccp_sock {
+@@ -303,6 +304,7 @@ struct dccp_sock {
+ __u8 dccps_sync_scheduled:1;
+ struct tasklet_struct dccps_xmitlet;
+ struct timer_list dccps_xmit_timer;
++ struct timer_list dccps_ccid_timer;
+ };
+
+ static inline struct dccp_sock *dccp_sk(const struct sock *sk)
+diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c
+index 3da1f77bd039..dbca1f1e2449 100644
+--- a/net/dccp/ccids/ccid2.c
++++ b/net/dccp/ccids/ccid2.c
+@@ -126,21 +126,26 @@ static void dccp_tasklet_schedule(struct sock *sk)
+
+ static void ccid2_hc_tx_rto_expire(struct timer_list *t)
+ {
+- struct ccid2_hc_tx_sock *hc = from_timer(hc, t, tx_rtotimer);
+- struct sock *sk = hc->sk;
+- const bool sender_was_blocked = ccid2_cwnd_network_limited(hc);
++ struct dccp_sock *dp = from_timer(dp, t, dccps_ccid_timer);
++ struct sock *sk = (struct sock *)dp;
++ struct ccid2_hc_tx_sock *hc;
++ bool sender_was_blocked;
+
+ bh_lock_sock(sk);
++
++ if (inet_sk_state_load(sk) == DCCP_CLOSED)
++ goto out;
++
++ hc = ccid_priv(dp->dccps_hc_tx_ccid);
++ sender_was_blocked = ccid2_cwnd_network_limited(hc);
++
+ if (sock_owned_by_user(sk)) {
+- sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + HZ / 5);
++ sk_reset_timer(sk, &dp->dccps_ccid_timer, jiffies + HZ / 5);
+ goto out;
+ }
+
+ ccid2_pr_debug("RTO_EXPIRE\n");
+
+- if (sk->sk_state == DCCP_CLOSED)
+- goto out;
+-
+ /* back-off timer */
+ hc->tx_rto <<= 1;
+ if (hc->tx_rto > DCCP_RTO_MAX)
+@@ -166,7 +171,7 @@ static void ccid2_hc_tx_rto_expire(struct timer_list *t)
+ if (sender_was_blocked)
+ dccp_tasklet_schedule(sk);
+ /* restart backed-off timer */
+- sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto);
++ sk_reset_timer(sk, &dp->dccps_ccid_timer, jiffies + hc->tx_rto);
+ out:
+ bh_unlock_sock(sk);
+ sock_put(sk);
+@@ -330,7 +335,7 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, unsigned int len)
+ }
+ #endif
+
+- sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto);
++ sk_reset_timer(sk, &dp->dccps_ccid_timer, jiffies + hc->tx_rto);
+
+ #ifdef CONFIG_IP_DCCP_CCID2_DEBUG
+ do {
+@@ -700,9 +705,9 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
+
+ /* restart RTO timer if not all outstanding data has been acked */
+ if (hc->tx_pipe == 0)
+- sk_stop_timer(sk, &hc->tx_rtotimer);
++ sk_stop_timer(sk, &dp->dccps_ccid_timer);
+ else
+- sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto);
++ sk_reset_timer(sk, &dp->dccps_ccid_timer, jiffies + hc->tx_rto);
+ done:
+ /* check if incoming Acks allow pending packets to be sent */
+ if (sender_was_blocked && !ccid2_cwnd_network_limited(hc))
+@@ -737,17 +742,18 @@ static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk)
+ hc->tx_last_cong = hc->tx_lsndtime = hc->tx_cwnd_stamp = ccid2_jiffies32;
+ hc->tx_cwnd_used = 0;
+ hc->sk = sk;
+- timer_setup(&hc->tx_rtotimer, ccid2_hc_tx_rto_expire, 0);
++ timer_setup(&dp->dccps_ccid_timer, ccid2_hc_tx_rto_expire, 0);
+ INIT_LIST_HEAD(&hc->tx_av_chunks);
+ return 0;
+ }
+
+ static void ccid2_hc_tx_exit(struct sock *sk)
+ {
++ struct dccp_sock *dp = dccp_sk(sk);
+ struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk);
+ int i;
+
+- sk_stop_timer(sk, &hc->tx_rtotimer);
++ sk_stop_timer(sk, &dp->dccps_ccid_timer);
+
+ for (i = 0; i < hc->tx_seqbufc; i++)
+ kfree(hc->tx_seqbuf[i]);
+diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
+index b9ee1a4a8955..685f4d046c0d 100644
+--- a/net/dccp/ccids/ccid3.c
++++ b/net/dccp/ccids/ccid3.c
+@@ -184,17 +184,24 @@ static inline void ccid3_hc_tx_update_win_count(struct ccid3_hc_tx_sock *hc,
+
+ static void ccid3_hc_tx_no_feedback_timer(struct timer_list *t)
+ {
+- struct ccid3_hc_tx_sock *hc = from_timer(hc, t, tx_no_feedback_timer);
+- struct sock *sk = hc->sk;
++ struct dccp_sock *dp = from_timer(dp, t, dccps_ccid_timer);
++ struct ccid3_hc_tx_sock *hc;
++ struct sock *sk = (struct sock *)dp;
+ unsigned long t_nfb = USEC_PER_SEC / 5;
+
+ bh_lock_sock(sk);
++
++ if (inet_sk_state_load(sk) == DCCP_CLOSED)
++ goto out;
++
+ if (sock_owned_by_user(sk)) {
+ /* Try again later. */
+ /* XXX: set some sensible MIB */
+ goto restart_timer;
+ }
+
++ hc = ccid_priv(dp->dccps_hc_tx_ccid);
++
+ ccid3_pr_debug("%s(%p, state=%s) - entry\n", dccp_role(sk), sk,
+ ccid3_tx_state_name(hc->tx_state));
+
+@@ -250,8 +257,8 @@ static void ccid3_hc_tx_no_feedback_timer(struct timer_list *t)
+ t_nfb = max(hc->tx_t_rto, 2 * hc->tx_t_ipi);
+
+ restart_timer:
+- sk_reset_timer(sk, &hc->tx_no_feedback_timer,
+- jiffies + usecs_to_jiffies(t_nfb));
++ sk_reset_timer(sk, &dp->dccps_ccid_timer,
++ jiffies + usecs_to_jiffies(t_nfb));
+ out:
+ bh_unlock_sock(sk);
+ sock_put(sk);
+@@ -280,7 +287,7 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
+ return -EBADMSG;
+
+ if (hc->tx_state == TFRC_SSTATE_NO_SENT) {
+- sk_reset_timer(sk, &hc->tx_no_feedback_timer, (jiffies +
++ sk_reset_timer(sk, &dp->dccps_ccid_timer, (jiffies +
+ usecs_to_jiffies(TFRC_INITIAL_TIMEOUT)));
+ hc->tx_last_win_count = 0;
+ hc->tx_t_last_win_count = now;
+@@ -354,6 +361,7 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, unsigned int len)
+ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
+ {
+ struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk);
++ struct dccp_sock *dp = dccp_sk(sk);
+ struct tfrc_tx_hist_entry *acked;
+ ktime_t now;
+ unsigned long t_nfb;
+@@ -420,7 +428,7 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
+ (unsigned int)(hc->tx_x >> 6));
+
+ /* unschedule no feedback timer */
+- sk_stop_timer(sk, &hc->tx_no_feedback_timer);
++ sk_stop_timer(sk, &dp->dccps_ccid_timer);
+
+ /*
+ * As we have calculated new ipi, delta, t_nom it is possible
+@@ -445,8 +453,8 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
+ "expire in %lu jiffies (%luus)\n",
+ dccp_role(sk), sk, usecs_to_jiffies(t_nfb), t_nfb);
+
+- sk_reset_timer(sk, &hc->tx_no_feedback_timer,
+- jiffies + usecs_to_jiffies(t_nfb));
++ sk_reset_timer(sk, &dp->dccps_ccid_timer,
++ jiffies + usecs_to_jiffies(t_nfb));
+ }
+
+ static int ccid3_hc_tx_parse_options(struct sock *sk, u8 packet_type,
+@@ -488,21 +496,23 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, u8 packet_type,
+
+ static int ccid3_hc_tx_init(struct ccid *ccid, struct sock *sk)
+ {
++ struct dccp_sock *dp = dccp_sk(sk);
+ struct ccid3_hc_tx_sock *hc = ccid_priv(ccid);
+
+ hc->tx_state = TFRC_SSTATE_NO_SENT;
+ hc->tx_hist = NULL;
+ hc->sk = sk;
+- timer_setup(&hc->tx_no_feedback_timer,
++ timer_setup(&dp->dccps_ccid_timer,
+ ccid3_hc_tx_no_feedback_timer, 0);
+ return 0;
+ }
+
+ static void ccid3_hc_tx_exit(struct sock *sk)
+ {
++ struct dccp_sock *dp = dccp_sk(sk);
+ struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk);
+
+- sk_stop_timer(sk, &hc->tx_no_feedback_timer);
++ sk_stop_timer(sk, &dp->dccps_ccid_timer);
+ tfrc_tx_hist_purge(&hc->tx_hist);
+ }
+
+--
+2.30.0
+
diff --git a/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0112-Revert-dccp-don-t-free-ccid2_hc_tx_sock-struct-in-dc.patch b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0112-Revert-dccp-don-t-free-ccid2_hc_tx_sock-struct-in-dc.patch
new file mode 100644
index 000000000000..59521fc6cd29
--- /dev/null
+++ b/sys-kernel/cairn-sources/files/5.10.9/hardened-patches/0112-Revert-dccp-don-t-free-ccid2_hc_tx_sock-struct-in-dc.patch
@@ -0,0 +1,40 @@
+From 81951627594eb1463fbc6b7da8f20410a068e88a Mon Sep 17 00:00:00 2001
+From: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
+Date: Tue, 13 Oct 2020 19:18:49 +0200
+Subject: [PATCH 112/113] Revert "dccp: don't free ccid2_hc_tx_sock struct in
+ dccp_disconnect()"
+
+This reverts commit 2677d20677314101293e6da0094ede7b5526d2b1.
+
+This fixes an issue that after disconnect, dccps_hc_tx_ccid will still be
+kept, allowing the socket to be reused as a listener socket, and the cloned
+socket will free its dccps_hc_tx_ccid, leading to a later use after free,
+when the listener socket is closed.
+
+This addresses CVE-2020-16119.
+
+Fixes: 2677d2067731 (dccp: don't free ccid2_hc_tx_sock struct in dccp_disconnect())
+Reported-by: Hadar Manor
+Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
+Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
+---
+ net/dccp/proto.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/dccp/proto.c b/net/dccp/proto.c
+index 6d705d90c614..359e848dba6c 100644
+--- a/net/dccp/proto.c
++++ b/net/dccp/proto.c
+@@ -279,7 +279,9 @@ int dccp_disconnect(struct sock *sk, int flags)
+
+ dccp_clear_xmit_timers(sk);
+ ccid_hc_rx_delete(dp->dccps_hc_rx_ccid, sk);
++ ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
+ dp->dccps_hc_rx_ccid = NULL;
++ dp->dccps_hc_tx_ccid = NULL;
+
+ __skb_queue_purge(&sk->sk_receive_queue);
+ __skb_queue_purge(&sk->sk_write_queue);
+--
+2.30.0
+