Add a new feature --generate
authorAlexander Popov <alex.popov@linux.com>
Mon, 12 Jun 2023 14:40:50 +0000 (17:40 +0300)
committerAlexander Popov <alex.popov@linux.com>
Mon, 12 Jun 2023 14:44:01 +0000 (17:44 +0300)
With this argument the tool generates a Kconfig fragment with the security
hardening options for the selected microarchitecture.

Refers to #67.

This Kconfig fragment can be merged with the existing Linux kernel config:

$ ./bin/kconfig-hardened-check -g X86_64 > /tmp/fragment
$ cd ~/linux-src/
$ ./scripts/kconfig/merge_config.sh .config /tmp/fragment
Using .config as base
Merging /tmp/fragment
Value of CONFIG_BUG_ON_DATA_CORRUPTION is redefined by fragment /tmp/fragment:
Previous value: # CONFIG_BUG_ON_DATA_CORRUPTION is not set
New value: CONFIG_BUG_ON_DATA_CORRUPTION=y
...

kconfig_hardened_check/__init__.py

index b2cee8feb8273d33429a79680f72ff3e84eb6bb9..d8e11f7ec806d1d8ce37159a73ff287c77862c61 100644 (file)
@@ -216,6 +216,8 @@ def main():
                         help='check the security hardening options in the kernel cmdline file')
     parser.add_argument('-p', '--print', choices=supported_archs,
                         help='print the security hardening recommendations for the selected microarchitecture')
+    parser.add_argument('-g', '--generate', choices=supported_archs,
+                        help='generate a Kconfig fragment with the security hardening options for the selected microarchitecture')
     args = parser.parse_args()
 
     mode = None
@@ -230,6 +232,9 @@ def main():
         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')
+
         if mode != 'json':
             print(f'[+] Kconfig file to check: {args.config}')
             if args.cmdline:
@@ -309,5 +314,20 @@ def main():
         print_checklist(mode, config_checklist, False)
         sys.exit(0)
 
+    if args.generate:
+        assert(args.config is None and args.cmdline is None), 'unexpected args'
+        if mode:
+            sys.exit(f'[!] ERROR: wrong mode "{mode}" for --generate')
+        arch = args.generate
+        add_kconfig_checks(config_checklist, arch)
+        for opt in config_checklist:
+            if opt.name == 'CONFIG_ARCH_MMAP_RND_BITS':
+                continue # don't add CONFIG_ARCH_MMAP_RND_BITS because its value needs refinement
+            if opt.expected == 'is not set':
+                print(f'# {opt.name} is not set')
+            else:
+                print(f'{opt.name}={opt.expected}')
+        sys.exit(0)
+
     parser.print_help()
     sys.exit(0)