#
# N.B. Hardening sysctl's:
# net.core.bpf_jit_harden
+# kptr_restrict=2
import sys
from argparse import ArgumentParser
self.result = opt.result
return ret, self.result
elif not ret:
- # The requirement is not met. Skip the check.
- return False, ''
+ self.result = 'FAIL: CONFIG_{} is needed'.format(opt.name)
+ return False, self.result
sys.exit('[!] ERROR: invalid AND check')
checklist.append(OptCheck('SCHED_STACK_END_CHECK', 'y', 'kspp', 'self_protection'))
checklist.append(OptCheck('SLAB_FREELIST_HARDENED', 'y', 'kspp', 'self_protection'))
checklist.append(OptCheck('SLAB_FREELIST_RANDOM', 'y', 'kspp', 'self_protection'))
- checklist.append(OptCheck('HARDENED_USERCOPY', 'y', 'kspp', 'self_protection'))
- checklist.append(OptCheck('HARDENED_USERCOPY_FALLBACK', 'is not set', 'kspp', 'self_protection'))
checklist.append(OptCheck('FORTIFY_SOURCE', 'y', 'kspp', 'self_protection'))
checklist.append(OptCheck('GCC_PLUGINS', 'y', 'kspp', 'self_protection'))
checklist.append(OptCheck('GCC_PLUGIN_RANDSTRUCT', 'y', 'kspp', 'self_protection'))
checklist.append(OptCheck('DEBUG_NOTIFIERS', 'y', 'kspp', 'self_protection'))
page_poisoning_is_set = OptCheck('PAGE_POISONING', 'y', 'kspp', 'self_protection')
checklist.append(page_poisoning_is_set)
+ hardened_usercopy_is_set = OptCheck('HARDENED_USERCOPY', 'y', 'kspp', 'self_protection')
+ checklist.append(hardened_usercopy_is_set)
+ checklist.append(AND(OptCheck('HARDENED_USERCOPY_FALLBACK', 'is not set', 'kspp', 'self_protection'), \
+ hardened_usercopy_is_set))
checklist.append(OR(OptCheck('MODULE_SIG', 'y', 'kspp', 'self_protection'), \
modules_not_set))
checklist.append(OR(OptCheck('MODULE_SIG_ALL', 'y', 'kspp', 'self_protection'), \
page_poisoning_is_set))
if debug_mode or arch == 'X86_32':
checklist.append(OptCheck('PAGE_TABLE_ISOLATION', 'y', 'my', 'self_protection'))
+ if debug_mode or arch == 'ARM':
+ checklist.append(OptCheck('STACKPROTECTOR_PER_TASK', 'y', 'my', 'self_protection'))
if debug_mode or arch == 'X86_64' or arch == 'ARM64' or arch == 'X86_32':
checklist.append(OptCheck('SECURITY', 'y', 'defconfig', 'security_policy'))
if debug_mode or arch == 'X86_32':
checklist.append(OptCheck('MODIFY_LDT_SYSCALL', 'is not set', 'my', 'cut_attack_surface'))
+ if debug_mode or arch == 'ARM64':
+ checklist.append(OptCheck('ARM64_PTR_AUTH', 'y', 'defconfig', 'userspace_protection'))
if debug_mode or arch == 'X86_64' or arch == 'ARM64':
checklist.append(OptCheck('ARCH_MMAP_RND_BITS', '32', 'my', 'userspace_protection'))
if debug_mode or arch == 'X86_32' or arch == 'ARM':
'option name', 'desired val', 'decision', 'reason', 'check result'))
print(' ' + '=' * 115)
for opt in checklist:
- if opt.result:
- print(' CONFIG_{:<32}|{:^13}|{:^10}|{:^20}||{:^28}'.format(
- opt.name, opt.expected, opt.decision, opt.reason, opt.result))
+ print(' CONFIG_{:<32}|{:^13}|{:^10}|{:^20}||{:^28}'.format(
+ opt.name, opt.expected, opt.decision, opt.reason, opt.result))
print()
construct_checklist(arch)
check_config_file(args.config)
- error_count = len(list(filter(lambda opt: opt.result and opt.result.startswith('FAIL'), checklist)))
+ error_count = len(list(filter(lambda opt: opt.result.startswith('FAIL'), checklist)))
+ ok_count = len(list(filter(lambda opt: opt.result.startswith('OK'), checklist)))
if debug_mode:
sys.exit(0)
- if error_count == 0:
- print('[+] config check is PASSED')
- sys.exit(0)
- else:
- sys.exit('[-] config check is NOT PASSED: {} errors'.format(error_count))
+ print('[+] config check is finished: \'OK\' - {} / \'FAIL\' - {}'.format(ok_count, error_count))
+ sys.exit(0)
if args.print:
arch = args.print