@@ -69,11 +69,12 @@ def add_kconfig_checks(l: List[ChecklistObjType], arch: str) -> None:
69
69
vmap_stack_is_set = KconfigCheck ('self_protection' , 'defconfig' , 'VMAP_STACK' , 'y' )
70
70
if arch in ('X86_64' , 'ARM64' , 'ARM' , 'RISCV' ):
71
71
l += [vmap_stack_is_set ]
72
+ if arch in ('X86_64' , 'X86_32' , 'RISCV' ):
73
+ l += [KconfigCheck ('self_protection' , 'defconfig' , 'LSM_MMAP_MIN_ADDR' , '65536' )]
72
74
if arch in ('X86_64' , 'X86_32' ):
73
75
l += [KconfigCheck ('self_protection' , 'defconfig' , 'DEBUG_WX' , 'y' )]
74
76
l += [KconfigCheck ('self_protection' , 'defconfig' , 'WERROR' , 'y' )]
75
77
l += [KconfigCheck ('self_protection' , 'defconfig' , 'X86_MCE' , 'y' )]
76
- l += [KconfigCheck ('self_protection' , 'defconfig' , 'SYN_COOKIES' , 'y' )] # another reason?
77
78
microcode_is_set = KconfigCheck ('self_protection' , 'defconfig' , 'MICROCODE' , 'y' )
78
79
l += [microcode_is_set ] # is needed for mitigating CPU bugs
79
80
l += [OR (KconfigCheck ('self_protection' , 'defconfig' , 'MICROCODE_INTEL' , 'y' ),
@@ -134,11 +135,15 @@ def add_kconfig_checks(l: List[ChecklistObjType], arch: str) -> None:
134
135
VersionCheck ((5 , 9 , 0 ))))] # HARDEN_EL2_VECTORS was included in RANDOMIZE_BASE in v5.9
135
136
l += [OR (KconfigCheck ('self_protection' , 'defconfig' , 'HARDEN_BRANCH_PREDICTOR' , 'y' ),
136
137
VersionCheck ((5 , 10 , 0 )))] # HARDEN_BRANCH_PREDICTOR is enabled by default since v5.10
138
+ l += [AND (KconfigCheck ('self_protection' , 'defconfig' , 'LSM_MMAP_MIN_ADDR' , '65536' ),
139
+ KconfigCheck ('cut_attack_surface' , 'kspp' , 'COMPAT' , 'is not set' ))]
140
+ # LSM_MMAP_MIN_ADDR for ARM64 requires disabled COMPAT (see security/Kconfig)
137
141
if arch == 'ARM' :
138
142
l += [KconfigCheck ('self_protection' , 'defconfig' , 'CPU_SW_DOMAIN_PAN' , 'y' )]
139
143
l += [KconfigCheck ('self_protection' , 'defconfig' , 'HARDEN_BRANCH_PREDICTOR' , 'y' )]
140
144
l += [KconfigCheck ('self_protection' , 'defconfig' , 'HARDEN_BRANCH_HISTORY' , 'y' )]
141
145
l += [KconfigCheck ('self_protection' , 'defconfig' , 'DEBUG_ALIGN_RODATA' , 'y' )]
146
+ l += [KconfigCheck ('self_protection' , 'defconfig' , 'LSM_MMAP_MIN_ADDR' , '32768' )]
142
147
if arch == 'RISCV' :
143
148
l += [KconfigCheck ('self_protection' , 'defconfig' , 'DEBUG_SG' , 'y' )]
144
149
l += [OR (KconfigCheck ('self_protection' , 'defconfig' , 'LIST_HARDENED' , 'y' ),
@@ -255,7 +260,6 @@ def add_kconfig_checks(l: List[ChecklistObjType], arch: str) -> None:
255
260
l += [KconfigCheck ('self_protection' , 'kspp' , 'DEFAULT_MMAP_MIN_ADDR' , '65536' )]
256
261
l += [KconfigCheck ('self_protection' , 'kspp' , 'HW_RANDOM_TPM' , 'y' )]
257
262
if arch in ('ARM64' , 'ARM' , 'RISCV' ):
258
- l += [KconfigCheck ('self_protection' , 'kspp' , 'SYN_COOKIES' , 'y' )] # another reason?
259
263
l += [KconfigCheck ('self_protection' , 'kspp' , 'WERROR' , 'y' )]
260
264
if arch in ('X86_64' , 'ARM64' ):
261
265
l += [AND (cfi_clang_is_set ,
@@ -505,6 +509,12 @@ def add_kconfig_checks(l: List[ChecklistObjType], arch: str) -> None:
505
509
l += [OR (KconfigCheck ('cut_attack_surface' , 'a13xp0p0v' , 'TRIM_UNUSED_KSYMS' , 'y' ),
506
510
modules_not_set )]
507
511
512
+ # 'network_security'
513
+ if arch in ('X86_64' , 'X86_32' ):
514
+ l += [KconfigCheck ('network_security' , 'defconfig' , 'SYN_COOKIES' , 'y' )]
515
+ if arch in ('ARM64' , 'ARM' , 'RISCV' ):
516
+ l += [KconfigCheck ('network_security' , 'kspp' , 'SYN_COOKIES' , 'y' )]
517
+
508
518
# 'harden_userspace'
509
519
if arch == 'ARM64' :
510
520
l += [KconfigCheck ('harden_userspace' , 'defconfig' , 'ARM64_PTR_AUTH' , 'y' )]
@@ -806,15 +816,10 @@ def add_sysctl_checks(l: List[ChecklistObjType], arch: StrOrNone) -> None:
806
816
# Use an omnipresent kconfig symbol to see if we have a kconfig file for checking:
807
817
have_kconfig = KconfigCheck ('-' , '-' , 'LOCALVERSION' , 'is present' )
808
818
819
+ # 'self_protection', 'kspp'
809
820
l += [OR (SysctlCheck ('self_protection' , 'kspp' , 'net.core.bpf_jit_harden' , '2' ),
810
821
AND (KconfigCheck ('-' , '-' , 'BPF_JIT' , 'is not set' ),
811
822
have_kconfig ))]
812
- # Choosing a right value for 'kernel.oops_limit' and 'kernel.warn_limit' is not easy.
813
- # A small value (e.g. 1, which is recommended by KSPP) allows easy DoS.
814
- # A large value (e.g. 10000, which is default 'kernel.oops_limit') may miss the exploit attempt.
815
- # Let's choose 100 as a reasonable compromise.
816
- l += [SysctlCheck ('self_protection' , 'a13xp0p0v' , 'kernel.oops_limit' , '100' )]
817
- l += [SysctlCheck ('self_protection' , 'a13xp0p0v' , 'kernel.warn_limit' , '100' )]
818
823
# Compatible with the 'DEFAULT_MMAP_MIN_ADDR' kconfig check by KSPP:
819
824
if arch in ('X86_64' , 'X86_32' , 'RISCV' ):
820
825
l += [SysctlCheck ('self_protection' , 'kspp' , 'vm.mmap_min_addr' , '65536' )]
@@ -825,6 +830,15 @@ def add_sysctl_checks(l: List[ChecklistObjType], arch: StrOrNone) -> None:
825
830
if arch == 'ARM' :
826
831
l += [SysctlCheck ('self_protection' , 'kspp' , 'vm.mmap_min_addr' , '32768' )]
827
832
833
+ # 'self_protection', 'a13xp0p0v'
834
+ # Choosing a right value for 'kernel.oops_limit' and 'kernel.warn_limit' is not easy.
835
+ # A small value (e.g. 1, which is recommended by KSPP) allows easy DoS.
836
+ # A large value (e.g. 10000, which is default 'kernel.oops_limit') may miss the exploit attempt.
837
+ # Let's choose 100 as a reasonable compromise.
838
+ l += [SysctlCheck ('self_protection' , 'a13xp0p0v' , 'kernel.oops_limit' , '100' )]
839
+ l += [SysctlCheck ('self_protection' , 'a13xp0p0v' , 'kernel.warn_limit' , '100' )]
840
+
841
+ # 'cut_attack_surface', 'kspp'
828
842
l += [SysctlCheck ('cut_attack_surface' , 'kspp' , 'kernel.dmesg_restrict' , '1' )]
829
843
l += [SysctlCheck ('cut_attack_surface' , 'kspp' , 'kernel.perf_event_paranoid' , '3' )]
830
844
# Without the custom patch that adds CONFIG_SECURITY_PERF_EVENTS_RESTRICT,
@@ -850,28 +864,62 @@ def add_sysctl_checks(l: List[ChecklistObjType], arch: StrOrNone) -> None:
850
864
have_kconfig ))]
851
865
# at first, it disabled unprivileged userfaultfd,
852
866
# and since v5.11 it enables unprivileged userfaultfd for user-mode only
853
-
854
867
l += [OR (SysctlCheck ('cut_attack_surface' , 'kspp' , 'kernel.modules_disabled' , '1' ),
855
868
AND (KconfigCheck ('cut_attack_surface' , 'kspp' , 'MODULES' , 'is not set' ),
856
869
have_kconfig ))]
857
870
# kernel.modules_disabled=1 should be set (e.g. with systemd) after
858
871
# the kernel startup, when all the required modules have loaded
859
872
873
+ # 'cut_attack_surface', 'grsec'
860
874
l += [OR (SysctlCheck ('cut_attack_surface' , 'grsec' , 'kernel.io_uring_disabled' , '2' ),
861
875
AND (KconfigCheck ('cut_attack_surface' , 'grsec' , 'IO_URING' , 'is not set' ),
862
876
have_kconfig ))] # compatible with the 'IO_URING' kconfig check by grsecurity
863
877
878
+ # 'cut_attack_surface', 'a13xp0p0v'
864
879
l += [OR (SysctlCheck ('cut_attack_surface' , 'a13xp0p0v' , 'kernel.sysrq' , '0' ),
865
880
AND (KconfigCheck ('cut_attack_surface' , 'clipos' , 'MAGIC_SYSRQ' , 'is not set' ),
866
881
have_kconfig ))]
867
882
883
+ # 'network_security', 'cis'
884
+ l += [SysctlCheck ('network_security' , 'cis' , 'net.ipv4.icmp_ignore_bogus_error_responses' , '1' )]
885
+ l += [SysctlCheck ('network_security' , 'cis' , 'net.ipv4.icmp_echo_ignore_broadcasts' , '1' )]
886
+ l += [SysctlCheck ('network_security' , 'cis' , 'net.ipv4.conf.all.accept_redirects' , '0' )]
887
+ l += [SysctlCheck ('network_security' , 'cis' , 'net.ipv4.conf.default.accept_redirects' , '0' )]
888
+ l += [SysctlCheck ('network_security' , 'cis' , 'net.ipv6.conf.all.accept_redirects' , '0' )]
889
+ l += [SysctlCheck ('network_security' , 'cis' , 'net.ipv6.conf.default.accept_redirects' , '0' )]
890
+ l += [SysctlCheck ('network_security' , 'cis' , 'net.ipv4.conf.all.accept_source_route' , '0' )]
891
+ l += [SysctlCheck ('network_security' , 'cis' , 'net.ipv4.conf.default.accept_source_route' , '0' )]
892
+ l += [SysctlCheck ('network_security' , 'cis' , 'net.ipv6.conf.all.accept_source_route' , '0' )]
893
+ l += [SysctlCheck ('network_security' , 'cis' , 'net.ipv6.conf.default.accept_source_route' , '0' )]
894
+ l += [SysctlCheck ('network_security' , 'cis' , 'net.ipv4.tcp_syncookies' , '1' )]
895
+ l += [SysctlCheck ('network_security' , 'cis' , 'net.ipv6.conf.all.accept_ra' , '0' )]
896
+ l += [SysctlCheck ('network_security' , 'cis' , 'net.ipv6.conf.default.accept_ra' , '0' )]
897
+ # The following recommendations from the CIS Benchmark may impact normal network functionality:
898
+ # CAUTION: without IP forwarding your system can not act as a router
899
+ # l += [SysctlCheck('network_security', 'cis', 'net.ipv4.ip_forward', '0')]
900
+ # l += [SysctlCheck('network_security', 'cis', 'net.ipv6.conf.all.forwarding', '0')]
901
+ # l += [SysctlCheck('network_security', 'cis', 'net.ipv4.conf.all.send_redirects', '0')]
902
+ # l += [SysctlCheck('network_security', 'cis', 'net.ipv4.conf.default.send_redirects', '0')]
903
+ # CAUTION: it's strange to ignore ICMP redirects from your default gateway
904
+ # l += [SysctlCheck('network_security', 'cis', 'net.ipv4.conf.all.secure_redirects', '0')]
905
+ # l += [SysctlCheck('network_security', 'cis', 'net.ipv4.conf.default.secure_redirects', '0')]
906
+ # CAUTION: rp_filter for network packets breaks asymmetrical routing (BGP, OSPF, etc) and some VPNs
907
+ # l += [SysctlCheck('network_security', 'cis', 'net.ipv4.conf.all.rp_filter', '1')]
908
+ # l += [SysctlCheck('network_security', 'cis', 'net.ipv4.conf.default.rp_filter', '1')]
909
+ # CAUTION: messages about packets with un-routable source addresses may clog up the kernel log
910
+ # l += [SysctlCheck('network_security', 'cis', 'net.ipv4.conf.all.log_martians', '1')]
911
+ # l += [SysctlCheck('network_security', 'cis', 'net.ipv4.conf.default.log_martians', '1')]
912
+
913
+ # 'harden_userspace', 'kspp'
868
914
l += [SysctlCheck ('harden_userspace' , 'kspp' , 'fs.protected_symlinks' , '1' )]
869
915
l += [SysctlCheck ('harden_userspace' , 'kspp' , 'fs.protected_hardlinks' , '1' )]
870
916
l += [SysctlCheck ('harden_userspace' , 'kspp' , 'fs.protected_fifos' , '2' )]
871
917
l += [SysctlCheck ('harden_userspace' , 'kspp' , 'fs.protected_regular' , '2' )]
872
918
l += [SysctlCheck ('harden_userspace' , 'kspp' , 'fs.suid_dumpable' , '0' )]
873
919
l += [SysctlCheck ('harden_userspace' , 'kspp' , 'kernel.randomize_va_space' , '2' )]
874
920
l += [SysctlCheck ('harden_userspace' , 'kspp' , 'kernel.yama.ptrace_scope' , '3' )]
921
+
922
+ # 'harden_userspace', 'a13xp0p0v'
875
923
l += [SysctlCheck ('harden_userspace' , 'a13xp0p0v' , 'vm.mmap_rnd_bits' , 'MAX' )]
876
924
# 'MAX' value is refined using ARCH_MMAP_RND_BITS_MAX
877
925
l += [SysctlCheck ('harden_userspace' , 'a13xp0p0v' , 'vm.mmap_rnd_compat_bits' , 'MAX' )]
0 commit comments