A Linux kernel configuration is a file which defines all of the enabled (or disabled) options which are compiled in to your kernel. If you have not seen one before, they generally reside in the kernel’s build directory with a filename of “.config”. They are sometimes collapsed in to a defconfig (default config) file which only shows options which were not already selected by default.
This discussion will present many configuration tables in the form of:
Expected Conditional | Architectures | Kernel Versions | Note |
---|---|---|---|
OPTION1=Y | Architecture to which this option applys (X86 and/or ARM) | Kernel versions in which OPTION1 exists | A description of OPTION1 |
OPTION2=is not set | Architecture to which this option applys (X86 and/or ARM) | Kernel versions in which OPTION2 exists | A description of OPTION2 |
In this case, it is recommended that the fictional option, OPTION1, is selected (CONFIG_OPTION1=y) in your kernel’s .config or defconfig file. It is also recommended that OPTION2 is disabled (CONFIG_OPTION2=is not set) in your kernel’s .config or defconfig file.
The option descriptions are sometimes difficult to interpret and may require further research. If you find an option that you’d like to know more information about, you may have to inspect the kernel source, search LWN, search Patchwork, or use your web search engine of choice.
When Linux kernel hardening, there are generally four categories of reason for which a configuration item may be enabled or disabled:
Expected Conditional | Architectures | Kernel Versions | Note |
---|---|---|---|
RETPOLINE=Y | X86_32, X86_64 | 4.15-4.20, 5.0-5.17 | Avoid speculative indirect branches in kernel (Spectre Mitigation) |
USB_USBNET=is not set | ARM, ARM64, X86_32, X86_64 | 2.6.22-2.6.39, 3.0-3.19, 4.0-4.20, 5.0-5.17 | If enabled, this adds USB networking subsystem support to the kernel |
DEVMEM=is not set | ARM, ARM64, X86_32, X86_64 | 4.0-4.20, 5.0-5.17 | Do not allow access to physical memory via /dev/mem |
PAGE_POISONING=Y | ARM, ARM64, X86_32, X86_64 | 4.6-4.20, 5.0-5.17 | Fill the pages with poison patterns after free_pages() and verify the patterns before alloc_pages. The filling of the memory helps reduce the risk of information leaks from freed data. This must be enabled from the boot cmdline with page_poison=1 |
The latter two options can help to protect against exploits which have not yet been discovered or released into the public domain (e.g. zero-day exploits) by reducing your kernel’s exploitable attack surface.
Analyzing, understanding, and modifying the kernel configuration with these tasks in mind is not trivial. Furthermore, in a large project it may not be clear exactly who is using which kernel configuration option. This can result in iterative backstepping until you arrive at a final configuration which works for your entire team.
There’s also a maintenance burden once you have created your final configuration. When you upgrade your kernel, many of the configuration options will have been removed and renamed. This will require another assessment and configuration period. Keeping your kernel up to date is extremely important, as security features are continuously added and revised in newer kernels. Starting a project with a long term stable (LTS) kernel is recommended, as an LTS kernel provides smaller (and sometimes backported) version increments to resolve security flaws (e.g upgrading from 5.0.x to 5.0.y). Such patches are provided until the long term stable support period ends.
Not all configuration items provide the same cost-benefit as others. To some extent, most options will have an impact in these key areas:
Expected Conditional | Architectures | Kernel Versions | Note |
---|---|---|---|
GCC_PLUGIN_STACKLEAK=Y | ARM64, X86_32, X86_64 | 5.2-5.17 | This blocks most uninitialized stack variable attacks, with the performance impact being driven by the depth of the stack usage, rather than the function calling complexity. The performance impact on a single CPU system kernel compilation sees a 1% slowdown. |
DM_CRYPT=Y | ARM, ARM64, X86_32, X86_64 | 2.6.4-2.6.39, 3.0-3.19, 4.0-4.20, 5.0-5.17 | Filesystem Hardening (Block Level Encryption via dm-crypt) – Requires userspace support |
PAGE_POISONING=Y | ARM, ARM64, X86_32, X86_64 | 4.6-4.20, 5.0-5.17 | Fill the pages with poison patterns after free_pages() and verify the patterns before alloc_pages. The filling of the memory helps reduce the risk of information leaks from freed data. This must be enabled from the boot cmdline with page_poison=1 |
Some configuration items will provide a better cost-benefit. Configuration items which have minimal impact on processor load are most valuable. For example, these add virtually no CPU overhead:
While these will add CPU overhead to some degree:
Expected Conditional | Architectures | Kernel Versions | Note |
---|---|---|---|
DEBUG_BUGVERBOSE=is not set | ARM, ARM64, X86_32, X86_64 | 2.6.9-2.6.39, 3.0-3.19, 4.0-4.20, 5.0-5.17 | Make sure this is not enabled, as it could provide an attacker sensitive kernel backtrace information on BUG() conditions |
ARCH_HAS_ELF_RANDOMIZE=Y | ARM, ARM64, X86_32, X86_64 | 4.1-4.20, 5.0-5.17 | Randomized locations for stack, mmap, brk, and ET_DYN |
INIT_ON_FREE_DEFAULT_ON=Y | ARM, ARM64, X86_32, X86_64 | 5.3-5.17 | More expensive form of INIT_ON_ALLOC_DEFAULT_ON. The primary difference is that data lifetime in memory is reduced, as anything freed is wiped immediately, making live forensics or cold boot memory attacks unable to recover freed memory contents. |
INIT_ON_ALLOC_DEFAULT_ON=Y | ARM, ARM64, X86_32, X86_64 | 5.3-5.17 | All page allocator and slab allocator memory will be zeroed when freed, eliminating many kinds of “uninitialized heap memory” flaws, especially heap content exposures. |
DEBUG_VIRTUAL=Y | ARM, ARM64, X86_32, X86_64 | 2.6.28-2.6.39, 3.0-3.19, 4.0-4.20, 5.0-5.17 | Enable some costly sanity checks in virtual to page code. This can catch mistakes with virt_to_page() and friends. |
Using multiple kernel configurations (development and production) can be an option. While it is wise to develop on a prototype system that most closely resembles a production system (as to not cause unforseen bugs in changing timing conditions and loads between configurations), some security options be too cumbersome to reasonably develop on. If you’re writing a kernel driver and you need to use a tracing tool or read a core dump, then certainly enable them while developing.
In the Timesys Kernel Hardening Analysis Tool, the kernel security options have been divided into various groups. This categorization is by no means a definitive separation; some options could be further categorized or applied to multiple categories.
Memory Protection
Memory exploits are classes of attack in which an entity is able to retrieve or modified privileged information about the system. These can be further categorized into:
Expected Conditional | Architectures | Kernel Versions | Note |
---|---|---|---|
INIT_STACK_ALL_ZERO=Y | ARM, ARM64, X86_32, X86_64 | 5.9-5.17 | Initializes everything on the stack with a zero value. This is intended to eliminate all classes of uninitialized stack variable exploits and information exposures, even variables that were warned to have been left uninitialized. (Strongest, safest) |
GCC_PLUGIN_ARM_SSP_PER_TASK=Y | ARM | 5.2-5.17 | Generates a separate stack canary value for each task, so if one task’s canary value is leaked it does not cause all other tasks to become vulnerable. |
STACKPROTECTOR=Y | ARM, ARM64, X86_32, X86_64 | 4.18-4.20, 5.0-5.17 | This option turns on the “stack-protector” GCC feature. This feature puts, at the beginning of functions, a canary value on the stack just before the return address, and validates the value just before actually returning. Stack based buffer overflows (that need to overwrite this return address) now also overwrite the canary, which gets detected and the attack is then neutralized via a kernel panic. |
STACKPROTECTOR_STRONG=Y | ARM, ARM64, X86_32, X86_64 | 4.18-4.20, 5.0-5.17 | Adds the CONFIG_STACKPROTECTOR canary logic to additional conditions related to variable assignment. |
STACKPROTECTOR_PER_TASK=Y | ARM, ARM64 | 5.0-5.17 | Use a different stack canary value for each task |
VMAP_STACK=Y | ARM64 | 4.9-4.20, 5.0-5.17 | Enable this if you want the use virtually-mapped kernel stacks with guard pages. This causes kernel stack overflows to be caught immediately. |
SCHED_STACK_END_CHECK=Y | ARM, ARM64, X86_32, X86_64 | 3.18-3.19, 4.0-4.20, 5.0-5.17 | Additional validation check on commonly targeted structure. Detect stack corruption on calls to schedule() |
STACKLEAK_METRICS=is not set | ARM64, X86_32, X86_64 | 5.2-5.17 | If this is set, STACKLEAK metrics for every task are available in the /proc file system. |
STACKLEAK_RUNTIME_DISABLE=is not set | ARM64, X86_32, X86_64 | 5.2-5.17 | If set, allows runtime disabling of kernel stack erasing |
GCC_PLUGIN_STACKLEAK=Y | ARM64, X86_32, X86_64 | 5.2-5.17 | This blocks most uninitialized stack variable attacks, with the performance impact being driven by the depth of the stack usage, rather than the function calling complexity. The performance impact on a single CPU system kernel compilation sees a 1% slowdown. |
Expected Conditional | Architectures | Kernel Versions | Note |
---|---|---|---|
STRICT_KERNEL_RWX=Y | ARM, ARM64, X86_32, X86_64 | 4.11-4.20, 5.0-5.17 | If this is set, kernel text and rodata memory will be made read-only, and non-text memory will be made non-executable. This provides protection against certain security exploits (e.g. executing the heap or modifying text) |
SLAB_FREELIST_HARDENED=Y | ARM, ARM64, X86_32, X86_64 | 4.14-4.20, 5.0-5.17 | Harden slab freelist metadata: Many kernel heap attacks try to target slab cache metadata and other infrastructure. This options makes minor performance sacrifices to harden the kernel slab allocator against common freelist exploit methods. Some slab implementations have more sanity-checking than others. This option is most effective with CONFIG_SLUB. |
SLAB_FREELIST_RANDOM=Y | ARM, ARM64, X86_32, X86_64 | 4.7-4.20, 5.0-5.17 | Randomizes the freelist order used on creating new pages. This security feature reduces the predictability of the kernel slab allocator against heap overflows. |
COMPAT_BRK=is not set | ARM, ARM64, X86_32, X86_64 | 2.6.25-2.6.39, 3.0-3.19, 4.0-4.20, 5.0-5.17 | Do not disable heap randomization |
INET_DIAG=is not set | ARM, ARM64, X86_32, X86_64 | 2.6.14-2.6.39, 3.0-3.19, 4.0-4.20, 5.0-5.17 | Do not allow INET socket monitoring interface. Assists heap memory attacks |
Expected Conditional | Architectures | Kernel Versions | Note |
---|---|---|---|
HARDENED_USERCOPY=Y | ARM, ARM64, X86_32, X86_64 | 4.8-4.20, 5.0-5.17 | This option checks for obviously wrong memory regions when copying memory to/from the kernel (via copy_to_user() and copy_from_user() functions) by rejecting memory ranges that are larger than the specified heap object, span multiple separately allocated pages, are not on the process stack, or are part of the kernel text. This kills entire classes of heap overflow exploits and similar kernel memory exposures. |
HARDENED_USERCOPY_FALLBACK=is not set | ARM, ARM64, X86_32, X86_64 | 4.16-4.20, 5.0-5.15 | This is a temporary option that allows missing usercopy whitelists to be discovered via a WARN() to the kernel log, instead of rejecting the copy, falling back to non-whitelisted hardened usercopy that checks the slab allocation size instead of the whitelist size. |
HARDENED_USERCOPY_PAGESPAN=is not set | ARM, ARM64, X86_32, X86_64 | 4.8-4.20, 5.0-5.17 | When a multi-page allocation is done without __GFP_COMP, hardened usercopy will reject attempts to copy it. There are, however, several cases of this in the kernel that have not all been removed. This config is intended to be used only while trying to find such users. |
HAVE_HARDENED_USERCOPY_ALLOCATOR=Y | ARM, ARM64, X86_32, X86_64 | 4.8-4.20, 5.0-5.17 | The heap allocator implements __check_heap_object() for validating memory ranges against heap object sizes. |
Expected Conditional | Architectures | Kernel Versions | Note |
---|---|---|---|
X86_UMIP=Y | X86_32, X86_64 | 5.5-5.17 | If enabled, a general protection fault is issued if the SGDT, SLDT, SIDT, SMSW or STR instructions are executed in user mode. These instructions unnecessarily expose information about the hardware state. |
PROC_PAGE_MONITOR=is not set | ARM, ARM64, X86_32, X86_64 | 2.6.28-2.6.39, 3.0-3.19, 4.0-4.20, 5.0-5.17 | Do not expose process memory utilization via /proc interfaces |
PROC_VMCORE=is not set | ARM, ARM64, X86_32, X86_64 | 2.6.37-2.6.39, 3.0-3.19, 4.0-4.20, 5.0-5.17 | Do not export the dump image of crashed kernel |
DEBUG_FS=is not set | ARM, ARM64, X86_32, X86_64 | 2.6.11-2.6.39, 3.0-3.19, 4.0-4.20, 5.0-5.17 | Do not enable debugfs, as it may expose vulnerabilities |
Expected Conditional | Architectures | Kernel Versions | Note |
---|---|---|---|
ARCH_HAS_ELF_RANDOMIZE=Y | ARM, ARM64, X86_32, X86_64 | 4.1-4.20, 5.0-5.17 | Randomized locations for stack, mmap, brk, and ET_DYN |
RANDOMIZE_BASE=Y | ARM64, X86_32, X86_64 | 4.7-4.20, 5.0-5.17 | In support of Kernel Address Space Layout Randomization (KASLR), this randomizes the physical address at which the kernel image is decompressed and the virtual address where the kernel image is mapped, as a security feature that deters exploit attempts relying on knowledge of the location of kernel code internals. |
RANDOMIZE_MEMORY=Y | X86_64 | 4.8-4.20, 5.0-5.17 | Randomizes the base virtual address of kernel memory sections (physical memory mapping, vmalloc & vmemmap). This security feature makes exploits relying on predictable memory locations less reliable. |
SLAB_FREELIST_RANDOM=Y | ARM, ARM64, X86_32, X86_64 | 4.7-4.20, 5.0-5.17 | Randomizes the freelist order used on creating new pages. This security feature reduces the predictability of the kernel slab allocator against heap overflows. |
GCC_PLUGIN_RANDSTRUCT=Y | ARM, ARM64, X86_32, X86_64 | 4.13-4.20, 5.0-5.17 | Randomizes layout of sensitive kernel structures |
Reducing Attack Surface
These are configuration options which can be selected to reduce the potential for exposure to unknown zero-day attacks by limiting the attack surface as much as we can. These are options that reduce the amount of information exposure and compiled-firmware attack surface (Again: If you don’t need it, disable it).
Expected Conditional | Architectures | Kernel Versions | Note |
---|---|---|---|
HIBERNATION=is not set | ARM, ARM64, X86_32, X86_64 | 2.6.23-2.6.39, 3.0-3.19, 4.0-4.20, 5.0-5.17 | Do not support hibernation. Allows replacement of running kernel. |
KEXEC=is not set | ARM, ARM64, X86_32, X86_64 | 2.6.16-2.6.39, 3.0-3.19, 4.0-4.20, 5.0-5.17 | Do not allow system to boot another Linux kernel |
KEXEC_FILE=is not set | ARM, ARM64, X86_32, X86_64 | 3.17-3.19, 4.0-4.20, 5.0-5.17 | Do not allow system to boot another Linux kernel |
Expected Conditional | Architectures | Kernel Versions | Note |
---|---|---|---|
MODULES=is not set | ARM, ARM64, X86_32, X86_64 | You should not allow for modules to be loaded unless you have the proper signing and signature checks enabled. Allowing the kernel to load unsigned modules can be dangerous | |
STRICT_MODULE_RWX=Y | ARM, ARM64, X86_32, X86_64 | 4.11-4.20, 5.0-5.17 | Module text and rodata memory will be made read-only, and non-text memory will be made non-executable. This provides protection against certain security exploits (e.g. writing to text) |
MODULE_SIG=Y | ARM, ARM64, X86_32, X86_64 | 3.7-3.19, 4.0-4.20, 5.0-5.17 | Enable module signature verification |
MODULE_SIG_ALL=Y | ARM, ARM64, X86_32, X86_64 | 3.9-3.19, 4.0-4.20, 5.0-5.17 | Automatically sign all modules during modules_install (so we don’t have to do this manually) |
MODULE_SIG_SHA512=Y | ARM, ARM64, X86_32, X86_64 | 3.7-3.19, 4.0-4.20, 5.0-5.17 | Sign modules with SHA-512 algorithm |
MODULE_SIG_FORCE=Y | ARM, ARM64, X86_32, X86_64 | 3.7-3.19, 4.0-4.20, 5.0-5.17 | Require modules to be validly signed |
DEBUG_SET_MODULE_RONX=Y | ARM, ARM64, X86_32, X86_64 | Varies depending on architecture | Helps catch unintended modifications to loadable kernel module’s text and read-only data. It also prevents execution of module data. |
Expected Conditional | Architectures | Kernel Versions | Note |
---|---|---|---|
SECCOMP=Y | ARM, ARM64, X86_32, X86_64 | Varies depending on architecture | This kernel feature is useful for number crunching applications that may need to compute untrusted bytecode during their execution. By using pipes or other transports made available to the process as file descriptors supporting the read/write syscalls, it’s possible to isolate those applications in their own address space using seccomp. Once seccomp is enabled via prctl(PR_SET_SECCOMP), it cannot be disabled and the task is only allowed to execute a few safe syscalls defined by each seccomp mode. |
USELIB=is not set | ARM, ARM64, X86_32, X86_64 | 4.5-4.20, 5.0-5.17 | If enabled, this allows the libc5 and earlier dynamic linker usblib syscall. Should no longer be needed. |
MODIFY_LDT_SYSCALL=is not set | X86_32, X86_64 | 4.3-4.20, 5.0-5.17 | Linux can allow user programs to install a per-process x86 Local Descriptor Table (LDT) using the modify_ldt(2) system call. This is required to run 16-bit or segmented code such as DOSEMU or some Wine programs. It is also used by some very old threading libraries. Enabling this feature adds a small amount of overhead to context switches and increases the low-level kernel attack surface. Disabling it removes the modify_ldt(2) system call. |
LEGACY_VSYSCALL_NONE=Y | X86_32, X86_64 | 4.4-4.20, 5.0-5.17 | There will be no vsyscall mapping at all. This will eliminate any risk of ASLR bypass due to the vsyscall fixed address mapping. Attempts to use the vsyscalls will be reported to dmesg, so that either old or malicious userspace programs can be identified. |
X86_VSYSCALL_EMULATION=is not set | X86_32, X86_64 | 3.19, 4.0-4.20, 5.0-5.17 | If set, this enables emulation of the legacy vsyscall page. |
Expected Conditional | Architectures | Kernel Versions | Note |
---|---|---|---|
SECURITY=Y | ARM, ARM64, X86_32, X86_64 | 2.5.50-2.5.75, 2.6.0-2.6.39, 3.0-3.19, 4.0-4.20, 5.0-5.17 | This allows you to choose different security modules to be configured into your kernel. |
SECURITY_YAMA=Y | ARM, ARM64, X86_32, X86_64 | 3.4-3.19, 4.0-4.20, 5.0-5.17 | This selects Yama, which extends DAC support with additional system-wide security settings beyond regular Linux discretionary access controls. Currently available is ptrace scope restriction. Like capabilities, this security module stacks with other LSMs. Further information can be found in Documentation/admin-guide/LSM/Yama.rst. |
SECURITY_WRITABLE_HOOKS=is not set | ARM, ARM64, X86_32, X86_64 | 4.12-4.20, 5.0-5.17 | If SECURITY_SELINUX_DISABLE must be set, make sure this is not set. Subsequent patches will add RO hardening to LSM hooks, however, SELinux still needs to be able to perform runtime disablement after init to handle architectures where init-time disablement via boot parameters is not feasible. Introduce a new kernel configuration parameter CONFIG_SECURITY_WRITABLE_HOOKS, and a helper macro __lsm_ro_after_init, to handle this case. |
SECURITY_SELINUX_DISABLE=is not set | ARM, ARM64, X86_32, X86_64 | 2.6.6-2.6.39, 3.0-3.19, 4.0-4.20, 5.0-5.17 | Do not allow NSA SELinux runtime disable |
SECURITY_LOCKDOWN_LSM=Y | ARM, ARM64, X86_32, X86_64 | 5.4-5.17 | Enables the lockdown LSM, which enables you to set the lockdown=integrity or lockdown=confidentiality modes during boot. Integrity attempts to block userspace from modifying the running kernel, while confidentiality also restricts reading of confidential material. |
SECURITY_LOCKDOWN_LSM_EARLY=Y | ARM, ARM64, X86_32, X86_64 | 5.4-5.17 | Enable lockdown LSM early in init |
LOCK_DOWN_KERNEL_FORCE_CONFIDENTIALITY=Y | ARM, ARM64, X86_32, X86_64 | 5.4-5.17 | The kernel runs in confidentiality mode by default. Features that allow the kernel to be modified at runtime or that permit userland code to read confidential material held inside the kernel are disabled. |
SECURITY_SAFESETID=Y | ARM, ARM64, X86_32, X86_64 | 5.1-5.17 | SafeSetID is an LSM module that gates the setid family of syscalls to restrict UID/GID transitions from a given UID/GID to only those approved by a system-wide whitelist. These restrictions also prohibit the given UIDs/GIDs from obtaining auxiliary privileges associated with CAP_SET{U/G}ID, such as allowing a user to set up user namespace UID mappings. |
SECURITY_LOADPIN=Y | ARM, ARM64, X86_32, X86_64 | 4.7-4.20, 5.0-5.17 | Any files read through the kernel file reading interface (kernel modules, firmware, kexec images, security policy) can be pinned to the first filesystem used for loading. When enabled, any files that come from other filesystems will be rejected. This is best used on systems without an initrd that have a root filesystem backed by a read-only device such as dm-verity or a CDROM. |
SECURITY_LOADPIN_ENFORCE=Y | ARM, ARM64, X86_32, X86_64 | 4.20, 5.0-5.17 | If selected, LoadPin will enforce pinning at boot. If not selected, it can be enabled at boot with the kernel parameter “loadpin.enforce=1”. |
Many security features are architecture specific because of a specific hardware level reason (differing instruction set, caches, branch predictors, and more) or merely because they have not been implemented on a specific architecture. Looking at DEBUG_SET_MODULE_RONX, we find that it was a relatively recent addition for ARM and ARM64 architectures.
Expected Conditional | Architectures | Kernel Versions | Note |
---|---|---|---|
DEBUG_SET_MODULE_RONX=Y | X86_32, X86_64 | 2.6.38-2.6.39, 3.0-3.19, 4.0-4.10 | Helps catch unintended modifications to loadable kernel module’s text and read-only data. It also prevents execution of module data. |
DEBUG_SET_MODULE_RONX=Y | ARM64 | 3.18-3.19, 4.0-4.10 | ↑ |
DEBUG_SET_MODULE_RONX=Y | ARM | 3.14-3.19, 4.0-4.10 | ↑ |
Looking at the Spectre and Meltdown variants, there are differing options depending on architecture as well:
Expected Conditional | Architectures | Kernel Versions | Note |
---|---|---|---|
HARDEN_BRANCH_PREDICTOR=Y | ARM, ARM64 | 4.16-4.20, 5.0-5.17 | (Spectre related) Speculation attacks against some high-performance processors rely on being able to manipulate the branch predictor for a victim context by executing aliasing branches in the attacker context. Such attacks can be partially mitigated against by clearing internal branch predictor state and limiting the prediction logic in some situations. |
RETPOLINE=Y | X86_32, X86_64 | 4.15-4.20, 5.0-5.17 | Avoid speculative indirect branches in kernel (Spectre Mitigation) |
This tool is available as part of the meta-vigishield layer, learn more about VigiShield here.
This Yocto-based tool can perform some security-minded analysis of your kernel configuration. The tool generates a report that shows the status of many configuration items which we have assessed as being security related.
The output from the Timesys Kernel Hardening Analysis Tool is formatted as a Comma Separated List (CSV). As an example, here are the first few lines from a sample report are:
Expected Conditional | Status | Priority | Kernel Versions | Category | Note |
---|---|---|---|---|---|
GCC_PLUGIN_RANDSTRUCT=Y | FAILED | 3 (High) | 4.13-4.20, 5.0-5.17 | gcc_plugin | Randomizes layout of sensitive kernel structures |
GCC_PLUGIN_ARM_SSP_PER_TASK=Y | SKIPPED (Version mismatch) | 3 (High) | 5.2-5.17 | gcc_plugin | Generates a separate stack canary value for each task, so if one task’s canary value is leaked it does not cause all other tasks to become vulnerable. |
GCC_PLUGIN_STRUCTLEAK=Y | SKIPPED (Version mismatch) | 3 (High) | 5.2-5.17 | gcc_plugin | This plugin is available to identify and zero-initialize stack variables that may have passed through uninitialized |
STACKPROTECTOR=Y | PASSED | 3 (High) | 4.18-4.20, 5.0-5.17 | stack_canary | This option turns on the “stack-protector” GCC feature. This feature puts, at the beginning of functions, a canary value on the stack just before the return address, and validates the value just before actually returning. Stack based buffer overflows (that need to overwrite this return address) now also overwrite the canary, which gets detected and the attack is then neutralized via a kernel panic. |
STACKPROTECTOR_STRONG=Y | PASSED | 3 (High) | 4.18-4.20, 5.0-5.17 | stack_canary | Adds the CONFIG_STACKPROTECTOR canary logic to additional conditions related to variable assignment. |
INIT_ON_ALLOC_DEFAULT_ON=Y | SKIPPED (Version mismatch) | 3 (High) | 5.3-5.17 | memory_protection | All page allocator and slab allocator memory will be zeroed when freed, eliminating many kinds of “uninitialized heap memory” flaws, especially heap content exposures. |
INIT_ON_FREE_DEFAULT_ON=Y | SKIPPED (Version mismatch) | 3 (High) | 5.3-5.17 | memory_protection | More expensive form of INIT_ON_ALLOC_DEFAULT_ON. The primary difference is that data lifetime in memory is reduced, as anything freed is wiped immediately, making live forensics or cold boot memory attacks unable to recover freed memory contents. |
STRICT_KERNEL_RWX=Y | PASSED | 4.11-4.20, 5.0-5.17 | 3 (High) | memory_protection | If this is set, kernel text and rodata memory will be made read-only, and non-text memory will be made non-executable. This provides protection against certain security exploits (e.g. executing the heap or modifying text) |
(MODULE_SIG_FORCE=Y) OR (MODULES=is not set) | FAILED | ||||
DESCRIPTION: MODULES | FAILED | 1 (Low) | 2.5.45-2.5.75, 2.6.0-2.6.39, 3.0-3.19, 4.0-4.20, 5.0-5.17 | module_security | You should not allow for modules to be loaded unless you have the proper signing and signature checks enabled. Allowing the kernel to load unsigned modules can be dangerous |
DESCRIPTION: MODULE_SIG_FORCE | FAILED | 3 (High) | 3.7-3.19, 4.0-4.20, 5.0-5.17 | module_security | Require modules to be validly signed |
In this case, GCC_PLUGIN_RANDSTRUCT was not enabled in the kernel configuration file, so the return status is, “FAILED.”
GCC_PLUGIN_ARM_SSP_PER_TASK, GCC_PLUGIN_STRUCTLEAK, INIT_ON_ALLOC_DEFAULT_ON, STRICT_KERNEL_RWX, and INIT_ON_FREE_DEFAULT_ON are all options which were available after the 5.0.19 kernel version, so those have been skipped with a, “SKIPPED (Version mismatch)” message.
The rest of the options were set appropriately and passed (STACKPROTECTOR and STACKPROTECTOR_STRONG).
Modules are also enabled without any forced signature checking, so the OR conditional [(MODULE_SIG_FORCE=Y) OR (MODULES=is not set)] for that has also failed.