X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=kconfig_hardened_check%2F__init__.py;h=4dc9fe721058df14ccdd050b308387714dcb43eb;hb=d361925ba8e7c1f712615e12d4eff678f1f4d59b;hp=3ac7aa7e1ba85f1e79924ee62f95077cdbd94b07;hpb=6ee763d040dc0988da257b19ad8c88d2ab9328cc;p=kconfig-hardened-check.git diff --git a/kconfig_hardened_check/__init__.py b/kconfig_hardened_check/__init__.py index 3ac7aa7..4dc9fe7 100644 --- a/kconfig_hardened_check/__init__.py +++ b/kconfig_hardened_check/__init__.py @@ -16,10 +16,7 @@ # Mitigations of CPU vulnerabilities: # Аrch-independent: # X86: -# spec_store_bypass_disable=on -# l1tf=full,force # l1d_flush=on (a part of the l1tf option) -# mds=full,nosmt # tsx=off # ARM64: # kpti=on @@ -74,8 +71,7 @@ from .__about__ import __version__ 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): + def __init__(self, reason, decision, name, expected): assert(name and name == name.strip() and len(name.split()) == 1), \ 'invalid name "{}" for {}'.format(name, self.__class__.__name__) self.name = name @@ -88,16 +84,18 @@ class OptCheck: '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'), \ + assert(expected and 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), \ + elif val_len == 2: + assert(expected == 'is present'), \ 'invalid expected value "{}" for "{}" check (3)'.format(expected, name) + else: + assert(val_len == 1), \ + 'invalid expected value "{}" for "{}" check (4)'.format(expected, name) self.expected = expected self.state = None @@ -108,8 +106,8 @@ class OptCheck: return None def check(self): - # handle the option presence check - if self.expected is None: + # handle the 'is present' check + if self.expected == 'is present': if self.state is None: self.result = 'FAIL: is not present' else: @@ -138,11 +136,7 @@ class OptCheck: self.result = 'FAIL: "' + self.state + '"' def table_print(self, _mode, with_results): - 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='') + print('{:<40}|{:^7}|{:^12}|{:^10}|{:^18}'.format(self.name, self.type, self.expected, self.decision, self.reason), end='') if with_results: print('| {}'.format(self.result), end='') @@ -599,7 +593,7 @@ def add_kconfig_checks(l, arch): l += [OR(KconfigCheck('cut_attack_surface', 'kspp', 'IO_STRICT_DEVMEM', 'y'), devmem_not_set)] # refers to LOCKDOWN l += [AND(KconfigCheck('cut_attack_surface', 'kspp', 'LDISC_AUTOLOAD', 'is not set'), - KconfigCheck('cut_attack_surface', 'kspp', 'LDISC_AUTOLOAD'))] # option presence check + KconfigCheck('cut_attack_surface', 'kspp', 'LDISC_AUTOLOAD', 'is present'))] if arch == 'ARM': l += [OR(KconfigCheck('cut_attack_surface', 'kspp', 'STRICT_DEVMEM', 'y'), devmem_not_set)] # refers to LOCKDOWN @@ -735,8 +729,27 @@ def add_cmdline_checks(l, arch): l += [CmdlineCheck('self_protection', 'defconfig', 'nopti', 'is not set')] l += [CmdlineCheck('self_protection', 'defconfig', 'nospectre_v1', 'is not set')] l += [CmdlineCheck('self_protection', 'defconfig', 'nospectre_v2', 'is not set')] + l += [CmdlineCheck('self_protection', 'defconfig', 'nospec_store_bypass_disable', 'is not set')] l += [OR(CmdlineCheck('self_protection', 'defconfig', 'mitigations', 'is not off'), CmdlineCheck('self_protection', 'defconfig', 'mitigations', 'is not set'))] + l += [OR(CmdlineCheck('self_protection', 'defconfig', 'spectre_v2', 'is not off'), + CmdlineCheck('self_protection', 'defconfig', 'spectre_v2', 'is not set'))] + l += [OR(CmdlineCheck('self_protection', 'defconfig', 'spectre_v2_user', 'is not off'), + CmdlineCheck('self_protection', 'defconfig', 'spectre_v2_user', 'is not set'))] + l += [OR(CmdlineCheck('self_protection', 'defconfig', 'spec_store_bypass_disable', 'is not off'), + CmdlineCheck('self_protection', 'defconfig', 'spec_store_bypass_disable', 'is not set'))] + l += [OR(CmdlineCheck('self_protection', 'defconfig', 'l1tf', 'is not off'), + CmdlineCheck('self_protection', 'defconfig', 'l1tf', 'is not set'))] + l += [OR(CmdlineCheck('self_protection', 'defconfig', 'mds', 'is not off'), + CmdlineCheck('self_protection', 'defconfig', 'mds', 'is not set'))] + l += [OR(CmdlineCheck('self_protection', 'defconfig', 'tsx_async_abort', 'is not off'), + CmdlineCheck('self_protection', 'defconfig', 'tsx_async_abort', 'is not set'))] + l += [OR(CmdlineCheck('self_protection', 'defconfig', 'srbds', 'is not off'), + CmdlineCheck('self_protection', 'defconfig', 'srbds', 'is not set'))] + l += [OR(CmdlineCheck('self_protection', 'defconfig', 'mmio_stale_data', 'is not off'), + CmdlineCheck('self_protection', 'defconfig', 'mmio_stale_data', 'is not set'))] + l += [OR(CmdlineCheck('self_protection', 'defconfig', 'retbleed', 'is not off'), + CmdlineCheck('self_protection', 'defconfig', 'retbleed', 'is not set'))] if arch == 'ARM64': l += [OR(CmdlineCheck('self_protection', 'defconfig', 'rodata', 'full'), AND(KconfigCheck('self_protection', 'defconfig', 'RODATA_FULL_DEFAULT_ENABLED', 'y'), @@ -746,7 +759,7 @@ def add_cmdline_checks(l, arch): CmdlineCheck('self_protection', 'defconfig', 'rodata', 'is not set'))] # 'self_protection', 'kspp' - l += [CmdlineCheck('self_protection', 'kspp', 'nosmt')] # option presence check + l += [CmdlineCheck('self_protection', 'kspp', 'nosmt', 'is present')] l += [OR(CmdlineCheck('self_protection', 'kspp', 'init_on_alloc', '1'), AND(KconfigCheck('self_protection', 'kspp', 'INIT_ON_ALLOC_DEFAULT_ON', 'y'), CmdlineCheck('self_protection', 'kspp', 'init_on_alloc', 'is not set')))] @@ -756,9 +769,9 @@ def add_cmdline_checks(l, arch): AND(CmdlineCheck('self_protection', 'kspp', 'page_poison', '1'), KconfigCheck('self_protection', 'kspp', 'PAGE_POISONING_ZERO', 'y'), CmdlineCheck('self_protection', 'kspp', 'slub_debug', 'P')))] - l += [OR(CmdlineCheck('self_protection', 'kspp', 'slab_nomerge'), + l += [OR(CmdlineCheck('self_protection', 'kspp', 'slab_nomerge', 'is present'), AND(KconfigCheck('self_protection', 'clipos', 'SLAB_MERGE_DEFAULT', 'is not set'), - CmdlineCheck('self_protection', 'kspp', 'slab_merge', 'is not set')))] # option presence check + CmdlineCheck('self_protection', 'kspp', 'slab_merge', 'is not set')))] l += [OR(CmdlineCheck('self_protection', 'kspp', 'iommu.strict', '1'), AND(KconfigCheck('self_protection', 'kspp', 'IOMMU_DEFAULT_DMA_STRICT', 'y'), CmdlineCheck('self_protection', 'kspp', 'iommu.strict', 'is not set')))] @@ -783,9 +796,6 @@ def add_cmdline_checks(l, arch): # 'self_protection', 'clipos' l += [CmdlineCheck('self_protection', 'clipos', 'page_alloc.shuffle', '1')] - if arch in ('X86_64', 'X86_32'): - l += [AND(CmdlineCheck('self_protection', 'clipos', 'spectre_v2', 'on'), - CmdlineCheck('self_protection', 'defconfig', 'nospectre_v2', 'is not set'))] # 'cut_attack_surface', 'kspp' if arch == 'X86_64': @@ -942,17 +952,41 @@ def parse_kconfig_file(parsed_options, fname): def normalize_cmdline_options(option, value): # Don't normalize the cmdline option values if # the Linux kernel doesn't use kstrtobool() for them + if option == 'debugfs': + # See debugfs_kernel() in fs/debugfs/inode.c + return value + if option == 'mitigations': + # See mitigations_parse_cmdline() in kernel/cpu.c + return value if option == 'pti': - # See pti_check_boottime_disable() in linux/arch/x86/mm/pti.c + # See pti_check_boottime_disable() in arch/x86/mm/pti.c return value if option == 'spectre_v2': - # See spectre_v2_parse_cmdline() in linux/arch/x86/kernel/cpu/bugs.c + # See spectre_v2_parse_cmdline() in arch/x86/kernel/cpu/bugs.c return value - if option == 'debugfs': - # See debugfs_kernel() in fs/debugfs/inode.c + if option == 'spectre_v2_user': + # See spectre_v2_parse_user_cmdline() in arch/x86/kernel/cpu/bugs.c return value - if option == 'mitigations': - # See mitigations_parse_cmdline() in linux/kernel/cpu.c + if option == 'spec_store_bypass_disable': + # See ssb_parse_cmdline() in arch/x86/kernel/cpu/bugs.c + return value + if option == 'l1tf': + # See l1tf_cmdline() in arch/x86/kernel/cpu/bugs.c + return value + if option == 'mds': + # See mds_cmdline() in arch/x86/kernel/cpu/bugs.c + return value + if option == 'tsx_async_abort': + # See tsx_async_abort_parse_cmdline() in arch/x86/kernel/cpu/bugs.c + return value + if option == 'srbds': + # See srbds_parse_cmdline() in arch/x86/kernel/cpu/bugs.c + return value + if option == 'mmio_stale_data': + # See mmio_stale_data_parse_cmdline() in arch/x86/kernel/cpu/bugs.c + return value + if option == 'retbleed': + # See retbleed_parse_cmdline() in arch/x86/kernel/cpu/bugs.c return value # Implement a limited part of the kstrtobool() logic