Skip to content

Commit

Permalink
feat: add KSPP compliance check script
Browse files Browse the repository at this point in the history
We tailor results for our needs. I picked Python for the script as we
don't have jq in the tools ;)

Also fixed the kernel config to be compliant according to the script and
subset of the enforcements.

I had to add a patch to kernel's Kconfig files to switch off some
default options which otherwise get enabled via `olddefconfig` and
violate KSPP.

Signed-off-by: Andrey Smirnov <smirnov.andrey@gmail.com>
  • Loading branch information
smira authored and talos-bot committed Dec 10, 2020
1 parent 401c91a commit 5c41522
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 14 deletions.
2 changes: 1 addition & 1 deletion Pkgfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
format: v1alpha2

vars:
TOOLS_IMAGE: ghcr.io/talos-systems/tools:v0.3.0-12-g0eb84c1
TOOLS_IMAGE: ghcr.io/talos-systems/tools:v0.3.0-13-g05b7372

labels:
org.opencontainers.image.source: https://github.com/talos-systems/pkgs
55 changes: 55 additions & 0 deletions kernel/kernel-prepare/patches/hardening.kconfig.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 7101ac64bb20..e2c8cff3f791 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -41,7 +41,7 @@ config FORCE_DYNAMIC_FTRACE
in order to test the non static function tracing in the
generic code, as other architectures still use it. But we
only need to keep it around for x86_64. No need to keep it
- for x86_32. For x86_32, force DYNAMIC_FTRACE.
+ for x86_32. For x86_32, force DYNAMIC_FTRACE.
#
# Arch settings
#
@@ -1191,7 +1191,6 @@ config VM86

config X86_16BIT
bool "Enable support for 16-bit segments" if EXPERT
- default y
depends on MODIFY_LDT_SYSCALL
help
This option is required by programs like Wine to run 16-bit
@@ -1204,7 +1203,7 @@ config X86_ESPFIX32
depends on X86_16BIT && X86_32

config X86_ESPFIX64
- def_bool y
+ bool "Foo"
depends on X86_16BIT && X86_64

config X86_VSYSCALL_EMULATION
@@ -2405,7 +2404,6 @@ config CMDLINE_OVERRIDE

config MODIFY_LDT_SYSCALL
bool "Enable the LDT (local descriptor table)" if EXPERT
- default y
help
Linux can allow user programs to install a per-process x86
Local Descriptor Table (LDT) using the modify_ldt(2) system
diff --git a/security/Kconfig b/security/Kconfig
index 7561f6f99f1d..7bf554bc0906 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -166,7 +166,6 @@ config HARDENED_USERCOPY
config HARDENED_USERCOPY_FALLBACK
bool "Allow usercopy whitelist violations to fallback to object size"
depends on HARDENED_USERCOPY
- default y
help
This is a temporary option that allows missing usercopy whitelists
to be discovered via a WARN() to the kernel log, instead of
@@ -292,4 +291,3 @@ config LSM
source "security/Kconfig.hardening"

endmenu
-
4 changes: 4 additions & 0 deletions kernel/kernel-prepare/pkg.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ steps:
done
make mrproper
- |
cd /toolchain && git clone https://github.com/a13xp0p0v/kconfig-hardened-check.git
- |
patch -p1 < /pkg/patches/hardening.kconfig.patch
install:
- |
mkdir -p /src
Expand Down
24 changes: 17 additions & 7 deletions kernel/kernel/config-amd64
Original file line number Diff line number Diff line change
Expand Up @@ -391,8 +391,6 @@ CONFIG_PERF_EVENTS_INTEL_CSTATE=y
# CONFIG_PERF_EVENTS_AMD_POWER is not set
# end of Performance monitoring

