# Please don't cry if my Python code looks like C.
#
#
-# N.B Missing hardening command line parameters:
-# iommu=force (does it help against DMA attacks?)
-#
-# Hardware tag-based KASAN with arm64 Memory Tagging Extension (MTE):
-# kasan=on
-# kasan.stacktrace=off
-# kasan.fault=panic
-#
# N.B. Hardening sysctls:
# kernel.kptr_restrict=2 (or 1?)
# kernel.dmesg_restrict=1 (also see the kconfig option)
'invalid expected value "{}" for "{}" check (1)'.format(expected, name)
val_len = len(expected.split())
if val_len == 3:
- assert(expected == 'is not set' or expected == 'is not off'), \
+ assert(expected in ('is not set', 'is not off')), \
'invalid expected value "{}" for "{}" check (2)'.format(expected, name)
elif val_len == 2:
assert(expected == 'is present'), \
self.result = 'FAIL: {} is not "{}"'.format(opt.name, opt.expected)
elif opt.result == 'FAIL: is not present':
self.result = 'FAIL: {} is not present'.format(opt.name)
- elif opt.result == 'FAIL: is off' or opt.result == 'FAIL: is off, "0"':
+ elif opt.result in ('FAIL: is off', 'FAIL: is off, "0"'):
self.result = 'FAIL: {} is off'.format(opt.name)
elif opt.result == 'FAIL: is off, not found':
self.result = 'FAIL: {} is off, not found'.format(opt.name)
VersionCheck((5, 5)))] # REFCOUNT_FULL is enabled by default since v5.5
if arch in ('X86_64', 'ARM64', 'X86_32'):
l += [KconfigCheck('self_protection', 'defconfig', 'RANDOMIZE_BASE', 'y')]
- if arch in ('X86_64', 'ARM64'):
+ if arch in ('X86_64', 'ARM64', 'ARM'):
l += [KconfigCheck('self_protection', 'defconfig', 'VMAP_STACK', 'y')]
if arch in ('X86_64', 'X86_32'):
l += [KconfigCheck('self_protection', 'defconfig', 'DEBUG_WX', 'y')]
l += [OR(KconfigCheck('self_protection', 'defconfig', 'X86_UMIP', 'y'),
KconfigCheck('self_protection', 'defconfig', 'X86_INTEL_UMIP', 'y'))]
if arch in ('ARM64', 'ARM'):
+ l += [KconfigCheck('self_protection', 'defconfig', 'IOMMU_DEFAULT_DMA_STRICT', 'y')]
+ l += [KconfigCheck('self_protection', 'defconfig', 'IOMMU_DEFAULT_PASSTHROUGH', 'is not set')] # true if IOMMU_DEFAULT_DMA_STRICT is set
l += [KconfigCheck('self_protection', 'defconfig', 'STACKPROTECTOR_PER_TASK', 'y')]
if arch == 'X86_64':
l += [KconfigCheck('self_protection', 'defconfig', 'PAGE_TABLE_ISOLATION', 'y')]
l += [KconfigCheck('self_protection', 'kspp', 'DEBUG_NOTIFIERS', 'y')]
l += [KconfigCheck('self_protection', 'kspp', 'INIT_ON_ALLOC_DEFAULT_ON', 'y')]
l += [KconfigCheck('self_protection', 'kspp', 'KFENCE', 'y')]
- 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')]
l += [KconfigCheck('self_protection', 'kspp', 'STATIC_USERMODEHELPER', 'y')] # needs userspace support
- l += [KconfigCheck('self_protection', 'kspp', 'SCHED_CORE', 'y')]
randstruct_is_set = OR(KconfigCheck('self_protection', 'kspp', 'RANDSTRUCT_FULL', 'y'),
KconfigCheck('self_protection', 'kspp', 'GCC_PLUGIN_RANDSTRUCT', 'y'))
l += [randstruct_is_set]
l += [AND(KconfigCheck('self_protection', 'kspp', 'CFI_PERMISSIVE', 'is not set'),
cfi_clang_is_set)]
if arch in ('X86_64', 'X86_32'):
+ l += [KconfigCheck('self_protection', 'kspp', 'SCHED_CORE', 'y')]
l += [KconfigCheck('self_protection', 'kspp', 'DEFAULT_MMAP_MIN_ADDR', '65536')]
+ 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 += [AND(KconfigCheck('self_protection', 'kspp', 'INTEL_IOMMU_DEFAULT_ON', 'y'),
iommu_support_is_set)]
if arch in ('ARM64', 'ARM'):
if arch == 'ARM64':
l += [KconfigCheck('self_protection', 'kspp', 'ARM64_SW_TTBR0_PAN', 'y')]
l += [KconfigCheck('self_protection', 'kspp', 'SHADOW_CALL_STACK', 'y')]
- l += [KconfigCheck('self_protection', 'kspp', 'KASAN_HW_TAGS', 'y')]
+ l += [KconfigCheck('self_protection', 'kspp', 'KASAN_HW_TAGS', 'y')] # see also: kasan=on, kasan.stacktrace=off, kasan.fault=panic
if arch == 'X86_32':
l += [KconfigCheck('self_protection', 'kspp', 'PAGE_TABLE_ISOLATION', 'y')]
l += [KconfigCheck('self_protection', 'kspp', 'HIGHMEM64G', 'y')]
CmdlineCheck('self_protection', 'defconfig', 'retbleed', 'is not set'))]
l += [OR(CmdlineCheck('self_protection', 'defconfig', 'kpti', 'is not off'),
CmdlineCheck('self_protection', 'defconfig', 'kpti', 'is not set'))]
+ l += [OR(CmdlineCheck('self_protection', 'defconfig', 'kvm.nx_huge_pages', 'is not off'),
+ CmdlineCheck('self_protection', 'defconfig', 'kvm.nx_huge_pages', 'is not set'))]
if arch == 'ARM64':
l += [OR(CmdlineCheck('self_protection', 'defconfig', 'ssbd', 'kernel'),
CmdlineCheck('self_protection', 'my', 'ssbd', 'force-on'),
CmdlineCheck('self_protection', 'kspp', 'slub_debug', 'P')))]
l += [OR(CmdlineCheck('self_protection', 'kspp', 'slab_nomerge', 'is present'),
AND(KconfigCheck('self_protection', 'clipos', 'SLAB_MERGE_DEFAULT', 'is not set'),
- CmdlineCheck('self_protection', 'kspp', 'slab_merge', 'is not set')))]
+ CmdlineCheck('self_protection', 'kspp', 'slab_merge', 'is not set'),
+ CmdlineCheck('self_protection', 'clipos', 'slub_merge', 'is not set')))]
l += [OR(CmdlineCheck('self_protection', 'kspp', 'iommu.strict', '1'),
AND(KconfigCheck('self_protection', 'kspp', 'IOMMU_DEFAULT_DMA_STRICT', 'y'),
CmdlineCheck('self_protection', 'kspp', 'iommu.strict', 'is not set')))]
# 'self_protection', 'clipos'
l += [CmdlineCheck('self_protection', 'clipos', 'page_alloc.shuffle', '1')]
+ if arch in ('X86_64', 'X86_32'):
+ l += [CmdlineCheck('self_protection', 'clipos', 'iommu', 'force')]
# 'cut_attack_surface', 'defconfig'
if arch in ('X86_64', 'X86_32'):
parse_cmdline_file(parsed_cmdline_options, args.cmdline)
populate_with_data(config_checklist, parsed_cmdline_options, 'cmdline')
- # now everything is ready for performing the checks
+ # now everything is ready, perform the checks
perform_checks(config_checklist)
- # finally print the results
if mode == 'verbose':
- print_unknown_options(config_checklist, parsed_kconfig_options)
+ # print the parsed options without the checks (for debugging)
+ all_parsed_options = parsed_kconfig_options # assignment does not copy
+ all_parsed_options.update(parsed_cmdline_options)
+ print_unknown_options(config_checklist, all_parsed_options)
+
+ # finally print the results
print_checklist(mode, config_checklist, True)
sys.exit(0)