If you say Y here, getting information on loaded modules, and
displaying all kernel symbols through a syscall will be restricted
to users with CAP_SYS_MODULE. For software compatibility reasons,
/proc/kallsyms will be restricted to the root user. The RBAC
system can hide that entry even from root.
This option also prevents leaking of kernel addresses through
several /proc entries.
Note that this option is only effective provided the following
conditions are met:
The kernel using grsecurity is not precompiled by some distribution
You have also enabled GRKERNSEC_DMESG
You are using the RBAC system and hiding other files such as your
kernel image and System.map. Alternatively, enabling this option
causes the permissions on /boot, /lib/modules, and the kernel
source directory to change at compile time to prevent
reading by non-root users.
If the above conditions are met, this option will aid in providing a
useful protection against local kernel exploitation of overflows
and arbitrary read/write vulnerabilities.
It is highly recommended that you enable GRKERNSEC_PERF_HARDEN
in addition to this feature.
Is hiding kernel symbols even possible without grsecurity?
Why even the kernel source directory should be hidden?
One idea of kernel recompilation for better hardening was the recompile on the users machine so the kernel would be uniquely compiled and kernel symbols would stay hidden, Rather than using Debian public kernel (from packages.debian.org) which has public well known kernel symbols.
But Debian is working towards reproducible builds. Thereby when compiling the Debian kernel on the user’s machine, it is likely the user would end up with a byte identical versions.
Could we use a reproducibility build kernel and then somehow instruct the kernel (through a kernel parameter or something) automagically randomize its kernel symbols addresses?
Assume this is true. Assume we have HIDESYM / kernel.kptr_restrict.
The critical point is…
vs nowadays reproducible builds. The kernel image cannot be in a public known state. It needs to be unique, private.
How the kernel image looks is public knowledge or easily knowable by compiling oneself.
Quote:
In the initial discussion about hiding /proc/kallsyms, a few people pointed out that most installations are distro kernels, and attackers can simply hard-code the addresses for the necessary functions.
system.map (kernel symbol addresses) file can be created from public or self-compiled kernel (vmlinux) (attacker could recompile. Just use the source code, and version and config we are using). Thanks to (mostly or already fully) reproduiclbe builds, the attacker would have the vmlinux binary. And then could deduct the kernel symbol addresses from that. Then hardcode these addresses in malware.
The only way to prevent that is to recompile the vmlinux binary in a… How? Randomize the vmlinux build somehow? A kernel parameter? Somehow supply the kernel with a random file so it can randomize itself?
The only thing I know that does this is OpenBSD’s KARL which basically generates a new kernel on each reboot. There doesn’t seem to be any equivalent for Linux.
No, ASLR is only for userspace memory. KASLR is for kernel memory and doesn’t change any kernel pointers. One of the reasons KASLR was such a bad idea is because the kernel is full of kernel pointer leaks.
Grsec made a good blog post on it.
As for kstructhunter, structleak should prevent that but because Debian’s repos are so old, it doesn’t yet support that.
I think you might be confused. Kernel structs and kernel pointers aren’t the same. While randstruct is important, it’s not really the point of this post.