X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=kconfig_hardened_check%2F__init__.py;h=3e3997d867dbccb6f6f115dd791745b01e6e926c;hb=0a9d3d0f700260d38a39cc1735ee5bd63d3e8f36;hp=bc63334f7852d1f993b7da26124153af539473a8;hpb=d0c0338fb4c85ba7bdc067b890672319d3f1fb1c;p=kconfig-hardened-check.git diff --git a/kconfig_hardened_check/__init__.py b/kconfig_hardened_check/__init__.py index bc63334..3e3997d 100644 --- a/kconfig_hardened_check/__init__.py +++ b/kconfig_hardened_check/__init__.py @@ -77,12 +77,30 @@ SIMPLE_OPTION_TYPES = ('kconfig', 'version', 'cmdline') class OptCheck: # Constructor without the 'expected' parameter is for option presence checks (any value is OK) def __init__(self, reason, decision, name, expected=None): - assert(reason and decision and name), \ - 'invalid {} check for "{}"'.format(self.__class__.__name__, name) + assert(name and name == name.strip() and len(name.split()) == 1), \ + 'invalid name "{}" for {}'.format(name, self.__class__.__name__) self.name = name - self.expected = expected + + assert(decision and decision == decision.strip() and len(decision.split()) == 1), \ + 'invalid decision "{}" for "{}" check'.format(decision, name) self.decision = decision + + assert(reason and reason == reason.strip() and len(reason.split()) == 1), \ + 'invalid reason "{}" for "{}" check'.format(reason, name) self.reason = reason + + if expected: + assert(expected == expected.strip()), \ + 'invalid expected value "{}" for "{}" check (1)'.format(expected, name) + val_len = len(expected.split()) + if val_len == 3: + assert(expected == 'is not set' or expected == 'is not off'), \ + 'invalid expected value "{}" for "{}" check (2)'.format(expected, name) + else: + assert(val_len == 1), \ + 'invalid expected value "{}" for "{}" check (3)'.format(expected, name) + self.expected = expected + self.state = None self.result = None @@ -94,19 +112,29 @@ class OptCheck: # handle the option presence check if self.expected is None: if self.state is None: - self.result = 'FAIL: not present' + self.result = 'FAIL: is not present' else: self.result = 'OK: is present' return + # handle the 'is not off' option check + if self.expected == 'is not off': + if self.state == 'off': + self.result = 'FAIL: is off' + elif self.state is None: + self.result = 'FAIL: is off, not found' + else: + self.result = 'OK: is not off, "' + self.state + '"' + return + # handle the option value check if self.expected == self.state: self.result = 'OK' elif self.state is None: if self.expected == 'is not set': - self.result = 'OK: not found' + self.result = 'OK: is not found' else: - self.result = 'FAIL: not found' + self.result = 'FAIL: is not found' else: self.result = 'FAIL: "' + self.state + '"' @@ -144,6 +172,8 @@ class CmdlineCheck(OptCheck): class VersionCheck: def __init__(self, ver_expected): + assert(ver_expected and isinstance(ver_expected, tuple) and len(ver_expected) == 2), \ + 'invalid version "{}" for VersionCheck'.format(ver_expected) self.ver_expected = ver_expected self.ver = () self.result = None @@ -228,11 +258,13 @@ class OR(ComplexOptCheck): # 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) + self.result = 'OK: {} is "{}"'.format(opt.name, opt.expected) + elif opt.result == 'OK: is not found': + self.result = 'OK: {} is not found'.format(opt.name) elif opt.result == 'OK: is present': self.result = 'OK: {} is present'.format(opt.name) + elif opt.result.startswith('OK: is not off'): + self.result = 'OK: {} is not off'.format(opt.name) else: # VersionCheck provides enough info assert(opt.result.startswith('OK: version')), \ @@ -257,10 +289,14 @@ class AND(ComplexOptCheck): # 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. - if opt.result.startswith('FAIL: \"') or opt.result == 'FAIL: not found': - self.result = 'FAIL: {} not "{}"'.format(opt.name, opt.expected) - elif opt.result == 'FAIL: not present': - self.result = 'FAIL: {} not present'.format(opt.name) + if opt.result.startswith('FAIL: \"') or opt.result == 'FAIL: is not found': + self.result = 'FAIL: {} is not "{}"'.format(opt.name, opt.expected) + elif opt.result == 'FAIL: is not present': + self.result = 'FAIL: {} is not present'.format(opt.name) + elif opt.result == 'FAIL: is off': + self.result = 'FAIL: {} is off'.format(opt.name) + elif opt.result == 'FAIL: is off, not found': + self.result = 'FAIL: {} is off, not found'.format(opt.name) else: # VersionCheck provides enough info self.result = opt.result @@ -387,6 +423,7 @@ def add_kconfig_checks(l, arch): l += [KconfigCheck('self_protection', 'defconfig', 'ARM64_PAN', 'y')] l += [KconfigCheck('self_protection', 'defconfig', 'ARM64_EPAN', 'y')] l += [KconfigCheck('self_protection', 'defconfig', 'UNMAP_KERNEL_AT_EL0', 'y')] + l += [KconfigCheck('self_protection', 'defconfig', 'ARM64_E0PD', 'y')] l += [OR(KconfigCheck('self_protection', 'defconfig', 'HARDEN_EL2_VECTORS', 'y'), AND(KconfigCheck('self_protection', 'defconfig', 'RANDOMIZE_BASE', 'y'), VersionCheck((5, 9))))] # HARDEN_EL2_VECTORS was included in RANDOMIZE_BASE in v5.9 @@ -426,6 +463,7 @@ def add_kconfig_checks(l, arch): l += [KconfigCheck('self_protection', 'kspp', 'ZERO_CALL_USED_REGS', 'y')] l += [KconfigCheck('self_protection', 'kspp', 'HW_RANDOM_TPM', 'y')] l += [KconfigCheck('self_protection', 'kspp', 'STATIC_USERMODEHELPER', 'y')] # needs userspace support + l += [KconfigCheck('self_protection', 'kspp', 'SCHED_CORE', 'y')] randstruct_is_set = OR(KconfigCheck('self_protection', 'kspp', 'RANDSTRUCT_FULL', 'y'), KconfigCheck('self_protection', 'kspp', 'GCC_PLUGIN_RANDSTRUCT', 'y')) l += [randstruct_is_set] @@ -490,7 +528,6 @@ def add_kconfig_checks(l, arch): l += [AND(KconfigCheck('self_protection', 'kspp', 'CFI_PERMISSIVE', 'is not set'), cfi_clang_is_set)] if arch in ('X86_64', 'X86_32'): - l += [KconfigCheck('self_protection', 'kspp', 'SCHED_CORE', 'y')] l += [KconfigCheck('self_protection', 'kspp', 'DEFAULT_MMAP_MIN_ADDR', '65536')] l += [AND(KconfigCheck('self_protection', 'kspp', 'INTEL_IOMMU_DEFAULT_ON', 'y'), iommu_support_is_set)]