X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=kconfig_hardened_check%2F__init__.py;h=a999c971df4a6eb392a1db051c42c8a8284d2cb9;hb=228f9e2b51f645266a70d86b215e9899f3bdeb9b;hp=65c47e6276bcf8e0c2b56fbd40816596795e7863;hpb=7f533e5aa62b1ca3e98807564bf5499cbcb66d08;p=kconfig-hardened-check.git diff --git a/kconfig_hardened_check/__init__.py b/kconfig_hardened_check/__init__.py index 65c47e6..a999c97 100644 --- a/kconfig_hardened_check/__init__.py +++ b/kconfig_hardened_check/__init__.py @@ -86,7 +86,10 @@ from .__about__ import __version__ TYPES_OF_CHECKS = ('kconfig', 'version') class OptCheck: - def __init__(self, reason, decision, name, expected): + # Constructor without the 'expected' parameter is for option presence checks (any value is OK) + def __init__(self, reason, decision, name, expected=None): + if not reason or not decision or not name: + sys.exit('[!] ERROR: invalid {} check for "{}"'.format(self.__class__.__name__, name)) self.name = name self.expected = expected self.decision = decision @@ -95,6 +98,15 @@ class OptCheck: self.result = None def check(self): + # handle the option presence check + if self.expected is None: + if self.state is None: + self.result = 'FAIL: not present' + else: + self.result = 'OK: is present' + return + + # handle the option value check if self.expected == self.state: self.result = 'OK' elif self.state is None: @@ -106,7 +118,11 @@ class OptCheck: self.result = 'FAIL: "' + self.state + '"' 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 self.expected is None: + expected = '' + else: + expected = self.expected + print('{:<40}|{:^7}|{:^12}|{:^10}|{:^18}'.format(self.name, self.type, expected, self.decision, self.reason), end='') if with_results: print('| {}'.format(self.result), end='') @@ -156,28 +172,6 @@ class VersionCheck: print('| {}'.format(self.result), end='') -class PresenceCheck: - def __init__(self, name, type): - self.type = type - if self.type == 'kconfig': - self.name = 'CONFIG_' + name - else: - sys.exit('[!] ERROR: unsupported type "{}" for {}'.format(type, self.__class__.__name__)) - self.state = None - self.result = None - - def check(self): - if self.state is None: - self.result = 'FAIL: not present' - return - self.result = 'OK: is present' - - def table_print(self, _mode, with_results): - print('{:<91}'.format(self.name + ' is present'), end='') - if with_results: - print('| {}'.format(self.result), end='') - - class ComplexOptCheck: def __init__(self, *opts): self.opts = opts @@ -241,11 +235,18 @@ class OR(ComplexOptCheck): for i, opt in enumerate(self.opts): 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 + self.result = opt.result + # Add more info for additional checks: + if i != 0: + if opt.result == 'OK': + self.result = 'OK: {} "{}"'.format(opt.name, opt.expected) + elif opt.result == 'OK: not found': + self.result = 'OK: {} not found'.format(opt.name) + elif opt.result == 'OK: is present': + self.result = 'OK: {} is present'.format(opt.name) + # VersionCheck provides enough info + elif not opt.result.startswith('OK: version'): + sys.exit('[!] ERROR: unexpected OK description "{}"'.format(opt.result)) return self.result = self.opts[0].result @@ -271,8 +272,10 @@ class AND(ComplexOptCheck): elif opt.result == 'FAIL: not present': self.result = 'FAIL: {} not present'.format(opt.name) else: - # This FAIL message is self-explaining. + # VersionCheck provides enough info self.result = opt.result + if not opt.result.startswith('FAIL: version'): + sys.exit('[!] ERROR: unexpected FAIL description "{}"'.format(opt.result)) return sys.exit('[!] ERROR: invalid AND check') @@ -599,7 +602,7 @@ def add_kconfig_checks(l, arch): l += [KconfigCheck('cut_attack_surface', 'clipos', 'ACPI_TABLE_UPGRADE', 'is not set')] # refers to LOCKDOWN l += [KconfigCheck('cut_attack_surface', 'clipos', 'EFI_CUSTOM_SSDT_OVERLAYS', 'is not set')] l += [AND(KconfigCheck('cut_attack_surface', 'clipos', 'LDISC_AUTOLOAD', 'is not set'), - PresenceCheck('LDISC_AUTOLOAD', 'kconfig'))] + KconfigCheck('cut_attack_surface', 'clipos', 'LDISC_AUTOLOAD'))] # option presence check if arch in ('X86_64', 'X86_32'): l += [KconfigCheck('cut_attack_surface', 'clipos', 'X86_INTEL_TSX_MODE_OFF', 'y')] # tsx=off @@ -721,6 +724,8 @@ def populate_simple_opt_with_data(opt, data, data_type): opt.state = data.get(opt.name, None) elif data_type == 'version': opt.ver = data + else: + sys.exit('[!] ERROR: unexpected data type "{}"'.format(data_type)) def populate_opt_with_data(opt, data, data_type):