X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=kconfig-hardened-check.py;h=4762219b1354e63b76c9c5559ee3fe249a46d680;hb=0ace19012b626203d14332090cdcd40ed2237100;hp=56c52ecc1b3c154a5f7350d29676ab6191b36661;hpb=6fa9f8b627ff568561d03ff75022bfad516642d7;p=kconfig-hardened-check.git diff --git a/kconfig-hardened-check.py b/kconfig-hardened-check.py index 56c52ec..4762219 100755 --- a/kconfig-hardened-check.py +++ b/kconfig-hardened-check.py @@ -156,7 +156,6 @@ def detect_arch(fname): with open(fname, 'r') as f: arch_pattern = re.compile("CONFIG_[a-zA-Z0-9_]*=y") arch = None - msg = None if not json_mode: print('[+] Trying to detect architecture in "{}"...'.format(fname)) for line in f.readlines(): @@ -173,6 +172,27 @@ def detect_arch(fname): return arch, 'OK' +def detect_version(fname): + with open(fname, 'r') as f: + ver_pattern = re.compile("# Linux/.* Kernel Configuration") + if not json_mode: + print('[+] Trying to detect kernel version in "{}"...'.format(fname)) + for line in f.readlines(): + if ver_pattern.match(line): + line = line.strip() + if not json_mode: + print('[+] Found version line: "{}"'.format(line)) + parts = line.split() + ver_str = parts[2] + ver_numbers = ver_str.split('.') + if len(ver_numbers) < 3 or not ver_numbers[0].isdigit() or not ver_numbers[1].isdigit(): + msg = 'failed to parse the version "' + ver_str + '"' + return None, msg + else: + return (int(ver_numbers[0]), int(ver_numbers[1])), None + return None, 'no kernel version detected' + + def construct_checklist(checklist, arch): modules_not_set = OptCheck('MODULES', 'is not set', 'kspp', 'cut_attack_surface') devmem_not_set = OptCheck('DEVMEM', 'is not set', 'kspp', 'cut_attack_surface') # refers to LOCK_DOWN_KERNEL @@ -417,17 +437,15 @@ def print_checklist(checklist, with_results): print() -def get_option_state(options, name): - return options.get(name, None) - - def perform_checks(checklist, parsed_options): for opt in checklist: if hasattr(opt, 'opts'): + # prepare ComplexOptCheck for o in opt.opts: - o.state = get_option_state(parsed_options, o.name) + o.state = parsed_options.get(o.name, None) else: - opt.state = get_option_state(parsed_options, opt.name) + # prepare OptCheck + opt.state = parsed_options.get(opt.name, None) opt.check() @@ -496,6 +514,12 @@ if __name__ == '__main__': elif not json_mode: print('[+] Detected architecture: {}'.format(arch)) + kernel_version, msg = detect_version(args.config) + if not kernel_version: + sys.exit('[!] ERROR: {}'.format(msg)) + elif not json_mode: + print('[+] Detected kernel version: {}.{}'.format(kernel_version[0], kernel_version[1])) + construct_checklist(config_checklist, arch) check_config_file(config_checklist, args.config) error_count = len(list(filter(lambda opt: opt.result.startswith('FAIL'), config_checklist)))