CONFIG_X86_16BIT=y
CONFIG_X86_ESPFIX64=y
CONFIG_X86_VSYSCALL_EMULATION=y
CONFIG_X86_IOPL_IOPERM=y
# CONFIG_I8K is not set
Expand Down Expand Up @@ -459,7 +457,6 @@ CONFIG_HOTPLUG_CPU=y
# CONFIG_LEGACY_VSYSCALL_XONLY is not set
CONFIG_LEGACY_VSYSCALL_NONE=y
# CONFIG_CMDLINE_BOOL is not set
CONFIG_MODIFY_LDT_SYSCALL=y
CONFIG_HAVE_LIVEPATCH=y
# end of Processor type and features

Expand Down Expand Up @@ -774,6 +771,10 @@ CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
# end of GCOV-based kernel profiling

CONFIG_HAVE_GCC_PLUGINS=y
CONFIG_GCC_PLUGINS=y
CONFIG_GCC_PLUGIN_LATENT_ENTROPY=y
CONFIG_GCC_PLUGIN_RANDSTRUCT=y
# CONFIG_GCC_PLUGIN_RANDSTRUCT_PERFORMANCE is not set
# end of General architecture-dependent options

CONFIG_RT_MUTEXES=y
Expand Down Expand Up @@ -4968,7 +4969,7 @@ CONFIG_SECURITY_NETWORK_XFRM=y
# CONFIG_INTEL_TXT is not set
CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y
CONFIG_HARDENED_USERCOPY=y
CONFIG_HARDENED_USERCOPY_FALLBACK=y
# CONFIG_HARDENED_USERCOPY_FALLBACK is not set
CONFIG_FORTIFY_SOURCE=y
# CONFIG_STATIC_USERMODEHELPER is not set
# CONFIG_SECURITY_SELINUX is not set
Expand Down Expand Up @@ -5010,13 +5011,22 @@ CONFIG_LSM="yama,loadpin,safesetid,integrity"
#
# Kernel hardening options
#
CONFIG_GCC_PLUGIN_STRUCTLEAK=y

#
# Memory initialization
#
CONFIG_INIT_STACK_NONE=y
# CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set
# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set
# CONFIG_INIT_STACK_NONE is not set
# CONFIG_GCC_PLUGIN_STRUCTLEAK_USER is not set
# CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF is not set
CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL=y
# CONFIG_GCC_PLUGIN_STRUCTLEAK_VERBOSE is not set
CONFIG_GCC_PLUGIN_STACKLEAK=y
CONFIG_STACKLEAK_TRACK_MIN_SIZE=100
# CONFIG_STACKLEAK_METRICS is not set
# CONFIG_STACKLEAK_RUNTIME_DISABLE is not set
CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y
CONFIG_INIT_ON_FREE_DEFAULT_ON=y
# end of Memory initialization
# end of Kernel hardening options
# end of Security options
Expand Down
27 changes: 21 additions & 6 deletions kernel/kernel/config-arm64
Original file line number Diff line number Diff line change
Expand Up @@ -548,8 +548,9 @@ CONFIG_CPU_FREQ_STAT=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set
CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
Expand Down Expand Up @@ -804,6 +805,11 @@ CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
# end of GCOV-based kernel profiling

CONFIG_HAVE_GCC_PLUGINS=y
CONFIG_GCC_PLUGINS=y
# CONFIG_GCC_PLUGIN_CYC_COMPLEXITY is not set
CONFIG_GCC_PLUGIN_LATENT_ENTROPY=y
CONFIG_GCC_PLUGIN_RANDSTRUCT=y
# CONFIG_GCC_PLUGIN_RANDSTRUCT_PERFORMANCE is not set
# end of General architecture-dependent options

CONFIG_RT_MUTEXES=y
Expand Down Expand Up @@ -991,7 +997,7 @@ CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_BOUNCE=y
CONFIG_MMU_NOTIFIER=y
# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=65536
CONFIG_DEFAULT_MMAP_MIN_ADDR=32768
CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y
# CONFIG_MEMORY_FAILURE is not set
# CONFIG_TRANSPARENT_HUGEPAGE is not set
Expand Down Expand Up @@ -7415,7 +7421,7 @@ CONFIG_SECURITY_NETWORK_XFRM=y
# CONFIG_SECURITY_PATH is not set
CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y
CONFIG_HARDENED_USERCOPY=y
CONFIG_HARDENED_USERCOPY_FALLBACK=y
# CONFIG_HARDENED_USERCOPY_FALLBACK is not set
# CONFIG_HARDENED_USERCOPY_PAGESPAN is not set
CONFIG_FORTIFY_SOURCE=y
# CONFIG_STATIC_USERMODEHELPER is not set
Expand Down Expand Up @@ -7458,13 +7464,22 @@ CONFIG_LSM="yama,loadpin,safesetid,integrity"
#
# Kernel hardening options
#
CONFIG_GCC_PLUGIN_STRUCTLEAK=y

#
# Memory initialization
#
CONFIG_INIT_STACK_NONE=y
# CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set
# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set
# CONFIG_INIT_STACK_NONE is not set
# CONFIG_GCC_PLUGIN_STRUCTLEAK_USER is not set
# CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF is not set
CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL=y
# CONFIG_GCC_PLUGIN_STRUCTLEAK_VERBOSE is not set
CONFIG_GCC_PLUGIN_STACKLEAK=y
CONFIG_STACKLEAK_TRACK_MIN_SIZE=100
# CONFIG_STACKLEAK_METRICS is not set
# CONFIG_STACKLEAK_RUNTIME_DISABLE is not set
CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y
CONFIG_INIT_ON_FREE_DEFAULT_ON=y
# end of Memory initialization
# end of Kernel hardening options
# end of Security options
Expand Down
3 changes: 3 additions & 0 deletions kernel/kernel/pkg.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@ steps:
- env:
ARCH: {{ if eq .ARCH "aarch64"}}arm64{{ else if eq .ARCH "x86_64" }}x86_64{{ else }}unsupported{{ end }}
CARCH: {{ if eq .ARCH "aarch64"}}arm64{{ else if eq .ARCH "x86_64" }}amd64{{ else }}unsupported{{ end }}
KARCH: {{ if eq .ARCH "aarch64"}}ARM64{{ else if eq .ARCH "x86_64" }}X86_64{{ else }}unsupported{{ end }}
prepare:
- |
cp -a /src/. .
cp -v /pkg/config-${CARCH} .config
patch -p0 < /pkg/patches/sign-file.patch
- |
python3 /toolchain/kconfig-hardened-check/bin/kconfig-hardened-check -c .config -p ${KARCH} -m json | python3 /pkg/scripts/filter-hardened-check.py
build:
- |
make -j $(nproc)
Expand Down
46 changes: 46 additions & 0 deletions kernel/kernel/scripts/filter-hardened-check.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"""
Script to filter JSON output of kconfig hardened check script.
"""

import json
import sys

"""
Names of check groups we analyze.
"""
GROUPS = {'defconfig', 'kspp'}

"""
Names of violations we ignore for a good reason.
"""
IGNORE_VIOLATIONS = {
'CONFIG_MODULES', # enabled for backwards compat, modules require signing key which is thrown away
'CONFIG_IA32_EMULATION', # see https://github.com/talos-systems/pkgs/pull/125
}

def main():
violations = json.load(sys.stdin)

# filter out non-failures
violations = [item for item in violations if item[4].startswith("FAIL")]

# filter only failures in the groups we're interested in
violations = [item for item in violations if item[2] in GROUPS]

# filter out violations we ignore
violations = [item for item in violations if item[0] not in IGNORE_VIOLATIONS]

if not violations:
sys.exit(0)

print('{:^45}|{:^13}|{:^10}|{:^20}'.format('option name', 'desired val', 'decision', 'reason'))
print('=' * 91)

for violation in violations:
print('{:<45}|{:^13}|{:^10}|{:^20}'.format(*violation))

sys.exit(1)


if __name__ == "__main__":
main()

0 comments on commit 5c41522

Please sign in to comment.