From 6cf9979c006c31cfd8ce04ca8d8ca9fdb890e87b Mon Sep 17 00:00:00 2001 From: Alexander Popov Date: Sun, 27 Aug 2023 23:31:55 +0300 Subject: [PATCH] Support separate sysctl checking (without kconfig) --- kconfig_hardened_check/__init__.py | 32 ++++++++++++++++++++++++++---- kconfig_hardened_check/checks.py | 10 ++++++++-- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/kconfig_hardened_check/__init__.py b/kconfig_hardened_check/__init__.py index 3e4db1c..5a7ff7f 100644 --- a/kconfig_hardened_check/__init__.py +++ b/kconfig_hardened_check/__init__.py @@ -258,7 +258,6 @@ def main(): if args.config: if args.print: sys.exit('[!] ERROR: --config and --print can\'t be used together') - if args.generate: sys.exit('[!] ERROR: --config and --generate can\'t be used together') @@ -338,13 +337,38 @@ def main(): # finally print the results print_checklist(mode, config_checklist, True) - sys.exit(0) elif args.cmdline: sys.exit('[!] ERROR: checking cmdline depends on checking Kconfig') elif args.sysctl: - # TODO: sysctl check should also work separately - sys.exit('[!] ERROR: checking sysctl depends on checking Kconfig') + # separate sysctl checking (without kconfig) + assert(args.config is None and args.cmdline is None), 'unexpected args' + if args.print: + sys.exit('[!] ERROR: --sysctl and --print can\'t be used together') + if args.generate: + sys.exit('[!] ERROR: --sysctl and --generate can\'t be used together') + + if mode != 'json': + print(f'[+] Sysctl output file to check: {args.sysctl}') + + # add relevant sysctl checks to the checklist + add_sysctl_checks(config_checklist, None) + + # populate the checklist with the parsed sysctl data + parsed_sysctl_options = OrderedDict() + parse_sysctl_file(mode, parsed_sysctl_options, args.sysctl) + populate_with_data(config_checklist, parsed_sysctl_options, 'sysctl') + + # now everything is ready, perform the checks + perform_checks(config_checklist) + + if mode == 'verbose': + # print the parsed options without the checks (for debugging) + print_unknown_options(config_checklist, parsed_sysctl_options) + + # finally print the results + print_checklist(mode, config_checklist, True) + sys.exit(0) if args.print: assert(args.config is None and args.cmdline is None and args.sysctl is None), 'unexpected args' diff --git a/kconfig_hardened_check/checks.py b/kconfig_hardened_check/checks.py index 7764509..4957ad5 100644 --- a/kconfig_hardened_check/checks.py +++ b/kconfig_hardened_check/checks.py @@ -15,6 +15,8 @@ from .engine import KconfigCheck, CmdlineCheck, SysctlCheck, VersionCheck, OR, A def add_kconfig_checks(l, arch): + assert(arch), 'empty arch' + # Calling the KconfigCheck class constructor: # KconfigCheck(reason, decision, name, expected) # @@ -379,6 +381,8 @@ def add_kconfig_checks(l, arch): def add_cmdline_checks(l, arch): + assert(arch), 'empty arch' + # Calling the CmdlineCheck class constructor: # CmdlineCheck(reason, decision, name, expected) # @@ -574,7 +578,6 @@ def normalize_cmdline_options(option, value): return value -def add_sysctl_checks(l, arch): # TODO: draft of security hardening sysctls: # kernel.kptr_restrict=2 (or 1?) # kernel.yama.ptrace_scope=3 @@ -598,7 +601,10 @@ def add_sysctl_checks(l, arch): # kernel.oops_limit (think about a proper value) # kernel.warn_limit (think about a proper value) # net.ipv4.tcp_syncookies=1 (?) -# + +def add_sysctl_checks(l, arch): +# This function may be called with arch=None + # Calling the SysctlCheck class constructor: # SysctlCheck(reason, decision, name, expected) -- 2.31.1