# slab_nomerge
# page_alloc.shuffle=1
# iommu=force (does it help against DMA attacks?)
+# iommu.passthrough=0
+# iommu.strict=1
# slub_debug=FZ (slow)
# init_on_alloc=1 (since v5.3)
# init_on_free=1 (since v5.3, otherwise slub_debug=P and page_poison=1)
else:
self.result = 'FAIL: "' + self.state + '"'
- if self.result.startswith('OK'):
- return True
- return False
-
def table_print(self, _mode, with_results):
print('{:<40}|{:^7}|{:^12}|{:^10}|{:^18}'.format(self.name, self.type, self.expected, self.decision, self.reason), end='')
if with_results:
def check(self):
if self.ver[0] > self.ver_expected[0]:
self.result = 'OK: version >= ' + str(self.ver_expected[0]) + '.' + str(self.ver_expected[1])
- return True
+ return
if self.ver[0] < self.ver_expected[0]:
self.result = 'FAIL: version < ' + str(self.ver_expected[0]) + '.' + str(self.ver_expected[1])
- return False
+ return
if self.ver[1] >= self.ver_expected[1]:
self.result = 'OK: version >= ' + str(self.ver_expected[0]) + '.' + str(self.ver_expected[1])
- return True
+ return
self.result = 'FAIL: version < ' + str(self.ver_expected[0]) + '.' + str(self.ver_expected[1])
- return False
def table_print(self, _mode, with_results):
ver_req = 'kernel version >= ' + str(self.ver_expected[0]) + '.' + str(self.ver_expected[1])
def check(self):
if self.state is None:
self.result = 'FAIL: not present'
- return False
+ return
self.result = 'OK: is present'
- return True
def table_print(self, _mode, with_results):
print('{:<91}'.format(self.name + ' is present'), end='')
# Use cases:
# OR(<X_is_hardened>, <X_is_disabled>)
# OR(<X_is_hardened>, <old_X_is_hardened>)
-
def check(self):
if not self.opts:
sys.exit('[!] ERROR: invalid OR check')
-
for i, opt in enumerate(self.opts):
- ret = opt.check()
- if ret:
+ opt.check()
+ if opt.result.startswith('OK'):
if opt.result == 'OK' and i != 0:
# Simple OK is not enough for additional checks, add more info:
self.result = 'OK: {} "{}"'.format(opt.name, opt.expected)
else:
self.result = opt.result
- return True
+ return
self.result = self.opts[0].result
- return False
class AND(ComplexOptCheck):
# AND(<suboption>, <main_option>)
# Suboption is not checked if checking of the main_option is failed.
# AND(<X_is_disabled>, <old_X_is_disabled>)
-
def check(self):
for i, opt in reversed(list(enumerate(self.opts))):
- ret = opt.check()
+ opt.check()
if i == 0:
self.result = opt.result
- return ret
- if not ret:
+ return
+ if not opt.result.startswith('OK'):
# This FAIL is caused by additional checks,
# and not by the main option that this AND-check is about.
# Describe the reason of the FAIL.
else:
# This FAIL message is self-explaining.
self.result = opt.result
- return False
-
+ return
sys.exit('[!] ERROR: invalid AND check')
modules_not_set = KconfigCheck('cut_attack_surface', 'kspp', 'MODULES', 'is not set')
devmem_not_set = KconfigCheck('cut_attack_surface', 'kspp', 'DEVMEM', 'is not set') # refers to LOCKDOWN
+ bpf_syscall_not_set = KconfigCheck('cut_attack_surface', 'lockdown', 'BPF_SYSCALL', 'is not set') # refers to LOCKDOWN
efi_not_set = KconfigCheck('cut_attack_surface', 'my', 'EFI', 'is not set')
# 'self_protection', 'defconfig'
if arch == 'ARM':
l += [KconfigCheck('self_protection', 'defconfig', 'CPU_SW_DOMAIN_PAN', 'y')]
l += [KconfigCheck('self_protection', 'defconfig', 'HARDEN_BRANCH_PREDICTOR', 'y')]
+ l += [KconfigCheck('self_protection', 'defconfig', 'HARDEN_BRANCH_HISTORY', 'y')]
# 'self_protection', 'kspp'
l += [KconfigCheck('self_protection', 'kspp', 'SECURITY_DMESG_RESTRICT', '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', 'GCC_PLUGIN_LATENT_ENTROPY', 'y')]
+ l += [KconfigCheck('self_protection', 'kspp', 'KFENCE', 'y')]
+ l += [KconfigCheck('self_protection', 'kspp', 'WERROR', 'y')]
+ l += [KconfigCheck('self_protection', 'kspp', 'IOMMU_DEFAULT_DMA_STRICT', 'y')]
randstruct_is_set = KconfigCheck('self_protection', 'kspp', 'GCC_PLUGIN_RANDSTRUCT', 'y')
l += [randstruct_is_set]
hardened_usercopy_is_set = KconfigCheck('self_protection', 'kspp', 'HARDENED_USERCOPY', '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
- l += [AND(KconfigCheck('self_protection', 'maintainer', 'UBSAN_SANITIZE_ALL', 'y'),
- 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
loadpin_is_set)]
# 'cut_attack_surface', 'defconfig'
- l += [KconfigCheck('cut_attack_surface', 'defconfig', 'BPF_UNPRIV_DEFAULT_OFF', 'y')] # see unprivileged_bpf_disabled
+ l += [OR(KconfigCheck('cut_attack_surface', 'defconfig', 'BPF_UNPRIV_DEFAULT_OFF', 'y'),
+ bpf_syscall_not_set)] # see unprivileged_bpf_disabled
l += [KconfigCheck('cut_attack_surface', 'defconfig', 'SECCOMP', 'y')]
l += [KconfigCheck('cut_attack_surface', 'defconfig', 'SECCOMP_FILTER', 'y')]
if arch in ('X86_64', 'ARM64', 'X86_32'):
l += [KconfigCheck('cut_attack_surface', 'clipos', 'X86_INTEL_TSX_MODE_OFF', 'y')] # tsx=off
# 'cut_attack_surface', 'lockdown'
+ l += [bpf_syscall_not_set] # refers to LOCKDOWN
l += [KconfigCheck('cut_attack_surface', 'lockdown', 'EFI_TEST', 'is not set')] # refers to LOCKDOWN
- l += [KconfigCheck('cut_attack_surface', 'lockdown', 'BPF_SYSCALL', 'is not set')] # refers to LOCKDOWN
l += [KconfigCheck('cut_attack_surface', 'lockdown', 'MMIOTRACE_TEST', 'is not set')] # refers to LOCKDOWN
l += [KconfigCheck('cut_attack_surface', 'lockdown', 'KPROBES', 'is not set')] # refers to LOCKDOWN
if option:
parsed_options[option] = value
- return parsed_options
-
def main():
# Report modes: