X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=kconfig_hardened_check%2F__init__.py;h=0f3f3d3fe1d15659cd5694884edcc70f66024a13;hb=bdac2c22b96b3a682801674efed92fddc8a347b0;hp=3fcb5e0ed3a41f7ed4f3c7fceb78c947d9d45479;hpb=b7f680ac37b139d02f109cfff9ad9344a8415aad;p=kconfig-hardened-check.git diff --git a/kconfig_hardened_check/__init__.py b/kconfig_hardened_check/__init__.py index 3fcb5e0..0f3f3d3 100755 --- a/kconfig_hardened_check/__init__.py +++ b/kconfig_hardened_check/__init__.py @@ -98,6 +98,11 @@ class OptCheck: 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): @@ -118,6 +123,32 @@ class VerCheck: 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): @@ -144,6 +175,20 @@ class ComplexOptCheck: 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. @@ -158,7 +203,7 @@ class OR(ComplexOptCheck): 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) @@ -179,7 +224,7 @@ class AND(ComplexOptCheck): 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 @@ -433,7 +478,7 @@ def construct_checklist(checklist, arch): 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')) @@ -458,13 +503,6 @@ def construct_checklist(checklist, arch): # 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 = [] @@ -489,22 +527,8 @@ def print_checklist(checklist, with_results): # 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() @@ -515,12 +539,12 @@ def perform_checks(checklist, parsed_options): 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() @@ -611,9 +635,7 @@ def main(): 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) @@ -626,6 +648,7 @@ def main(): sys.exit(0) parser.print_help() + sys.exit(0) if __name__ == '__main__': main()