Posts Tagged ‘virtualbox’

SecureBoot and VirtualBox kernel modules

Saturday, June 1st, 2019

Installing VirtualBox on Ubuntu 18 (same as for modern Fedora Core) with SecureBoot will result in the following error when running the command /sbin/vboxsetup

The error message would be something like this:

There were problems setting up VirtualBox. To re-start the set-up process, run
/sbin/vboxconfig
as root. If your system is using EFI Secure Boot you may need to sign the
kernel modules (vboxdrv, vboxnetflt, vboxnetadp, vboxpci) before you can load
them. Please see your Linux system’s documentation for more information.

This is because SecureBoot would not allow for non-signed kernel drivers, and VirtualBox creates its own drivers as part of its configuration.

I have found a great solution for this problem in the answers to this question here, which goes as follows:

Create a file (as root) called /usr/bin/ensure-vbox-signed with the following content:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#!/bin/bash
 
MOKUTIL="/usr/bin/mokutil"
MODPROBE="/sbin/modprobe"
MODINFO="/sbin/modinfo"
SIG_DIR="/var/lib/shim-signed/mok"
PUB="${SIG_DIR}/MOK.der"
KEY="${SIG_DIR}/MOK.priv"
 
if ! "${MOKUTIL}" --sb-state | grep -qi '[[:space:]]enabled$' ; then
	echo "WARNING: Secure Boot is not enabled, signing is not necessary"
	exit 0
fi
 
# If secure boot is enabled, we try to find the signature keys
[ -f "${KEY}" ] || { echo "ERROR: Couldn't find the MOK private key at ${KEY}" ; exit 1 ; }
[ -f "${PUB}" ] || { echo "ERROR: Couldn't find the MOK public key at ${PUB}" ; exit 1 ; }
 
INFO="$("${MODINFO}" -n vboxdrv)"
if [ -z "${INFO}" ] ; then
	# If there's no such module, compile it
	/usr/lib/virtualbox/vboxdrv.sh setup
	INFO="$("${MODINFO}" -n vboxdrv)"
	if [ -z "${INFO}" ] ; then
		echo "ERROR: Module compilation failed (${MODPROBE} couldn't find it after vboxdrv.sh was called)"
		exit 1
	fi
fi
 
KVER="${1}"
[ -z "${KVER}" ] && KVER="$(uname -r)"
 
KDIR="/usr/src/linux-headers-${KVER}"
DIR="$(dirname "${INFO}")"
 
for module in "${DIR}"/vbox*.ko ; do
	MOD="$(basename "${module}")"
	MOD="${MOD//.*/}"
 
	# Quick check - if the module loads, it needs no signing
	echo "Loading ${MOD}..."
	"${MODPROBE}" "${MOD}" && continue
 
	# The module didn't load, and it must have been built (above), so it needs signing
	echo "Signing ${MOD}..."
	if ! "${KDIR}/scripts/sign-file" sha256 "${KEY}" "${PUB}" "${module}" ; then
		echo -e "\tFailed to sign ${module} with ${KEY} and ${PUB} (rc=${?}, kernel=${KVER})"
		exit 1
	fi
 
	echo "Reloading the signed ${MOD}..."
	if ! "${MODPROBE}" "${MOD}" ; then
		echo -e "\tSigned ${MOD}, but failed to load it from ${module}"
		exit 1
	fi
	echo "Loaded the signed ${MOD}!"
done
exit 0

Make sure this file is executable by root. Create a systemd service /etc/systemd/system/ensure-vboxdrv-signed.service with the following contents:

[Unit]
SourcePath=/usr/bin/ensure-vbox-signed
Description=Ensure the VirtualBox Linux kernel modules are signed
Before=vboxdrv.service
After=

[Service]
Type=oneshot
Restart=no
TimeoutSec=30
IgnoreSIGPIPE=no
KillMode=process
GuessMainPID=no
RemainAfterExit=yes
ExecStart=/usr/bin/ensure-vbox-signed

[Install]
WantedBy=multi-user.target
RequiredBy=vboxdrv.service

Run sudo systemctl reload-daemon, and then enable the service by running sudo systemctl start ensure-vboxdrv-signed.service

It should sign and enable your vbox drivers, and allow you to run your VirtualBox machines.