enforce kernel module software signature verification [module signing] / disallow kernel module loading by default

Looking at the DKMS manpage, the POST and PRE options look interesting.

Also see the dkms.conf overrides sections.

It looks like we can just create a file /etc/dkms/virtualbox-guest.conf that has POST_BUILD=command or PRE_INSTALL=command in it. “command” being the script used to sign the module.

1 Like

This drop-in folder is functional. Tested. Module got load amd the error message was a different one. Just nontrivial to know the name of the actual name of the module. Not same as lsmod. Try to load it manually beforehand.

1 Like

We might not have to invent a DKMS module signing mechanism.

The VirtualBox upgrade from 6.0.8 to 6.0.10 might have broken this.

As per: https://www.virtualbox.org/ticket/11577?cnum_edit=16#comment:26

Above says that reverting https://www.virtualbox.org/changeset/79186/vbox fixed the issue.

I don’t know where to find that file on the disk. So can’t patch this.

Also that ticket seems to be about VirtualBox host modules but I guess the source code for module signing is being re-used for guest additions too. So still related.


Btw this is the tool already on the drive which allows to sign modules.

/usr/src/linux-headers-*/scripts/sign-file

Good to know but hopefully no need to use it for this very purpose.

1 Like

Ah, that’s why it didn’t work for me the last time. I formatted the output of the two lsmods to get the list of modules.

1 Like
1 Like

For development / debugging it is useful to use sort to format the output of lsmod to make it easier readable and comparable. I.e.:

sudo lsmod | sort

And write to a file.

sudo lsmod | sort > lsmod_before

Then disable module loading. And load some modules through /usr/lib/modules-load.d folder or so. Then look at lsmod again.

sudo lsmod | sort > lsmod_after

Then compare.

meld lsmod_before lsmod_after

Use of kernel.modules_disabled=1 is now possible and initially documented:
Operating System Hardening - Kicksecure

However, I don’t think the current approach using /usr/lib/modules-load.d folder is a good implementation. Therefore not committed to git yet. Just a proof of concept. It would be better to load those systemd units that require kernel modules early enough before systemd-sysctl.service. Therefore we could avoid being the first distribution writing to /usr/lib/modules-load.d folder.

The problem with /usr/lib/modules-load.d is:

  • non-standard
  • not yet discussed with any upstream
  • manually maintained module lists might get outdated after kernel upgrades, things might break

We’re not the first ever to have this issue. Bug was reported here https://bugzilla.redhat.com/show_bug.cgi?id=1198949 and then dismissed. That doesn’t discourage us discussing this elsewhere.


lsmod columns here:

Module Size Used by

Modules have “dependency trees”. Therefore I skiped adding those modules to /usr/lib/modules-load.d which are not Used by other modules. The idea was to only add the “top level” modules and let dependencies resolve itself in case in later kernel versions dependencies change (less modules perhaps) no update of the file would be required.


Working on this seems worthwhile. Thereby we can review what kernel modules are load, learn new things, perhaps reduce attack surface. For example:

A graphical session (perhaps X, XFCE and/or lightdm) automatically loads module binfmt_misc. Seems to be this:

Dunno yet if it is a good idea to have this in the kernel. It’s possible to avoid loading this module too but don’t know yet if it breaks anything.

1 Like

An alternative way would be to create a systemd service that runs after systemd-modules-load.service and sets kernel.modules_disabled=1.

This should make sure that all modules are loaded before we set that setting. I haven’t tested this though and it might lead to another error like with systemd-sysctl.

I don’t think that’s a good idea, systemd-sysctl is one of the first services to start. Starting a bunch of units before that would likely be way too early.

The official documentation is here Kernel Support for miscellaneous Binary Formats (binfmt_misc) — The Linux Kernel documentation

Not sure what it’s used for.

2 Likes

madaidan via Whonix Forum:

An alternative way would be to create a systemd service that runs after systemd-modules-load.service and sets kernel.modules_disabled=1.

… and after systemd-sysctl.service (since that can be used to
influence kernel module loading).

