return None, 'no kernel version detected'
-def construct_checklist(l, arch):
+def add_kconfig_checks(l, arch):
# Calling the KconfigCheck class constructor:
# KconfigCheck(reason, decision, name, expected)
if mode == 'json':
opts = []
for o in checklist:
- opt = ['CONFIG_'+o.name, o.expected, o.decision, o.reason]
+ opt = ['CONFIG_'+o.name, o.type, o.expected, o.decision, o.reason]
if with_results:
opt.append(o.result)
opts.append(opt)
print('[+] Config check is finished: \'OK\' - {}{} / \'FAIL\' - {}{}'.format(ok_count, ok_suppressed, fail_count, fail_suppressed))
-def perform_check(opt, parsed_options, kernel_version):
+def populate_opt_with_data(opt, parsed_options, kernel_version):
if hasattr(opt, 'opts'):
# prepare ComplexOptCheck
for o in opt.opts:
if hasattr(o, 'opts'):
# Recursion for nested ComplexOptChecks
- perform_check(o, parsed_options, kernel_version)
+ populate_opt_with_data(o, parsed_options, kernel_version)
if hasattr(o, 'state'):
o.state = parsed_options.get(o.name, None)
if hasattr(o, 'ver'):
if not hasattr(opt, 'state'):
sys.exit('[!] ERROR: bad simple check {}'.format(vars(opt)))
opt.state = parsed_options.get(opt.name, None)
- opt.check()
-def perform_checks(checklist, parsed_options, kernel_version):
+def populate_with_data(checklist, parsed_options, kernel_version):
for opt in checklist:
- perform_check(opt, parsed_options, kernel_version)
+ populate_opt_with_data(opt, parsed_options, kernel_version)
-def parse_config_file(parsed_options, fname):
+def perform_checks(checklist):
+ for opt in checklist:
+ opt.check()
+
+
+def parse_kconfig_file(parsed_options, fname):
with open(fname, 'r') as f:
opt_is_on = re.compile("CONFIG_[a-zA-Z0-9_]*=[a-zA-Z0-9_\"]*")
opt_is_off = re.compile("# CONFIG_[a-zA-Z0-9_]* is not set")
elif opt_is_off.match(line):
option, value = line[9:].split(' ', 1)
if value != 'is not set':
- sys.exit('[!] ERROR: bad disabled config option "{}"'.format(line))
+ sys.exit('[!] ERROR: bad disabled kconfig option "{}"'.format(line))
if option in parsed_options:
- sys.exit('[!] ERROR: config option "{}" exists multiple times'.format(line))
+ sys.exit('[!] ERROR: kconfig option "{}" exists multiple times'.format(line))
if option:
parsed_options[option] = value
def main():
# Report modes:
# * verbose mode for
- # - reporting about unknown kernel options in the config
+ # - reporting about unknown kernel options in the kconfig
# - verbose printing of ComplexOptCheck items
# * json mode for printing the results in JSON format
report_modes = ['verbose', 'json', 'show_ok', 'show_fail']
if mode != 'json':
print('[+] Detected kernel version: {}.{}'.format(kernel_version[0], kernel_version[1]))
- construct_checklist(config_checklist, arch)
- parsed_options = OrderedDict()
- parse_config_file(parsed_options, args.config)
- perform_checks(config_checklist, parsed_options, kernel_version)
+ # add relevant kconfig checks to the checklist
+ add_kconfig_checks(config_checklist, arch)
+
+ # populate the checklist with the parsed kconfig data
+ parsed_kconfig_options = OrderedDict()
+ parse_kconfig_file(parsed_kconfig_options, args.config)
+ populate_with_data(config_checklist, parsed_kconfig_options, kernel_version)
+
+ # now everything is ready for performing the checks
+ perform_checks(config_checklist)
+ # finally print the results
if mode == 'verbose':
- print_unknown_options(config_checklist, parsed_options)
+ print_unknown_options(config_checklist, parsed_kconfig_options)
print_checklist(mode, config_checklist, True)
sys.exit(0)
if args.print:
if mode in ('show_ok', 'show_fail'):
- sys.exit('[!] ERROR: please use "{}" mode for checking the kernel config'.format(mode))
+ sys.exit('[!] ERROR: wrong mode "{}" for --print'.format(mode))
arch = args.print
- construct_checklist(config_checklist, arch)
+ add_kconfig_checks(config_checklist, arch)
if mode != 'json':
print('[+] Printing kernel security hardening preferences for {}...'.format(arch))
print_checklist(mode, config_checklist, False)