else:
return False, self.result
+ def table_print(self, with_results):
+ print('CONFIG_{:<38}|{:^13}|{:^10}|{:^20}'.format(self.name, self.expected, self.decision, self.reason), end='')
+ if with_results:
+ print('| {}'.format(self.result), end='')
+
class VerCheck:
def __init__(self, ver_expected):
self.result = 'FAIL: version < ' + str(self.ver_expected[0]) + '.' + str(self.ver_expected[1])
return False, self.result
+ def table_print(self, with_results):
+ ver_req = 'kernel version >= ' + str(self.ver_expected[0]) + '.' + str(self.ver_expected[1])
+ print('{:<91}'.format(ver_req), end='')
+ if with_results:
+ print('| {}'.format(self.result), end='')
+
+
+class PresenceCheck:
+ def __init__(self, name):
+ self.name = name
+ self.state = None
+ self.result = None
+
+ def check(self):
+ if self.state is None:
+ self.result = 'FAIL: not present'
+ return False, self.result
+ else:
+ self.result = 'OK: is present'
+ return True, self.result
+
+ def table_print(self, with_results):
+ print('CONFIG_{:<84}'.format(self.name + ' is present'), end='')
+ if with_results:
+ print('| {}'.format(self.result), end='')
+
class ComplexOptCheck:
def __init__(self, *opts):
def reason(self):
return self.opts[0].reason
+ def table_print(self, with_results):
+ if debug_mode:
+ print(' {:87}'.format('<<< ' + self.__class__.__name__ + ' >>>'), end='')
+ if with_results:
+ print('| {}'.format(self.result), end='')
+ for o in self.opts:
+ print()
+ o.table_print(with_results)
+ else:
+ o = self.opts[0]
+ o.table_print(False)
+ if with_results:
+ print('| {}'.format(self.result), end='')
+
class OR(ComplexOptCheck):
# self.opts[0] is the option that this OR-check is about.
for i, opt in enumerate(self.opts):
ret, msg = opt.check()
if ret:
- if i == 0 or not hasattr(opt, 'name'):
+ if i == 0 or not hasattr(opt, 'expected'):
self.result = opt.result
else:
self.result = 'OK: CONFIG_{} "{}"'.format(opt.name, opt.expected)
self.result = opt.result
return ret, self.result
elif not ret:
- if hasattr(opt, 'name'):
+ if hasattr(opt, 'expected'):
self.result = 'FAIL: CONFIG_{} is needed'.format(opt.name)
else:
self.result = opt.result
checklist.append(OptCheck('X86_MSR', 'is not set', 'clipos', 'cut_attack_surface')) # refers to LOCKDOWN
checklist.append(OptCheck('X86_CPUID', 'is not set', 'clipos', 'cut_attack_surface'))
checklist.append(AND(OptCheck('LDISC_AUTOLOAD', 'is not set', 'clipos', 'cut_attack_surface'), \
- VerCheck((5, 1)))) # LDISC_AUTOLOAD can be disabled since v5.1
+ PresenceCheck('LDISC_AUTOLOAD')))
checklist.append(OptCheck('AIO', 'is not set', 'grapheneos', 'cut_attack_surface'))
# checklist.append(OptCheck('LKDTM', 'm', 'my', 'feature_test'))
-def print_opt(opt, with_results):
- print('CONFIG_{:<38}|{:^13}|{:^10}|{:^20}'.format(opt.name, opt.expected, opt.decision, opt.reason), end='')
- if with_results:
- print('| {}'.format(opt.result), end='')
- print()
-
-
def print_checklist(checklist, with_results):
if json_mode:
opts = []
# table contents
for opt in checklist:
- if debug_mode and hasattr(opt, 'opts'):
- print(' {:87}'.format('<<< ' + opt.__class__.__name__ + ' >>>'), end='')
- if with_results:
- print('| {}'.format(opt.result), end='')
- print()
- for o in opt.opts:
- if hasattr(o, 'ver_expected'):
- ver_req = 'kernel version >= ' + str(o.ver_expected[0]) + '.' + str(o.ver_expected[1])
- print('{:<91}'.format(ver_req), end='')
- if with_results:
- print('| {}'.format(o.result), end='')
- print()
- else:
- print_opt(o, with_results)
- else:
- print_opt(opt, with_results)
+ opt.table_print(with_results)
+ print()
if debug_mode:
print('-' * sep_line_len)
print()
if hasattr(opt, 'opts'):
# prepare ComplexOptCheck
for o in opt.opts:
- if hasattr(o, 'name'):
+ if hasattr(o, 'state'):
o.state = parsed_options.get(o.name, None)
else:
- # prepare simple OptCheck
- if not hasattr(opt, 'name'):
- sys.exit('[!] ERROR: bad OptCheck {}'.format(vars(opt)))
+ # prepare simple check
+ if not hasattr(opt, 'state'):
+ sys.exit('[!] ERROR: bad simple check {}'.format(vars(opt)))
opt.state = parsed_options.get(opt.name, None)
opt.check()
check_config_file(config_checklist, args.config, arch)
error_count = len(list(filter(lambda opt: opt.result.startswith('FAIL'), config_checklist)))
ok_count = len(list(filter(lambda opt: opt.result.startswith('OK'), config_checklist)))
- if debug_mode:
- sys.exit(0)
- if not json_mode:
+ if not debug_mode and not json_mode:
print('[+] config check is finished: \'OK\' - {} / \'FAIL\' - {}'.format(ok_count, error_count))
sys.exit(0)
sys.exit(0)
parser.print_help()
+ sys.exit(0)
if __name__ == '__main__':
main()