X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=kconfig_hardened_check%2F__init__.py;h=1ed83d50e52a452ec8fd4465f9a15cc3df60a025;hb=0ac5fe3024e03e5cc6706fb7269a507bdc489f4f;hp=218e8fd7d8504ca08aa664edf8994a1e4a05e7e3;hpb=da3daebde9537381f2acc49b5d959fdd7312cde5;p=kconfig-hardened-check.git diff --git a/kconfig_hardened_check/__init__.py b/kconfig_hardened_check/__init__.py index 218e8fd..1ed83d5 100644 --- a/kconfig_hardened_check/__init__.py +++ b/kconfig_hardened_check/__init__.py @@ -12,13 +12,11 @@ # # N.B Hardening command line parameters: # iommu=force (does it help against DMA attacks?) -# loadpin.enforce=1 # # Mitigations of CPU vulnerabilities: # Аrch-independent: # mitigations=auto,nosmt (nosmt is slow) # X86: -# spectre_v2=on # spec_store_bypass_disable=on # l1tf=full,force # l1d_flush=on (a part of the l1tf option) @@ -366,6 +364,9 @@ def add_kconfig_checks(l, arch): if arch in ('X86_64', 'ARM64'): l += [KconfigCheck('self_protection', 'defconfig', 'VMAP_STACK', 'y')] if arch in ('X86_64', 'X86_32'): + l += [KconfigCheck('self_protection', 'defconfig', 'X86_MCE', 'y')] + l += [KconfigCheck('self_protection', 'defconfig', 'X86_MCE_INTEL', 'y')] + l += [KconfigCheck('self_protection', 'defconfig', 'X86_MCE_AMD', 'y')] l += [KconfigCheck('self_protection', 'defconfig', 'MICROCODE', 'y')] # is needed for mitigating CPU bugs l += [KconfigCheck('self_protection', 'defconfig', 'RETPOLINE', 'y')] l += [OR(KconfigCheck('self_protection', 'defconfig', 'X86_SMAP', 'y'), @@ -422,6 +423,7 @@ def add_kconfig_checks(l, arch): l += [KconfigCheck('self_protection', 'kspp', 'IOMMU_DEFAULT_DMA_STRICT', 'y')] l += [KconfigCheck('self_protection', 'kspp', 'IOMMU_DEFAULT_PASSTHROUGH', 'is not set')] # true if IOMMU_DEFAULT_DMA_STRICT is set l += [KconfigCheck('self_protection', 'kspp', 'ZERO_CALL_USED_REGS', 'y')] + l += [KconfigCheck('self_protection', 'kspp', 'HW_RANDOM_TPM', 'y')] randstruct_is_set = OR(KconfigCheck('self_protection', 'kspp', 'RANDSTRUCT_FULL', 'y'), KconfigCheck('self_protection', 'kspp', 'GCC_PLUGIN_RANDSTRUCT', 'y')) l += [randstruct_is_set] @@ -448,7 +450,22 @@ def add_kconfig_checks(l, arch): # Starting from v5.11 CONFIG_PAGE_POISONING unconditionally checks # the 0xAA poison pattern on allocation. # That brings higher performance penalty. + ubsan_bounds_is_set = KconfigCheck('self_protection', 'kspp', 'UBSAN_BOUNDS', 'y') + l += [ubsan_bounds_is_set] + l += [OR(KconfigCheck('self_protection', 'kspp', 'UBSAN_LOCAL_BOUNDS', 'y'), + AND(ubsan_bounds_is_set, + cc_is_gcc))] + l += [AND(KconfigCheck('self_protection', 'kspp', 'UBSAN_TRAP', 'y'), + ubsan_bounds_is_set, + KconfigCheck('self_protection', 'kspp', 'UBSAN_SHIFT', 'is not set'), + KconfigCheck('self_protection', 'kspp', 'UBSAN_DIV_ZERO', 'is not set'), + KconfigCheck('self_protection', 'kspp', 'UBSAN_UNREACHABLE', 'is not set'), + KconfigCheck('self_protection', 'kspp', 'UBSAN_BOOL', 'is not set'), + KconfigCheck('self_protection', 'kspp', 'UBSAN_ENUM', 'is not set'), + KconfigCheck('self_protection', 'kspp', 'UBSAN_ALIGNMENT', 'is not set'))] # only array index bounds checking with traps if arch in ('X86_64', 'ARM64', 'X86_32'): + l += [AND(KconfigCheck('self_protection', 'kspp', 'UBSAN_SANITIZE_ALL', 'y'), + ubsan_bounds_is_set)] # ARCH_HAS_UBSAN_SANITIZE_ALL is not enabled for ARM stackleak_is_set = KconfigCheck('self_protection', 'kspp', 'GCC_PLUGIN_STACKLEAK', 'y') l += [AND(stackleak_is_set, gcc_plugins_support_is_set)] l += [KconfigCheck('self_protection', 'kspp', 'RANDOMIZE_KSTACK_OFFSET_DEFAULT', 'y')] @@ -465,23 +482,12 @@ def add_kconfig_checks(l, arch): l += [KconfigCheck('self_protection', 'kspp', 'HIGHMEM64G', 'y')] l += [KconfigCheck('self_protection', 'kspp', 'X86_PAE', 'y')] - # 'self_protection', 'maintainer' - ubsan_bounds_is_set = KconfigCheck('self_protection', 'maintainer', 'UBSAN_BOUNDS', 'y') # only array index bounds checking - l += [ubsan_bounds_is_set] # recommended by Kees Cook in /issues/53 - if arch in ('X86_64', 'ARM64', 'X86_32'): # ARCH_HAS_UBSAN_SANITIZE_ALL is not enabled for ARM - l += [AND(KconfigCheck('self_protection', 'maintainer', 'UBSAN_SANITIZE_ALL', 'y'), - ubsan_bounds_is_set)] # recommended by Kees Cook in /issues/53 - l += [AND(KconfigCheck('self_protection', 'maintainer', 'UBSAN_TRAP', 'y'), - ubsan_bounds_is_set)] # recommended by Kees Cook in /issues/53 - # 'self_protection', 'clipos' l += [KconfigCheck('self_protection', 'clipos', 'DEBUG_VIRTUAL', 'y')] l += [KconfigCheck('self_protection', 'clipos', 'STATIC_USERMODEHELPER', 'y')] # needs userspace support l += [OR(KconfigCheck('self_protection', 'clipos', 'EFI_DISABLE_PCI_DMA', 'y'), efi_not_set)] l += [KconfigCheck('self_protection', 'clipos', 'SLAB_MERGE_DEFAULT', 'is not set')] - l += [KconfigCheck('self_protection', 'clipos', 'RANDOM_TRUST_BOOTLOADER', 'is not set')] - l += [KconfigCheck('self_protection', 'clipos', 'RANDOM_TRUST_CPU', 'is not set')] l += [AND(KconfigCheck('self_protection', 'clipos', 'RANDSTRUCT_PERFORMANCE', 'is not set'), KconfigCheck('self_protection', 'clipos', 'GCC_PLUGIN_RANDSTRUCT_PERFORMANCE', 'is not set'), randstruct_is_set)] @@ -505,9 +511,6 @@ def add_kconfig_checks(l, arch): # 'self_protection', 'my' l += [OR(KconfigCheck('self_protection', 'my', 'RESET_ATTACK_MITIGATION', 'y'), efi_not_set)] # needs userspace support (systemd) - l += [OR(KconfigCheck('self_protection', 'my', 'UBSAN_LOCAL_BOUNDS', 'y'), - AND(ubsan_bounds_is_set, - cc_is_gcc))] if arch == 'X86_64': l += [KconfigCheck('self_protection', 'my', 'SLS', 'y')] # vs CVE-2021-26341 in Straight-Line-Speculation l += [AND(KconfigCheck('self_protection', 'my', 'AMD_IOMMU_V2', 'y'), @@ -528,15 +531,12 @@ def add_kconfig_checks(l, arch): l += [KconfigCheck('security_policy', 'kspp', 'SECURITY_YAMA', 'y')] l += [KconfigCheck('security_policy', 'kspp', 'SECURITY_LANDLOCK', 'y')] l += [KconfigCheck('security_policy', 'kspp', 'SECURITY_SELINUX_DISABLE', 'is not set')] - l += [KconfigCheck('security_policy', 'clipos', 'SECURITY_LOCKDOWN_LSM', 'y')] - l += [KconfigCheck('security_policy', 'clipos', 'SECURITY_LOCKDOWN_LSM_EARLY', 'y')] - l += [KconfigCheck('security_policy', 'clipos', 'LOCK_DOWN_KERNEL_FORCE_CONFIDENTIALITY', 'y')] - l += [KconfigCheck('security_policy', 'my', 'SECURITY_WRITABLE_HOOKS', 'is not set')] # refers to SECURITY_SELINUX_DISABLE - l += [KconfigCheck('security_policy', 'my', 'SECURITY_SAFESETID', 'y')] - loadpin_is_set = KconfigCheck('security_policy', 'my', 'SECURITY_LOADPIN', 'y') - l += [loadpin_is_set] # needs userspace support - l += [AND(KconfigCheck('security_policy', 'my', 'SECURITY_LOADPIN_ENFORCE', 'y'), - loadpin_is_set)] + l += [KconfigCheck('security_policy', 'kspp', 'SECURITY_SELINUX_BOOTPARAM', 'is not set')] + l += [KconfigCheck('security_policy', 'kspp', 'SECURITY_SELINUX_DEVELOP', 'is not set')] + l += [KconfigCheck('security_policy', 'kspp', 'SECURITY_LOCKDOWN_LSM', 'y')] + l += [KconfigCheck('security_policy', 'kspp', 'SECURITY_LOCKDOWN_LSM_EARLY', 'y')] + l += [KconfigCheck('security_policy', 'kspp', 'LOCK_DOWN_KERNEL_FORCE_CONFIDENTIALITY', 'y')] + l += [KconfigCheck('security_policy', 'kspp', 'SECURITY_WRITABLE_HOOKS', 'is not set')] # refers to SECURITY_SELINUX_DISABLE # 'cut_attack_surface', 'defconfig' l += [OR(KconfigCheck('cut_attack_surface', 'defconfig', 'BPF_UNPRIV_DEFAULT_OFF', 'y'), @@ -638,6 +638,7 @@ def add_kconfig_checks(l, arch): l += [KconfigCheck('cut_attack_surface', 'clipos', 'X86_IOPL_IOPERM', 'is not set')] # refers to LOCKDOWN l += [KconfigCheck('cut_attack_surface', 'clipos', 'ACPI_TABLE_UPGRADE', 'is not set')] # refers to LOCKDOWN l += [KconfigCheck('cut_attack_surface', 'clipos', 'EFI_CUSTOM_SSDT_OVERLAYS', 'is not set')] + l += [KconfigCheck('cut_attack_surface', 'clipos', 'COREDUMP', 'is not set')] # cut userspace attack surface l += [AND(KconfigCheck('cut_attack_surface', 'clipos', 'LDISC_AUTOLOAD', 'is not set'), KconfigCheck('cut_attack_surface', 'clipos', 'LDISC_AUTOLOAD'))] # option presence check if arch in ('X86_64', 'X86_32'): @@ -698,6 +699,12 @@ def add_cmdline_checks(l, arch): # very complex and not give a 100% guarantee anyway. # 'self_protection', 'defconfig' + l += [CmdlineCheck('self_protection', 'defconfig', 'nosmep', 'is not set')] + l += [CmdlineCheck('self_protection', 'defconfig', 'nosmap', 'is not set')] + l += [CmdlineCheck('self_protection', 'defconfig', 'nokaslr', 'is not set')] + l += [CmdlineCheck('self_protection', 'defconfig', 'nopti', 'is not set')] + l += [CmdlineCheck('self_protection', 'defconfig', 'nospectre_v1', 'is not set')] + l += [CmdlineCheck('self_protection', 'defconfig', 'nospectre_v2', 'is not set')] if arch == 'ARM64': l += [OR(CmdlineCheck('self_protection', 'defconfig', 'rodata', 'full'), AND(KconfigCheck('self_protection', 'defconfig', 'RODATA_FULL_DEFAULT_ENABLED', 'y'), @@ -726,26 +733,26 @@ def add_cmdline_checks(l, arch): AND(KconfigCheck('self_protection', 'kspp', 'IOMMU_DEFAULT_PASSTHROUGH', 'is not set'), CmdlineCheck('self_protection', 'kspp', 'iommu.passthrough', 'is not set')))] # The cmdline checks compatible with the kconfig recommendations of the KSPP project... - l += [CmdlineCheck('self_protection', 'kspp', 'nokaslr', 'is not set')] l += [OR(CmdlineCheck('self_protection', 'kspp', 'hardened_usercopy', '1'), AND(KconfigCheck('self_protection', 'kspp', 'HARDENED_USERCOPY', 'y'), CmdlineCheck('self_protection', 'kspp', 'hardened_usercopy', 'is not set')))] l += [OR(CmdlineCheck('self_protection', 'kspp', 'slab_common.usercopy_fallback', '0'), AND(KconfigCheck('self_protection', 'kspp', 'HARDENED_USERCOPY_FALLBACK', 'is not set'), - CmdlineCheck('self_protection', 'kspp', 'slab_common.usercopy_fallback', 'is not set')))] # ... the end + CmdlineCheck('self_protection', 'kspp', 'slab_common.usercopy_fallback', 'is not set')))] + # ... the end if arch in ('X86_64', 'ARM64', 'X86_32'): l += [OR(CmdlineCheck('self_protection', 'kspp', 'randomize_kstack_offset', '1'), AND(KconfigCheck('self_protection', 'kspp', 'RANDOMIZE_KSTACK_OFFSET_DEFAULT', 'y'), CmdlineCheck('self_protection', 'kspp', 'randomize_kstack_offset', 'is not set')))] if arch in ('X86_64', 'X86_32'): - l += [CmdlineCheck('self_protection', 'kspp', 'pti', 'on')] + l += [AND(CmdlineCheck('self_protection', 'kspp', 'pti', 'on'), + CmdlineCheck('self_protection', 'defconfig', 'nopti', 'is not set'))] # 'self_protection', 'clipos' l += [CmdlineCheck('self_protection', 'clipos', 'page_alloc.shuffle', '1')] - - # 'self_protection', 'my' - l += [CmdlineCheck('self_protection', 'my', 'nosmep', 'is not set')] - l += [CmdlineCheck('self_protection', 'my', 'nosmap', 'is not set')] + if arch in ('X86_64', 'X86_32'): + l += [AND(CmdlineCheck('self_protection', 'clipos', 'spectre_v2', 'on'), + CmdlineCheck('self_protection', 'defconfig', 'nospectre_v2', 'is not set'))] # 'cut_attack_surface', 'kspp' if arch == 'X86_64': @@ -905,6 +912,9 @@ def normalize_cmdline_options(option, value): if option == 'pti': # See pti_check_boottime_disable() in linux/arch/x86/mm/pti.c return value + if option == 'spectre_v2': + # See spectre_v2_parse_cmdline() in linux/arch/x86/kernel/cpu/bugs.c + return value if option == 'debugfs': # See debugfs_kernel() in fs/debugfs/inode.c return value