Security Practices

Oniro Project aims to build a secure system foundation, applying the best industry practices in terms of development quality. This page describes the security-related settings included in the distribution.

Linux Kernel Hardening Options (Qemu Builds Only)

Hardening is a process of securing the system by reducing the attack surface for vulnerabilities, such as removing unused or unsafe options and modules, for example, setting up the defaults considered to be safe, and enabling additional checks. The goal of hardening is to make the attack harder or reduce its impact.

Hardening options improve security and allow developers to detect bugs early thus increasing software quality in general.

Hardening and security options may have performance costs (e.g. due to additional checks in the code path). Oniro attempts to assure that security hardening features do not increase overhead more than %5, in general.

On the other hand, additional tests come with an additional computing costs and may reduce performance. The hardening options suggested are checked against a research from a benchmark 1, and it is verified that only such options are enabled, that do not raise the computation cost, and the performance loss is expected to be around 5 percent at most.

The Linux kernel hardening options of Oniro Project are descibed as follows, and suggested hardening options are defined in configuration files in oniro/meta-oniro-core/recipes-kernel/linux/linux/.

You can find the decisions that have been made for different categories of options as follows, and the descriptions are taken from the Kconfig with changes for better readability:

Memory Allocator

The hardening options of memory allocation protect against issues like leaking data freed from memory, and accessing wrong memory zones.

Source files: oniro/meta-oniro-core/recipes-kernel/linux/linux/hardening_allocator.cfg and oniro/meta-oniro-core/recipes-kernel/linux/linux/hardening_allocator_perf.cfg.

Config option

Oniro state

CONFIG_SLAB_FREELIST_RANDOM CONFIG_SLAB_FREELIST_HARDENED CONFIG_SHUFFLE_PAGE_ALLOCATOR CONFIG_PAGE_POISONING CONFIG_PAGE_POISONING_NO_SANITY CONFIG_PAGE_POISONING_ZERO CONFIG_INIT_ON_ALLOC_DEFAULT_ON

On On On On On On On

CONFIG_SLAB_FREELIST_RANDOM=y

Description: Randomize the freelist order used on creating new pages. This security feature reduces the predictability of the kernel slab allocator against heap overflows.

Recommendation source: KSPP 2

CONFIG_SLAB_FREELIST_HARDENED=y

Description: Many kernel heap attacks try to target slab cache metadata and other infrastructure. This option 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 SLUB.

Recommendation source: KSPP 2

CONFIG_SHUFFLE_PAGE_ALLOCATOR=y

Description: Randomization of the page allocator improves the average utilization of a direct-mapped memory-side-cache. See section 5.2.27 Heterogeneous Memory Attribute Table (HMAT) in the ACPI 6.2a specification for an example of how a platform advertises the presence of a memory-side-cache. There are also incidental security benefits as it reduces the predictability of page allocations to compliment SLAB_FREELIST_RANDOM, but the default granularity of shuffling on the MAX_ORDER - 1 i.e, 10th order of pages is selected based on cache utilization benefits on x86.

While the randomization improves cache utilization, it may negatively impact workloads on platforms without a cache. For this reason, by default, the randomization is enabled only after runtime detection of a direct-mapped memory-side-cache. Otherwise, the randomization may be force enabled with the page_alloc.shuffle kernel command line parameter.

Recommendation source: KSPP 2

CONFIG_PAGE_POISONING=y

Description: 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 does have a potential performance impact if enabled with the page_poison=1 kernel boot option.

Note that “poison” here is not the same thing as the “HWPoison” for MEMORY_FAILURE. This is software poisoning only.

Recommendation source: KSPP 2

CONFIG_PAGE_POISONING_NO_SANITY=y

Description: Skip the sanity checking on alloc, only fill the pages with poison on free. This reduces some of the overhead of the poisoning feature.

Recommendation source: KSPP 2

CONFIG_PAGE_POISONING_ZERO=y

Description: Instead of using the existing poison value, fill the pages with zeros. This makes it harder to detect when errors are occurring due to sanitization, but the zeroing at free means that it is no longer necessary to write zeros when GFP_ZERO is used on allocation.

Recommendation source: KSPP 2

CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y

