← All rules
SOCLE-CLD-KRN-079// Kernel buildmediumeffective runtime

Unmap kernel when running in userspace (aka KAISER)

Requires the kernel to be built with CONFIG_UNMAP_KERNEL_AT_EL0=y, enabling the KPTI/KAISER page-table isolation that mitigates Meltdown on arm64.

Checked against the resolved running state (e.g. sshd -T, sysctl, systemctl show), catches drop-ins and Includes a file read would miss. Caveat: runtime ≠ persistence; a value correct now may not survive a reboot.

A pass proves✓ running now✓ on disk✓ survives rebootthe qualified verdict →
Debian 12CIS 1.1.0Debian 13CIS 1.0.0FedoraRHEL 10 / Rocky 10 / AlmaLinux 10RHEL 8 / Rocky 8 / AlmaLinux 8CIS 4.0.0RHEL 9 / Rocky 9 / AlmaLinux 9CIS 2.0.0Ubuntu 22.04CIS 3.0.0Ubuntu 24.04CIS 1.0.0Ubuntu 26.04
One check, maps to 1 standard

Pavois asserts the effective configuration, the live, resolved state, not a file. File-based scanners (OVAL/SCAP, Lynis) miss Includes, drop-ins and runtime defaults; this check sees what is actually applied.

A mapping is a cross-reference to where each standard places this requirement, anchored and cross-validated, not a claim of equivalence. A passing check is evidence toward these references, how to read it.

Why this rule matters

CONFIG_UNMAP_KERNEL_AT_EL0 enables the KPTI/KAISER mitigation on arm64: kernel page tables are unmapped while running at exception level 0 (userspace). Without it, an unprivileged process can mount the Meltdown (CVE-2017-5754) side-channel attack to read kernel memory, including credentials, keys and other processes' secrets, across the user/kernel boundary.

What Pavois checks

Pavois reads the build-time kernel config of the running kernel, /boot/config-$(uname -r) or /proc/config.gz, and requires CONFIG_UNMAP_KERNEL_AT_EL0=y. This reflects the kernel actually booted, not a config file that may describe a different or not-yet-installed kernel: a file-based scanner reading a stale /boot/config-* could pass while the live kernel lacks the mitigation.

only_if('arm64 only') { os.arch.to_s =~ /aarch64|arm/ }
describe command("grep -h '^CONFIG_UNMAP_KERNEL_AT_EL0=' /boot/config-$(uname -r) 2>/dev/null; zcat /proc/config.gz 2>/dev/null | grep '^CONFIG_UNMAP_KERNEL_AT_EL0='") do
  its('stdout') { should match(/^CONFIG_UNMAP_KERNEL_AT_EL0=y$/) }
end

How to verify it is applied

Run grep '^CONFIG_UNMAP_KERNEL_AT_EL0=' /boot/config-$(uname -r) (or zcat /proc/config.gz | grep CONFIG_UNMAP_KERNEL_AT_EL0). Expected output: CONFIG_UNMAP_KERNEL_AT_EL0=y. On arm64 you can also confirm the runtime state with cat /sys/devices/system/cpu/vulnerabilities/meltdown (expect Mitigation: PTI).

Inspect & investigate

There is no audit-log trail for a build-time option. Inspect the booted kernel's view: dmesg | grep -i 'kpti\|meltdown\|unmap' and cat /sys/devices/system/cpu/vulnerabilities/meltdown show whether the mitigation is active at runtime.

Remediation

No automated remediation: remediation is empty because this is a kernel build-time option that cannot be toggled on a running system. Fixing it requires installing a vendor kernel compiled with CONFIG_UNMAP_KERNEL_AT_EL0=y (all current Debian/Ubuntu/RHEL arm64 kernels already enable it). Apply it manually by booting a compliant kernel, then re-run the scan.

Pavois applies this with its own harden engine, the plan below, not a shell script:

resourcekernel_build
pavois harden plan local

where the target is local, a user@host SSH alias, or a container , Docs

Impact & precautions

Failing the check means the Meltdown mitigation is absent on arm64: kernel memory is potentially readable by any local process. Precautions before changing kernel: KPTI/PTI adds a small syscall/context-switch overhead (typically a few percent), and switching kernels can affect out-of-tree modules (GPU, storage). Test the new kernel on a non-production host, keep the previous kernel entry in the bootloader for rollback, and verify hardware drivers load before committing.

Standards mapping

StandardReferenceTypeVersionConfidence
ANSSI BP-028R27direct2.0high

Each reference is a cross-reference anchored in the upstream benchmark and cross-validated against the SCAP Security Guide and ansible-lockdown, not a claim of equivalence. Direct = a prescriptive, line-level requirement; supporting = an abstract control family (NIST) the check provides evidence toward. How to read a mapping.

Sources & references