Kernel Hardening (Whonix and/or Qubes-Whonix)

@Patrick

Hi Patrick,

I read somewhere where you were discussing hardening the kernel/s in either Whonix and/or Qubes with other developers.

This information below may be of use (?) - recommendations for ‘paranoid settings’ from the Kernel Hardening Project.

I’m not sure of the default kernel settings in Debian/Fedora etc that is used in Qubes-Whonix and non-Qubes-Whonix.

http://kernsec.org/wiki/index.php/Kernel_Self_Protection_Project#Recommended_settings

Key section:

Recommended settings
People ask from time to time what a good security set of build
CONFIGs and runtime sysctl are. This is a brain-dump of the various
options for a particularly paranoid system.

CONFIGs

Report BUG() conditions and kill the offending process.

CONFIG_BUG=y

Make sure kernel page tables have safe permissions.

CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_RODATA=y

Use -fstack-protector-strong (gcc 4.9+) for best stack canary coverage.

CONFIG_CC_STACKPROTECTOR=y
CONFIG_CC_STACKPROTECTOR_STRONG=y

Blocks direct physical memory access.

CONFIG_STRICT_DEVMEM=y

Provides some protections against SYN flooding.

CONFIG_SYN_COOKIES=y

Perform additional validation of various commonly targetted structures.

CONFIG_DEBUG_CREDENTIALS=y
CONFIG_DEBUG_NOTIFIERS=y
CONFIG_DEBUG_LIST=y

Provide userspace with seccomp BPF API for syscall attack surface reduction.

CONFIG_SECCOMP=y
CONFIG_SECCOMP_FILTER=y

Provide userspace with ptrace ancestry protections.

CONFIG_SECURITY=y
CONFIG_SECURITY_YAMA=y

Perform usercopy bounds checking.

CONFIG_HARDENED_USERCOPY=y

Randomize allocator freelists.

CONFIG_SLAB_FREELIST_RANDOM=y

Allow allocator validation checking to be enabled.

CONFIG_SLUB_DEBUG=y

Dangerous; allows direct physical memory writing.

CONFIG_ACPI_CUSTOM_METHOD is not set

Dangerous; disables brk ASLR.

CONFIG_COMPAT_BRK is not set

Dangerous; disables VDSO ASLR.

CONFIG_COMPAT_VDSO is not set

Dangerous; allows direct kernel memory writing.

CONFIG_DEVKMEM is not set

Dangerous; allows replacement of running kernel.

CONFIG_KEXEC is not set

Dangerous; allows replacement of running kernel.

CONFIG_HIBERNATION is not set

Prior to v4.1, assists heap memory attacks; best to keep interface disabled.

CONFIG_INET_DIAG is not set

Easily confused by misconfigured userspace, keep off.

CONFIG_BINFMT_MISC is not set

Use the modern PTY interface (devpts) only.

CONFIG_LEGACY_PTYS is not set

Reboot devices immediately if kernel experiences an Oops.

CONFIG_PANIC_ON_OOPS=y
CONFIG_PANIC_TIMEOUT=-1

Keep root from altering kernel memory via loadable modules.

CONFIG_MODULES is not set

But if CONFIG_MODULE=y is needed, at least they must be signed with a per-build key.

CONFIG_DEBUG_SET_MODULE_RONX=y
CONFIG_MODULE_SIG=y
CONFIG_MODULE_SIG_FORCE=y
CONFIG_MODULE_SIG_ALL=y
CONFIG_MODULE_SIG_SHA512=y
CONFIG_MODULE_SIG_HASH=“sha512”
CONFIG_MODULE_SIG_KEY=“certs/signing_key.pem”

x86_32

On 32-bit kernels, require PAE for NX bit support.

CONFIG_M486 is not set

CONFIG_HIGHMEM4G is not set

CONFIG_HIGHMEM64G=y
CONFIG_X86_PAE=y

Disallow allocating the first 64k of memory.

CONFIG_DEFAULT_MMAP_MIN_ADDR=65536

Randomize position of kernel.

CONFIG_RANDOMIZE_BASE=y

x86_64

Full 64-bit means PAE and NX bit.

CONFIG_X86_64=y

Disallow allocating the first 64k of memory.

CONFIG_DEFAULT_MMAP_MIN_ADDR=65536

Randomize position of kernel and memory.

CONFIG_RANDOMIZE_BASE=y
CONFIG_RANDOMIZE_MEMORY=y

Modern libc no longer needs a fixed-position mapping in userspace, remove it as a possible target.

CONFIG_LEGACY_VSYSCALL_NONE=y

Remove additional attack surface, unless you really need them.

CONFIG_IA32_EMULATION is not set

CONFIG_X86_X32 is not set

CONFIG_MODIFY_LDT_SYSCALL is not set

arm

Disallow allocating the first 32k of memory (cannot be 64k due to ARM loader).

CONFIG_DEFAULT_MMAP_MIN_ADDR=32768

For maximal userspace memory area (and maximum ASLR).

CONFIG_VMSPLIT_3G=y

If building an out-of-tree Qualcomm kernel, this is similar to CONFIG_DEBUG_RODATA.

CONFIG_STRICT_MEMORY_RWX=y

Make sure PXN/PAN emulation is enabled.

CONFIG_CPU_SW_DOMAIN_PAN=y

Dangerous; old interfaces and needless additional attack surface.

CONFIG_OABI_COMPAT is unset

arm64

Disallow allocating the first 32k of memory (cannot be 64k due to ARM loader).

CONFIG_DEFAULT_MMAP_MIN_ADDR=32768

Randomize position of kernel (requires UEFI RNG or bootloader support for /chosen/kaslr-seed DT property).

CONFIG_RANDOMIZE_BASE=y

kernel command line options

Enable allocator free poisoning.

slub_debug=P

x86_64

Remove vsyscall entirely to avoid it being a fixed-position ROP target of any kind.

(Same as CONFIG_LEGACY_VSYSCALL_NONE=y above.)

vsyscall=none

sysctls

Try to keep kernel address exposures out of various /proc files (kallsyms, modules, etc).

kernel.kptr_restrict = 1

Avoid kernel memory address exposures via dmesg.

kernel.dmesg_restrict = 1

Block non-uid-0 profiling

kernel.perf_event_paranoid = 3

Turn off kexec, even if it’s built in.

kernel.kexec_load_disabled = 1

Avoid non-ancestor ptrace access to running processes and their credentials.

kernel.yama.ptrace_scope = 1

This is hard to do oneself. Let alone deploy in a Linux distribution.

If it was simple, it would be a standard feature of Debian already. If we get to that point, I cannot say yet.

Mentioned here:
Advanced Security Guide - Whonix

That the Linux project is moving to improve kernel security is a welcome development on the surface. However their cherry-picking approach of minor Grsec features makes the effort a security theater exercise. All the features of Grsec work together to provide the robust security it has. Unless a serious effort is made to add all of it there isn’t much real world protection we can expect to see in vanilla kernels.