kernel recompilation for better hardening

Then let’s use apparmor-profile-everything to block write access to these (/etc/sysctl.d and sysctl and whatnot) to prevent root from enabling core dumps. That reaches the same goal but doesn’t worsen debugging.

If there’s an issue now, and someone wants to debug it, we can say “use root, re-enable core dumps”, done.

If there’s an issue when apparmor-profile-everything is default, and someone wants to debug it, we can say “use superroot, re-enable core dumps”, done.

But if core dumps are disabled in kernel and once apparmor-profile-everything is default and someone wants to debug it, we don’t have a good answer. “Need superroot. And need to re-compile your kernel.” We’d need a debug kernel and a regular kernel. But issues producible with the regular kernel may not happen with the debug kernel. So if not needed, let’s not destroy debugging.

1 Like

Those are disabled anyway.

The same could be said for nearly every other security feature.

Why enable kptr_restrict or dmesg_restrict since they interfere with debugging?

Why remove System.map?

Why not give total, unrestricted access to /proc and /sys?

So many debugging features open up security holes. Some need to be sacrificed.

Besides, the chances an end user is going to need to look at core dumps on a stable kernel is very unlikely. Those are only really needed for developers testing stuff.

Recompiling the kernel isn’t that big of a deal due to hardened-vm-kernel (once it’s finished). We could even have a second package that allows users to add their own custom configurations and still being easy to use.

2 Likes

Things are difficult already. Very difficult.
I know people with university degrees, and engineering working in technology but not information technology. These are as much as that’s possible, “certified intelligent”. Yet, these are incapable to use any Linux desktop distribution. Let alone Whonix. Whonix is operating in a geek sphere. Yet, I don’t want to make it too difficult to make even more geeks give up.

It is my goal to follow the principle of least astonishment.

Disabling debugging can be a bad surprise already. But it’s justified for a security focused distribution. And it can be undo in one step by using root. And in future, it can be undone by using superroot. But disabling these settings and then also removing it from the kernel… That’s two times for the same thing. Even someone who managed to re-enable the debugging sysctl settings (using superroot) could still not debug.

It is also my goal to stay reasonable. I am expecting upcoming discussions. Using reasonable time effort to answer reasonable questions.

Why did you disable core dumps in sysctl settings?

Because, see Core Dumps - Kicksecure

Alright, but why don’t you let even root change these settings, it’s blocked by apparmor-profile-everything?

Because we’re implementing Untrusted Root - improve Security by Restricting Root too.

Alright, I see why core dumps are disabled by default and re-enabling requires superroot. I used superroot to enable core dumps. Why I still can’t get coredumps?

We disabled core dumps in kernel too. You need to recompile your kernel.

Kernel recompilation is pushing it. :confused: Why did you disable coredumps in kernel too if you already disabled the sysctl and blocked root from re-enalbing it using apparmor-profile-everything?

:thinking: That one I don’t know. :thinking:

The last answer isn’t reasonable. There needs to be a good answer for that.

Quite a lengthy potentially upcoming discussion. (Can often be shortened by writing documentation.) But super lengthy and complex already. I’d like to avoid layers of complexity if avoidable.

Yes but these are all easily undone in 1 step. Either with root or superoot. Disabling them has a reasonable justification and the process of re-enabling is reasonable too. Kernel recompilation is an extra step on top which isn’t well justified yet. Piling up unjustified things makes the project harder to maintain. Also I don’t want to push the level of complexity to a stage where I myself start to forget things and not see through anymore.

Slim, few people, but these can be very important people. I specifically don’t want to needlessly annoy super geeks too much. If there’s a great rationale for requiring a rain dance they might forgive, but I don’t want to be unreasonable.

2 Likes

Alright. Good point. I’ve now re-enabled coredumps https://github.com/madaidan/hardened-vm-kernel/commit/e6b8c4b4049fe2d98aba8f4de866718106f68a79

I still don’t think coredumps will ever be needed for the average user and “super geeks” would probably be able to re-compile the kernel.

1 Like

I don’t know why make keeps shifting around preempt stuff. Probably just dependency weirdness.

1 Like

Could you enable GCC_PLUGIN_RANDSTRUCT please?

