Harden memory copies between kernel and userspace
Requires the kernel to be built with CONFIG_HARDENED_USERCOPY=y so userspace copies are bounds-checked against object size.
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.
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_HARDENED_USERCOPY=y makes the kernel validate every copy_to_user/copy_from_user against the bounds of the source/destination object. Without it, a copy that overruns a heap or stack object goes unchecked, turning ordinary bugs into kernel memory disclosures (leaking secrets, defeating KASLR) or heap overflow primitives that drive privilege-escalation exploits. Enabling it neutralizes entire classes of these attacks at low runtime cost.
What Pavois checks
Pavois reads the build configuration of the running kernel, /boot/config-$(uname -r) and the in-memory /proc/config.gz, and confirms CONFIG_HARDENED_USERCOPY=y. This targets the kernel actually booted, not a stale /boot/config-* left by a previous package, so a custom or vendor kernel that silently dropped the option is caught.
describe command("C=/boot/config-$(uname -r); if [ -r \"$C\" ]; then cat \"$C\"; elif zcat /proc/config.gz 2>/dev/null | head -1 | grep -q .; then zcat /proc/config.gz; else echo PAVOIS_NO_KERNEL_CONFIG; fi | grep -E '^(CONFIG_HARDENED_USERCOPY=|PAVOIS_NO_KERNEL_CONFIG)'") do
its('stdout') { should_not match(/PAVOIS_NO_KERNEL_CONFIG/) }
its('stdout') { should match(/^CONFIG_HARDENED_USERCOPY=y$/) }
endHow to verify it is applied
Run grep '^CONFIG_HARDENED_USERCOPY=' /boot/config-$(uname -r) (or zcat /proc/config.gz | grep CONFIG_HARDENED_USERCOPY). Expected output: CONFIG_HARDENED_USERCOPY=y.
Inspect & investigate
When the protection trips at runtime the kernel logs a usercopy fault, inspect dmesg | grep -i usercopy or journalctl -k | grep -i usercopy for messages like usercopy: Kernel memory overwrite attempt detected.
Remediation
No automated remediation: this is a kernel build-time option, not a runtime tunable. Pavois's harden plan is empty. To fix it you must boot a kernel compiled with CONFIG_HARDENED_USERCOPY=y, install a distribution kernel that ships it (current Debian/Ubuntu/RHEL kernels do) or rebuild your custom kernel with the option set, then reboot.
Pavois applies this with its own harden engine, the plan below, not a shell script:
| resource | kernel_build |
|---|
pavois harden plan localwhere the target is local, a user@host SSH alias, or a container , Docs
Impact & precautions
If the option is absent, the kernel offers no bounds checking on userspace copies, leaving the system exposed to memory-disclosure and heap-overflow exploitation. Changing it requires booting a different kernel: validate that the replacement kernel still boots and loads all required drivers/modules before removing the old one. Keep the previous kernel entry in the bootloader so you can fall back if the new kernel fails to boot.
Standards mapping
| Standard | Reference | Type | Version | Confidence |
|---|---|---|---|---|
| ANSSI BP-028 | R15 | direct | 2.0 | high |
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.