Description: This has the effect of setting init_on_alloc=1 on the kernel command line. This can be disabled with init_on_alloc=0. When init_on_alloc is enabled, all page allocator and slab allocator memory will be zeroed when allocated, eliminating many kinds of “uninitialized heap memory” flaws, especially heap content exposures. The performance impact varies by workload, but most cases see <1% impact. Some synthetic workloads have measured as high as 7%.

Recommendation source: KSPP 2

Reducing Attack Surface

The following options remove some obsolete or un-needed features, which could make attacks easier:

Config option

Oniro state

CONFIG_COMPAT_BRK CONFIG_PROC_KCORE CONFIG_BINFMT_MISC

Off Off Off

Option: CONFIG_COMPAT_BRK is not set

Reason: Disabling this option enables heap randomization. Randomization of the heap has been introduced around the year 2000, we do not expect Oniro to run binaries compiled before that date, so we can enable.

Description: Randomizing heap placement makes heap exploits harder, but it also breaks ancient binaries (including anything libc5 based). This option changes the bootup default to heap randomization disabled, and can be overridden at runtime by setting /proc/sys/kernel/randomize_va_space to 2.

Recommendation source: KSPP 2

Option: CONFIG_PROC_KCORE is not set

Description: Provides a virtual ELF core file of the live kernel. This can be read with gdb and other ELF tools. No modifications can be made using this mechanism.

Recommendation source: KSPP 2

Option: CONFIG_BINFMT_MISC is not set

Description: If you say Y here, it will be possible to plug wrapper-driven binary formats into the kernel. You will like this especially when you use programs that need an interpreter to run like Java, Python, .NET or Emacs-Lisp. It is also useful if you often run DOS executables under the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO). Once you have registered such a binary class with the kernel, you can start one of those programs simply by typing in its name at a shell prompt; Linux will automatically feed it to the correct interpreter.

Recommendation source: KSPP 2

Dmesg Options

Those options are related to the kernel log in dmesg:

Config option

Oniro state

CONFIG_SECURITY_DMESG_RESTRICT

On

Source files: oniro/meta-oniro-core/recipes-kernel/linux/linux/hardening_dmesg.cfg

CONFIG_SECURITY_DMESG_RESTRICT=y

Description: This enforces restrictions on unprivileged users reading the kernel syslog via dmesg(8).

If this option is not selected, no restrictions will be enforced unless the dmesg_restrict sysctl is explicitly set to (1).

Recommendation source: KSPP 2

Compiler-level Hardening

Those options enable checks done by the compiler:

Config option

Oniro state

CONFIG_FORTIFY_SOURCE

On

Source file: oniro/meta-oniro-core/recipes-kernel/linux/linux/hardening_fortify_source.cfg.

CONFIG_FORTIFY_SOURCE=y

Description: Detect overflows of buffers in common string and memory functions where the compiler can determine and validate the buffer sizes.

Recommendation source: KSPP 2

Memory Accesses

With those options we disable the complete physical memory access and detect unsafe memory permissions:

Config option

Oniro state

CONFIG_DEBUG_WX CONFIG_DEVMEM

On Off

Source file: oniro/meta-oniro-core/recipes-kernel/linux/linux/hardening_memory.cfg.

CONFIG_DEBUG_WX=y

Description: Generates a warning if any W+X mappings are found at boot.

This is useful for discovering cases where the kernel is leaving W+X mappings after applying NX, as such mappings are a security risk.

Look for a message in dmesg output like this:

/mm: Checked W+X mappings: passed, no W+X pages found.

or like this, if the check failed:

/mm: Checked W+X mappings: failed, W+X pages found.

Note that even if the check fails, your kernel is possibly still fine, as W+X mappings are not a security hole in themselves, what they do is that they make the exploitation of other unfixed kernel bugs easier.

Recommendation source: KSPP 2

CONFIG_DEVMEM is not set

Reason: Disabling access to the whole memory mapping.

Description: Say Y here if you want to support the /dev/mem device. The /dev/mem device is used to access areas of physical memory.

Recommendation source: KSPP 2

Copying from Userspace

Those options add verification when copying potentially malicious data from the user space:

Config option

Oniro state

CONFIG_HARDENED_USERCOPY CONFIG_HARDENED_USERCOPY_FALLBACK