(related: Hide Kernel Symbols for Better Security vs Reproducible Builds - #9 by madaidan)

1 Like

Randstruct isn’t supported by Debian yet unless we use backports.

It also comes with a large performance drop but there is a RANDSTRUCT_PERFORMANCE option which has worse security but better performance.

1 Like

Ignoring the apt during apt issue [1], I would like to make progress making this accessible to users. Currently we have no script / automation / documentation / awareness.

How to solve the following…?

~/kernel/linux-source-4.19 $ make deb-pkg
  LEX     scripts/kconfig/zconf.lex.c
  HOSTCC  scripts/kconfig/zconf.tab.o
  HOSTLD  scripts/kconfig/conf
scripts/kconfig/conf  --syncconfig Kconfig
***
*** Configuration file ".config" not found!
***
*** Please run some configurator (e.g. "make oldconfig" or
*** "make menuconfig" or "make xconfig").
***
make[2]: *** [scripts/kconfig/Makefile:69: syncconfig] Error 1
make[1]: *** [Makefile:533: syncconfig] Error 2
Makefile:620: include/config/auto.conf.cmd: No such file or directory
make: *** [Makefile:632: include/config/auto.conf.cmd] Error 2

What’s the solution to make this non-interactive (no user terminal input required)?

make defconfig?

Needs kernel source or gcc from backports? kernel source might be quite doable. I don’t think that would cause any conflicts. Otherwise mixing with backports could lead to issues. Not a great default choice for a distribution default.

But even gcc from backports would not be a blocker. I could script the following:
set up a chroot (based on buster, buster-backports, or whatever) and build the kernel inside the chroot. Perhaps even using cowbuilder.

If we want to create something amazing here, we might have to bite the bullet using backports, chroot, whatnot. Needless to say, ideally we could use linux-hardened.

To solve [1] (apt during apt) we might introduce a wrapper or teach users to use a tool other than apt if they want a hardened kernel. (More and more wrappers. Stream isolation (uwt), rapt (restricted APT) and now kernel upgrade.)

To make some progress I’ve added the build script.

https://github.com/Whonix/hardened-vm-kernel/blob/master/build

Could you try it please? It is still primitive. But it can be improved over time. Soon I can do the proper packaging. Install build to /usr/bin/hardened-kernel-build? Then this pacakge could be added to repository and users could manually run /usr/bin/hardened-kernel-build. Next step would be /usr/bin/hardened-kernel-install-and-build? Not a good name. And after this got more usable, the last step would be sorting out [1].

1 Like

Save https://github.com/Whonix/hardened-vm-kernel/blob/master/usr/share/hardened-vm-kernel/kernel-config as file .config in the directory containing the kernel source.

Probably both. Need to test.

Sounds like a good idea.

You should change

cp usr/share/hardened-vm-kernel/kernel-config "$source_folder"

to

cp usr/share/hardened-vm-kernel/kernel-config "$source_folder/.config"

Instead of using pushd and popd, you can use tar’s -C option, patch’s -d option and make’s -C option.

e.g.

tar -xaf "/usr/src/linux-source-${version}.tar.xz" -C "$working_folder"

xzcat "/usr/src/linux-patch-${version}-rt.patch.xz" | patch -p1 -d "$source_folder"

make deb-pkg -C "$source_folder"

make defconfig isn’t needed if the full config is already at .config.

You should use make deb-pkg -j $(nproc) so the compilation uses all available cores to speed up.

We might also want to use patch’s -s option to hide output unless it’s an error.

Users don’t need to manually run that. That can be done during package installation. Actually installing the kernel is the only problem.

To get rid of this problem entirely, we can replace make deb-pkg with just make and sort out the kernel images and bootloader configuration ourselves without needing to use the .debs.

1 Like
2 Likes

We don’t need the kernel source from backports. scripts/gcc-plugins/randomize_layout_plugin.c exists in the stable debian kernel sources.

Looking at the commit, the minimum gcc version is supposed to be 4.7 and debian’s is 8.3 so we should be able to use randstruct.

Searching make menuconfig, the randstruct option does exist but for some reason, it isn’t showing up in the menu or when grepping the config file.

These plugins might be hidden behind another config option we have to enable first.

1 Like

Found the problem. We need to install gcc-8-plugin-dev first.

1 Like
1 Like

Added all your suggestions.

(Not done: chroot / cowbuilder.)

There is one prompt which requires interactive entry.

+ make deb-pkg -j 8 -C /home/user/kernel/linux-source-4.19/
make: Entering directory '/home/user/kernel/linux-source-4.19'
  HOSTCC  scripts/basic/fixdep
  HOSTCC  scripts/kconfig/conf.o
  YACC    scripts/kconfig/zconf.tab.c
  LEX     scripts/kconfig/zconf.lex.c
  HOSTCC  scripts/kconfig/zconf.tab.o
  HOSTLD  scripts/kconfig/conf
scripts/kconfig/conf  --syncconfig Kconfig
*
* Restart config...
*
*
* General setup
*
Compile also drivers which will not load (COMPILE_TEST) [N/y/?] n
Local version - append to kernel release (LOCALVERSION) [] 
Automatically append version information to the version string (LOCALVERSION_AUTO) [N/y/?] n
Build ID Salt (BUILD_SALT) [4.19.0-67-amd64] 4.19.0-67-amd64
Kernel compression mode
  1. Gzip (KERNEL_GZIP)
  2. Bzip2 (KERNEL_BZIP2)
  3. LZMA (KERNEL_LZMA)
> 4. XZ (KERNEL_XZ)
  5. LZO (KERNEL_LZO)
  6. LZ4 (KERNEL_LZ4)
choice[1-6?]: 4
Default hostname (DEFAULT_HOSTNAME) [(none)] (none)
Support for paging of anonymous memory (swap) (SWAP) [Y/n/?] y
System V IPC (SYSVIPC) [Y/n/?] y
POSIX Message Queues (POSIX_MQUEUE) [Y/n/?] y
Enable process_vm_readv/writev syscalls (CROSS_MEMORY_ATTACH) [Y/n/?] y
uselib syscall (USELIB) [N/y/?] n
Auditing support (AUDIT) [Y/?] y
Preemption Model
  1. No Forced Preemption (Server) (PREEMPT_NONE)
> 2. Voluntary Kernel Preemption (Desktop) (PREEMPT_VOLUNTARY)
  3. Preemptible Kernel (Low-Latency Desktop) (PREEMPT__LL) (NEW)
  4. Preemptible Kernel (Basic RT) (PREEMPT_RTB) (NEW)
  5. Fully Preemptible Kernel (RT) (PREEMPT_RT_FULL) (NEW)
choice[1-5?]: 

Indeed.

And we need to use some trigger too. If he kernel source file is upgraded (security update by Debian), the kernel (and all modules) need to be rebuild too.

(https://wiki.debian.org/DpkgTriggers)

Maybe dpkg --force-all (or some more limited --force-something) parameter could do. Will try. Will also ask Debian mentors.

I hope not. A package is a good vehicle to get all the files in the right place and to cleanly remove these later on. It also integrates all with /etc/kernel/, dkms, initramfs, dracut, grub, dpkg triggers, what I am not even aware of and future changes.

2 Likes

I don’t get any prompts. Are you sure the config is at .config in the kernel source directory?

We can just copy/paste all that into our package. So users will just need to install hardened-vm-kernel and it will handle everything rather than needing to use wrappers or other things.

1 Like

Yes, I am sure.

diff usr/share/hardened-vm-kernel/kernel-config ~/kernel/linux-source-4.19/.config ; echo $?

0

I don’t know if that is possible without using a package. For example to trigger DKMS, a new kernel package needs to be installed. It may be possible to reinvent all of this (call DKMS ourselfes) but the bigger the hack, the more likely it will have bugs.

question | with a package | without a package
What kernel version is installed? | Check kernel package version. | ?
How to remove that kernel? | apt purge… | ?

By not using a package many things get messy / lots of code duplication / bugs.

1 Like

I can’t reproduce this. Exactly which of the config options does it prompt you about? Is it all of the ones you said or where some automatically selected?

Just one question. Just exactly that. That’s it.
Deleted working folder? That state. That might make the difference.

1 Like

That’s weird. CONFIG_PREEMPT_VOLUNTARY is already enabled https://github.com/Whonix/hardened-vm-kernel/blob/master/usr/share/hardened-vm-kernel/kernel-config#L89

Same as the default Debian config.

1 Like

I think we should sign all modules during build. After the build, we can sign lkrg, vbox guest additions etc. with scripts/sign-file, then we can destroy the private key with shred -zu in certs/ and enforce only signed module loading. This way, only signed modules can load, vbox won’t break and we don’t need to worry about a private key.

1 Like