This should make sure that all modules are loaded before we set that setting.> I haven’t tested this though and it might lead to another error like
with systemd-sysctl.

Does not work for sure. kloak as is now would still fail to load since
trying to autoload the uinput kernel module. We’d still need to use
/usr/lib/modules-load.d.

Need to find out if there is a better way than requiring all upstreams
to define their modules in /usr/lib/modules-load.d.

I don’t think that’s a good idea, systemd-sysctl is one of the first services to start. Starting a bunch of units before that would likely be way too early.

Good point. Might be inappropriate for some services indeed. Need to ask
various upstream, not sure to whom this is up. Looks like unchartered
territory. Very few search results on search engines.

1 Like

Probably systemd since it handles the module loading and sysctl.

1 Like

What happened to ModAutoRestrict LSM?

https://lwn.net/Articles/719385/

1 Like
1 Like

It probably got scrapped in favour of kernel.modules_disabled=1.

I have no idea why people try to make features like these LSMs. It’s just unneeded complexity for a simple option.

1 Like

Debian -- Details of package lockdown in buster already invented disabling module after boot.

It could be improved to fine tune when module lockdown happens. At the moment execution time isn’t fixed.

Contacted lockdown and hardening-runtime.

Package: hardening-runtime
Severity: wishlist
X-Debbugs-CC: whonix-devel@whonix.org

We now have (at least) three very similar packages.

Let’s join forces before we independently reinvent everything.

Cheers,
Patrick

The idea is to have more eyes on this. And more benefit to more users. Therefore also beneficial due to wider testing.

2 Likes

It turns out, this won’t only be useful for the root user. Unprivileged users can still indirectly load kernel modules through auto-loading.

E.g. an attacker tries to use X protocol, the needed kernel module is auto-loaded even though the attacker is unprivileged and then the attacker exploits a vulnerability in X module.

Setting kernel.modules_disabled=1 will prevent the module from being loaded regardless.

Blacklisting the modules in modprobe.d would also prevent auto-loading of that specific module as it makes run /bin/false instead of auto-loading it.

There is a currently unaccepted patch that restricts auto-loading of kernel modules to root only called the Timgad LSM though.

1 Like

This is a much better and more recent version of the patch.

https://lkml.org/lkml/2017/11/27/754

1 Like

Got answer:

RFE: add module-load-only-if-modules_disabled.d · Issue #13540 · systemd/systemd · GitHub

Why would you turn off on-demand loading? Where is the difference of loading something ondemand vs explicitly when it comes to security? If you dont trust a module dont ship/install it. If you trust it it shouldnt mayter if you load it at boot or when actually used. What am I missing?

2 Likes

The issue was closed.

RFE: add module-load-only-if-modules_disabled.d · Issue #13540 · systemd/systemd · GitHub

I don’t think this is for upstream systemd to manage. It may be possible to declare a static list of modules to load, but it is only possible in very specific circumstances, when you know exactly which hardware, which network devices, which network protocols, which encryption types, etc, etc, any given application will use. But even on a medium-sized distro this would be completely infeasible.

2 Likes

https://lists.archlinux.org/pipermail/arch-general/2015-July/039589.html

Signed modules don’t really offer any added security with a vanilla
kernel because root still has full control over the kernel via other
known mechanisms (i.e. no exploits necessary). The feature is mostly useful for enforcing a policy of not allowing third party modules, similar to the kernel taint bits which can be overwritten if you really feel like doing it.

It’s not a very compelling feature though because it’s only truly useful in combination with a fully read-only root and grsecurity’s romount_protect feature.

A strong MAC policy could also plug the other attack routes… but it’s also going to prevent loading modules for that role anyway.

1 Like

New versions of DKMS have a SIGN_TOOL= feature. Please have a look, see if that looks alright, and give feedback to the DKMS developers:

SIGN_TOOL=

The module signing tool to be run at a build. Two arguments will be passed to the signing tool. The first argument is the target kernel version, the second is the module file path. If the tool exits with a non-zero value, the build will be aborted.

2 Likes
2 Likes