X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=kconfig_hardened_check%2F__init__.py;h=2cbcfa5e8197f592c7ad005aea65244d1504f56b;hb=a4e54de7ae6c5312e1b99821c666a487067e8e07;hp=41d6520fc4a0594a8d531d291956c63b0343635b;hpb=6ae70f5e1b058b05245f033abf507a8017862372;p=kconfig-hardened-check.git diff --git a/kconfig_hardened_check/__init__.py b/kconfig_hardened_check/__init__.py index 41d6520..2cbcfa5 100644 --- a/kconfig_hardened_check/__init__.py +++ b/kconfig_hardened_check/__init__.py @@ -288,7 +288,7 @@ def detect_arch(fname, archs): return arch, 'OK' -def detect_version(fname): +def detect_kernel_version(fname): with open(fname, 'r') as f: ver_pattern = re.compile("# Linux/.* Kernel Configuration") for line in f.readlines(): @@ -304,6 +304,26 @@ def detect_version(fname): return None, 'no kernel version detected' +def detect_compiler(fname): + gcc_version = None + clang_version = None + with open(fname, 'r') as f: + gcc_version_pattern = re.compile("CONFIG_GCC_VERSION=[0-9]*") + clang_version_pattern = re.compile("CONFIG_CLANG_VERSION=[0-9]*") + for line in f.readlines(): + if gcc_version_pattern.match(line): + gcc_version = line[19:-1] + if clang_version_pattern.match(line): + clang_version = line[21:-1] + if not gcc_version or not clang_version: + return None, 'no CONFIG_GCC_VERSION or CONFIG_CLANG_VERSION' + if gcc_version == '0' and clang_version != '0': + return 'CLANG ' + clang_version, 'OK' + if gcc_version != '0' and clang_version == '0': + return 'GCC ' + gcc_version, 'OK' + sys.exit('[!] ERROR: invalid GCC_VERSION and CLANG_VERSION: {} {}'.format(gcc_version, clang_version)) + + def add_kconfig_checks(l, arch): # Calling the KconfigCheck class constructor: # KconfigCheck(reason, decision, name, expected) @@ -322,8 +342,8 @@ def add_kconfig_checks(l, arch): # 'self_protection', 'defconfig' l += [KconfigCheck('self_protection', 'defconfig', 'BUG', 'y')] l += [KconfigCheck('self_protection', 'defconfig', 'SLUB_DEBUG', 'y')] - l += [AND(KconfigCheck('self_protection', 'defconfig', 'GCC_PLUGINS', 'y'), - cc_is_gcc)] + gcc_plugins_support_is_set = KconfigCheck('self_protection', 'defconfig', 'GCC_PLUGINS', 'y') + l += [gcc_plugins_support_is_set] l += [OR(KconfigCheck('self_protection', 'defconfig', 'STACKPROTECTOR', 'y'), KconfigCheck('self_protection', 'defconfig', 'CC_STACKPROTECTOR', 'y'), KconfigCheck('self_protection', 'defconfig', 'CC_STACKPROTECTOR_REGULAR', 'y'), @@ -348,7 +368,8 @@ def add_kconfig_checks(l, arch): if arch in ('X86_64', 'X86_32'): l += [KconfigCheck('self_protection', 'defconfig', 'MICROCODE', 'y')] # is needed for mitigating CPU bugs l += [KconfigCheck('self_protection', 'defconfig', 'RETPOLINE', 'y')] - l += [KconfigCheck('self_protection', 'defconfig', 'X86_SMAP', 'y')] + l += [OR(KconfigCheck('self_protection', 'defconfig', 'X86_SMAP', 'y'), + VersionCheck((5, 19)))] # X86_SMAP is enabled by default since v5.19 l += [KconfigCheck('self_protection', 'defconfig', 'SYN_COOKIES', 'y')] # another reason? l += [OR(KconfigCheck('self_protection', 'defconfig', 'X86_UMIP', 'y'), KconfigCheck('self_protection', 'defconfig', 'X86_INTEL_UMIP', 'y'))] @@ -395,7 +416,7 @@ def add_kconfig_checks(l, arch): l += [KconfigCheck('self_protection', 'kspp', 'DEBUG_NOTIFIERS', 'y')] l += [KconfigCheck('self_protection', 'kspp', 'INIT_ON_ALLOC_DEFAULT_ON', 'y')] l += [AND(KconfigCheck('self_protection', 'kspp', 'GCC_PLUGIN_LATENT_ENTROPY', 'y'), - cc_is_gcc)] + gcc_plugins_support_is_set)] l += [KconfigCheck('self_protection', 'kspp', 'KFENCE', 'y')] l += [KconfigCheck('self_protection', 'kspp', 'WERROR', 'y')] l += [KconfigCheck('self_protection', 'kspp', 'IOMMU_DEFAULT_DMA_STRICT', 'y')] @@ -429,7 +450,7 @@ def add_kconfig_checks(l, arch): # That brings higher performance penalty. if arch in ('X86_64', 'ARM64', 'X86_32'): stackleak_is_set = KconfigCheck('self_protection', 'kspp', 'GCC_PLUGIN_STACKLEAK', 'y') - l += [AND(stackleak_is_set, cc_is_gcc)] + l += [AND(stackleak_is_set, gcc_plugins_support_is_set)] l += [KconfigCheck('self_protection', 'kspp', 'RANDOMIZE_KSTACK_OFFSET_DEFAULT', 'y')] if arch in ('X86_64', 'X86_32'): l += [KconfigCheck('self_protection', 'kspp', 'SCHED_CORE', 'y')] @@ -467,10 +488,10 @@ def add_kconfig_checks(l, arch): if arch in ('X86_64', 'ARM64', 'X86_32'): l += [AND(KconfigCheck('self_protection', 'clipos', 'STACKLEAK_METRICS', 'is not set'), stackleak_is_set, - cc_is_gcc)] + gcc_plugins_support_is_set)] l += [AND(KconfigCheck('self_protection', 'clipos', 'STACKLEAK_RUNTIME_DISABLE', 'is not set'), stackleak_is_set, - cc_is_gcc)] + gcc_plugins_support_is_set)] if arch in ('X86_64', 'X86_32'): l += [AND(KconfigCheck('self_protection', 'clipos', 'INTEL_IOMMU_DEFAULT_ON', 'y'), iommu_support_is_set)] @@ -719,6 +740,10 @@ def add_cmdline_checks(l, arch): # 'self_protection', 'clipos' l += [CmdlineCheck('self_protection', 'clipos', 'page_alloc.shuffle', '1')] + # 'self_protection', 'my' + l += [CmdlineCheck('self_protection', 'my', 'nosmep', 'is not set')] + l += [CmdlineCheck('self_protection', 'my', 'nosmap', 'is not set')] + # 'cut_attack_surface', 'kspp' if arch == 'X86_64': l += [OR(CmdlineCheck('cut_attack_surface', 'kspp', 'vsyscall', 'none'), @@ -954,12 +979,19 @@ def main(): if mode != 'json': print('[+] Detected architecture: {}'.format(arch)) - kernel_version, msg = detect_version(args.config) + kernel_version, msg = detect_kernel_version(args.config) if not kernel_version: sys.exit('[!] ERROR: {}'.format(msg)) if mode != 'json': print('[+] Detected kernel version: {}.{}'.format(kernel_version[0], kernel_version[1])) + compiler, msg = detect_compiler(args.config) + if mode != 'json': + if compiler: + print('[+] Detected compiler: {}'.format(compiler)) + else: + print('[-] Can\'t detect the compiler: {}'.format(msg)) + # add relevant kconfig checks to the checklist add_kconfig_checks(config_checklist, arch)