On Off

File: oniro/meta-oniro-core/recipes-kernel/linux/linux/hardening_usercopy.cfg.

Reason: Perform boundary checks on memory when copying to/from the kernel. Also disable the whitelisting with this check.

CONFIG_HARDENED_USERCOPY=y

Description: 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.

Recommendation source: KSPP 2

CONFIG_HARDENED_USERCOPY_FALLBACK is not set

Reason: Do not enable the whitelisting for usercopy checks. The kernel keeps a list of memory zones allowed for copying user data. This option was added to allow the transition from around 2017, but we assume all code we use has been already fixed.

Description: 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. This option will be removed once it seems like all missing usercopy whitelists have been identified and fixed. Booting with slab_common.usercopy_fallback=Y/N can change this setting.

Recommendation source: KSPP 2

Data Validation

With those options we add verification of the internal kernel data structures:

Config option

Oniro state

CONFIG_DEBUG_NOTIFIERS CONFIG_DEBUG_LIST CONFIG_DEBUG_SG CONFIG_BUG_ON_DATA_CORRUPTION CONFIG_SCHED_STACK_END_CHECK

On On On On On

File: oniro/meta-oniro-core/recipes-kernel/linux/linux/hardening_validation_checks.cfg.

CONFIG_DEBUG_KERNEL=y

Reason: Needed for CONFIG_SCHED_STACK_END_CHECK.

Description: Say Y here if you are developing drivers or trying to debug and identify kernel problems.

Recommendation source: KSPP 2

CONFIG_DEBUG_NOTIFIERS=y

Reason: Perform additional checks for the notifier call chains.

Description: Enable this to turn on sanity checking for notifier call chains. This is most useful for kernel developers to make sure that modules properly unregister themselves from notifier chains. This is a relatively cheap check, but if you care about maximum performance say N.

Recommendation source: KSPP 2

CONFIG_DEBUG_LIST=y

Reason: Perform additional checks for the lists.

Description: Enable this option to turn on extended checks in the linked-list walking routines.

Recommendation source: KSPP 2

CONFIG_DEBUG_SG=y

Reason: Perform additional checks for scatter-gather lists.

Description: Enable this option to turn on checks on scatter-gather tables. This can help find problems with drivers that do not properly initialize their sg tables.

Recommendation source: KSPP 2

CONFIG_BUG_ON_DATA_CORRUPTION=y

Reason: Detect data corruptions early and stop with a BUG() error message.

Description: Select this option if the kernel should BUG() when it encounters data corruption in kernel memory structures when they get checked for validity.

Recommendation source: KSPP 2

CONFIG_SCHED_STACK_END_CHECK=y

Reason: Check stack overflow when calling schedule(). If it happens, stop the system with a panic as the memory region could not be trusted.

Description: This option checks for a stack overrun on calls to schedule(). If the stack end location is found to be over written, always panic as the content of the corrupted region can no longer be trusted. This is to ensure no erroneous behaviour occurs which could result in data corruption or a sporadic crash at a later stage once the region is examined. The runtime overhead introduced is minimal.

Recommendation source: KSPP 2

Options not Applied (yet)

GCC plugins

GCC plugins offer ways to additionally harden the code at the compiler level. These options are proposed to be applied in the future releases.

IOMMU

IOMMU is not enabled yet.

Panic on Oops

File: Source file: hardening_fortify_source.cfg

KSPP 2 recomends setting up the following: ` CONFIG_PANIC_ON_OOPS=y CONFIG_PANIC_TIMEOUT=-1 `

They cause the kernel to reboot on serious error (Oops, see the Oops Wikipedia page <https://en.wikipedia.org/wiki/Linux_kernel_oops> for more information).

This might happen during development and result in a reboot loop, so it was decideed not to enable this options in the development phase. You can add this file to the kernel configuration if it is safe in your product.

Module Signing

Module signing is not enabled yet, we need the key infrastructure set up.

Known Issues

None.

References

1

Benchmarking of Linux kernel security options - a blog post from BlackIkeEagle Kconfig hardening tests

2(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23)

Kernel Self Protection Project (KSPP) is an initiative that works on adding security features to the Linux kernel. Among other things, they previde a set of recommendations on options to use.