Add the 'fs.protected_regular' check
[kconfig-hardened-check.git] / kernel_hardening_checker / checks.py
index 4bebb8c4da1e36e36396958f7f61d5a203f3b346..84c5c1974632a0dc12fff2a63951c4fd536e84f4 100644 (file)
@@ -457,10 +457,11 @@ def add_cmdline_checks(l, arch):
                  CmdlineCheck('self_protection', 'defconfig', 'rodata', 'is not set'))]
 
     # 'self_protection', 'kspp'
-    l += [CmdlineCheck('self_protection', 'kspp', 'nosmt', 'is present')]
-    l += [CmdlineCheck('self_protection', 'kspp', 'mitigations', 'auto,nosmt')] # 'nosmt' by kspp + 'auto' by defconfig
+    l += [CmdlineCheck('self_protection', 'kspp', 'mitigations', 'auto,nosmt')]
+    l += [CmdlineCheck('self_protection', 'kspp', 'nosmt', 'is present')] # slow (high performance penalty)
     l += [CmdlineCheck('self_protection', 'kspp', 'slab_merge', 'is not set')] # consequence of 'slab_nomerge' by kspp
     l += [CmdlineCheck('self_protection', 'kspp', 'slub_merge', 'is not set')] # consequence of 'slab_nomerge' by kspp
+    l += [CmdlineCheck('self_protection', 'kspp', 'page_alloc.shuffle', '1')]
     l += [OR(CmdlineCheck('self_protection', 'kspp', 'slab_nomerge', 'is present'),
              AND(KconfigCheck('self_protection', 'clipos', 'SLAB_MERGE_DEFAULT', 'is not set'),
                  CmdlineCheck('self_protection', 'kspp', 'slab_merge', 'is not set'),
@@ -474,14 +475,13 @@ def add_cmdline_checks(l, arch):
              AND(CmdlineCheck('self_protection', 'kspp', 'page_poison', '1'),
                  KconfigCheck('self_protection', 'kspp', 'PAGE_POISONING_ZERO', 'y'),
                  CmdlineCheck('self_protection', 'kspp', 'slub_debug', 'P')))]
-    # The cmdline checks compatible with the kconfig recommendations of the KSPP project...
     l += [OR(CmdlineCheck('self_protection', 'kspp', 'hardened_usercopy', '1'),
              AND(KconfigCheck('self_protection', 'kspp', 'HARDENED_USERCOPY', 'y'),
                  CmdlineCheck('self_protection', 'kspp', 'hardened_usercopy', 'is not set')))]
-    l += [OR(CmdlineCheck('self_protection', 'kspp', 'slab_common.usercopy_fallback', '0'),
-             AND(KconfigCheck('self_protection', 'kspp', 'HARDENED_USERCOPY_FALLBACK', 'is not set'),
-                 CmdlineCheck('self_protection', 'kspp', 'slab_common.usercopy_fallback', 'is not set')))]
-    # ... the end
+    l += [AND(CmdlineCheck('self_protection', 'kspp', 'slab_common.usercopy_fallback', 'is not set'),
+              KconfigCheck('self_protection', 'kspp', 'HARDENED_USERCOPY_FALLBACK', 'is not set'))]
+              # don't require slab_common.usercopy_fallback=0,
+              # since HARDENED_USERCOPY_FALLBACK was removed in Linux v5.16
     if arch in ('X86_64', 'ARM64', 'X86_32'):
         l += [OR(CmdlineCheck('self_protection', 'kspp', 'iommu.strict', '1'),
                  AND(KconfigCheck('self_protection', 'kspp', 'IOMMU_DEFAULT_DMA_STRICT', 'y'),
@@ -497,7 +497,6 @@ def add_cmdline_checks(l, arch):
                   CmdlineCheck('self_protection', 'defconfig', 'nopti', 'is not set'))]
 
     # 'self_protection', 'clipos'
-    l += [CmdlineCheck('self_protection', 'clipos', 'page_alloc.shuffle', '1')]
     if arch in ('X86_64', 'X86_32'):
         l += [CmdlineCheck('self_protection', 'clipos', 'iommu', 'force')]
 
@@ -579,17 +578,8 @@ def normalize_cmdline_options(option, value):
 
 
 # TODO: draft of security hardening sysctls:
-#    kernel.kptr_restrict=2 (or 1?)
-#    kernel.yama.ptrace_scope=3
 #    what about bpf_jit_enable?
-#    vm.unprivileged_userfaultfd=0
-#        (at first, it disabled unprivileged userfaultfd,
-#         and since v5.11 it enables unprivileged userfaultfd for user-mode only)
 #    vm.mmap_min_addr has a good value
-#    fs.protected_symlinks=1
-#    fs.protected_hardlinks=1
-#    fs.protected_fifos=2
-#    fs.protected_regular=2
 #    fs.suid_dumpable=0
 #    kernel.modules_disabled=1
 #    kernel.randomize_va_space=2
@@ -616,3 +606,13 @@ def add_sysctl_checks(l, arch):
     l += [SysctlCheck('cut_attack_surface', 'kspp', 'user.max_user_namespaces', '0')]
     l += [SysctlCheck('cut_attack_surface', 'kspp', 'dev.tty.ldisc_autoload', '0')]
     l += [SysctlCheck('cut_attack_surface', 'kspp', 'kernel.unprivileged_bpf_disabled', '1')]
+    l += [SysctlCheck('cut_attack_surface', 'kspp', 'kernel.kptr_restrict', '2')]
+    l += [SysctlCheck('cut_attack_surface', 'kspp', 'kernel.yama.ptrace_scope', '3')]
+    l += [SysctlCheck('cut_attack_surface', 'kspp', 'vm.unprivileged_userfaultfd', '0')]
+          # At first, it disabled unprivileged userfaultfd,
+          # and since v5.11 it enables unprivileged userfaultfd for user-mode only.
+
+    l += [SysctlCheck('harden_userspace', 'kspp', 'fs.protected_symlinks', '1')]
+    l += [SysctlCheck('harden_userspace', 'kspp', 'fs.protected_hardlinks', '1')]
+    l += [SysctlCheck('harden_userspace', 'kspp', 'fs.protected_fifos', '2')]
+    l += [SysctlCheck('harden_userspace', 'kspp', 'fs.protected_regular', '2')]