VirtualBox

source: vbox/trunk/src/VBox/Installer/linux/vboxdrv.sh@ 98715

Last change on this file since 98715 was 98565, checked in by vboxsync, 22 months ago

Linux: rcvboxdrv: Allow to bypass forced kernel modules signature validation, bugref:10287.

Added a tweak which allows to bypass modules signature validation for distributions
which do not provide tools for that. Administrator should explicitly add:

VBOX_BYPASS_MODULES_SIGNATURE_CHECK="1"

into /etc/vbox/vbox.cfg in order to enable this tweak.

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Author Date Id Revision
File size: 29.0 KB
Line 
1#! /bin/sh
2# Oracle VM VirtualBox
3# Linux kernel module init script
4
5#
6# Copyright (C) 2006-2023 Oracle and/or its affiliates.
7#
8# This file is part of VirtualBox base platform packages, as
9# available from https://www.virtualbox.org.
10#
11# This program is free software; you can redistribute it and/or
12# modify it under the terms of the GNU General Public License
13# as published by the Free Software Foundation, in version 3 of the
14# License.
15#
16# This program is distributed in the hope that it will be useful, but
17# WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19# General Public License for more details.
20#
21# You should have received a copy of the GNU General Public License
22# along with this program; if not, see <https://www.gnu.org/licenses>.
23#
24# SPDX-License-Identifier: GPL-3.0-only
25#
26
27# chkconfig: 345 20 80
28# description: VirtualBox Linux kernel module
29#
30### BEGIN INIT INFO
31# Provides: vboxdrv
32# Required-Start: $syslog
33# Required-Stop:
34# Default-Start: 2 3 4 5
35# Default-Stop: 0 1 6
36# Short-Description: VirtualBox Linux kernel module
37### END INIT INFO
38
39## @todo This file duplicates a lot of script with vboxadd.sh. When making
40# changes please try to reduce differences between the two wherever possible.
41
42## @todo Remove the stop_vms target so that this script is only relevant to
43# kernel modules. Nice but not urgent.
44
45PATH=/sbin:/bin:/usr/sbin:/usr/bin:$PATH
46DEVICE=/dev/vboxdrv
47MODPROBE=/sbin/modprobe
48SCRIPTNAME=vboxdrv.sh
49
50# The below is GNU-specific. See VBox.sh for the longer Solaris/OS X version.
51TARGET=`readlink -e -- "${0}"` || exit 1
52SCRIPT_DIR="${TARGET%/[!/]*}"
53
54if $MODPROBE -c | grep -q '^allow_unsupported_modules *0'; then
55 MODPROBE="$MODPROBE --allow-unsupported-modules"
56fi
57
58setup_log()
59{
60 test -n "${LOG}" && return 0
61 # Rotate log files
62 LOG="/var/log/vbox-setup.log"
63 mv "${LOG}.3" "${LOG}.4" 2>/dev/null
64 mv "${LOG}.2" "${LOG}.3" 2>/dev/null
65 mv "${LOG}.1" "${LOG}.2" 2>/dev/null
66 mv "${LOG}" "${LOG}.1" 2>/dev/null
67}
68
69[ -f /etc/vbox/vbox.cfg ] && . /etc/vbox/vbox.cfg
70export VBOX_KBUILD_TYPE
71export USERNAME
72export USER=$USERNAME
73
74if test -n "${INSTALL_DIR}" && test -x "${INSTALL_DIR}/VirtualBox"; then
75 MODULE_SRC="${INSTALL_DIR}/src/vboxhost"
76elif test -x /usr/lib/virtualbox/VirtualBox; then
77 INSTALL_DIR=/usr/lib/virtualbox
78 MODULE_SRC="/usr/share/virtualbox/src/vboxhost"
79elif test -x "${SCRIPT_DIR}/VirtualBox"; then
80 # Executing from the build directory
81 INSTALL_DIR="${SCRIPT_DIR}"
82 MODULE_SRC="${INSTALL_DIR}/src"
83else
84 # Silently exit if the package was uninstalled but not purged.
85 # Applies to Debian packages only (but shouldn't hurt elsewhere)
86 exit 0
87fi
88VIRTUALBOX="${INSTALL_DIR}/VirtualBox"
89VBOXMANAGE="${INSTALL_DIR}/VBoxManage"
90BUILDINTMP="${MODULE_SRC}/build_in_tmp"
91if test -u "${VIRTUALBOX}"; then
92 GROUP=root
93 DEVICE_MODE=0600
94else
95 GROUP=vboxusers
96 DEVICE_MODE=0660
97fi
98
99KERN_VER=`uname -r`
100
101# Prepend PATH for building UEK7 on OL8 distribution.
102case "$KERN_VER" in
103 5.15.0-*.el8uek*) PATH="/opt/rh/gcc-toolset-11/root/usr/bin:$PATH";;
104esac
105
106if test -e "${MODULE_SRC}/vboxpci"; then
107 MODULE_LIST="vboxdrv vboxnetflt vboxnetadp vboxpci"
108else
109 MODULE_LIST="vboxdrv vboxnetflt vboxnetadp"
110fi
111# Secure boot state.
112case "`mokutil --sb-state 2>/dev/null`" in
113 *"disabled in shim"*) unset HAVE_SEC_BOOT;;
114 *"SecureBoot enabled"*) HAVE_SEC_BOOT=true;;
115 *) unset HAVE_SEC_BOOT;;
116esac
117# So far we can only sign modules on Ubuntu and on Debian 10 and later.
118DEB_PUB_KEY=/var/lib/shim-signed/mok/MOK.der
119DEB_PRIV_KEY=/var/lib/shim-signed/mok/MOK.priv
120unset HAVE_DEB_KEY
121case "`mokutil --test-key "$DEB_PUB_KEY" 2>/dev/null`" in
122 *"is already"*) DEB_KEY_ENROLLED=true;;
123 *) unset DEB_KEY_ENROLLED;;
124esac
125
126# Try to find a tool for modules signing.
127SIGN_TOOL=$(which kmodsign 2>/dev/null)
128# Attempt to use in-kernel signing tool if kmodsign not found.
129if test -z "$SIGN_TOOL"; then
130 if test -x "/lib/modules/$KERN_VER/build/scripts/sign-file"; then
131 SIGN_TOOL="/lib/modules/$KERN_VER/build/scripts/sign-file"
132 fi
133fi
134
135# Check if update-secureboot-policy tool supports required commandline options.
136update_secureboot_policy_supports()
137{
138 opt_name="$1"
139 [ -n "$opt_name" ] || return
140
141 [ -z "$(update-secureboot-policy --help 2>&1 | grep "$opt_name")" ] && return
142 echo "1"
143}
144
145HAVE_UPDATE_SECUREBOOT_POLICY_TOOL=
146if type update-secureboot-policy >/dev/null 2>&1; then
147 [ "$(update_secureboot_policy_supports new-key)" = "1" -a "$(update_secureboot_policy_supports enroll-key)" = "1" ] && \
148 HAVE_UPDATE_SECUREBOOT_POLICY_TOOL=true
149fi
150
151[ -r /etc/default/virtualbox ] && . /etc/default/virtualbox
152
153# Preamble for Gentoo
154if [ "`which $0`" = "/sbin/rc" ]; then
155 shift
156fi
157
158begin_msg()
159{
160 test -n "${2}" && echo "${SCRIPTNAME}: ${1}."
161 logger -t "${SCRIPTNAME}" "${1}."
162}
163
164succ_msg()
165{
166 logger -t "${SCRIPTNAME}" "${1}."
167}
168
169fail_msg()
170{
171 echo "${SCRIPTNAME}: failed: ${1}." >&2
172 logger -t "${SCRIPTNAME}" "failed: ${1}."
173}
174
175failure()
176{
177 fail_msg "$1"
178 exit 1
179}
180
181running()
182{
183 lsmod | grep -q "$1[^_-]"
184}
185
186log()
187{
188 setup_log
189 echo "${1}" >> "${LOG}"
190}
191
192module_build_log()
193{
194 setup_log
195 echo "${1}" | egrep -v \
196 "^test -e include/generated/autoconf.h|^echo >&2|^/bin/false\)$" \
197 >> "${LOG}"
198}
199
200# Detect VirtualBox version info or report error.
201VBOX_VERSION="`"$VBOXMANAGE" -v | cut -d r -f1`"
202[ -n "$VBOX_VERSION" ] || failure 'Cannot detect VirtualBox version number'
203VBOX_REVISION="r`"$VBOXMANAGE" -v | cut -d r -f2`"
204[ "$VBOX_REVISION" != "r" ] || failure 'Cannot detect VirtualBox revision number'
205
206## Output the vboxdrv part of our udev rule. This is redirected to the right file.
207udev_write_vboxdrv() {
208 VBOXDRV_GRP="$1"
209 VBOXDRV_MODE="$2"
210
211 echo "KERNEL==\"vboxdrv\", OWNER=\"root\", GROUP=\"$VBOXDRV_GRP\", MODE=\"$VBOXDRV_MODE\""
212 echo "KERNEL==\"vboxdrvu\", OWNER=\"root\", GROUP=\"root\", MODE=\"0666\""
213 echo "KERNEL==\"vboxnetctl\", OWNER=\"root\", GROUP=\"$VBOXDRV_GRP\", MODE=\"$VBOXDRV_MODE\""
214}
215
216## Output the USB part of our udev rule. This is redirected to the right file.
217udev_write_usb() {
218 INSTALLATION_DIR="$1"
219 USB_GROUP="$2"
220
221 echo "SUBSYSTEM==\"usb_device\", ACTION==\"add\", RUN+=\"$INSTALLATION_DIR/VBoxCreateUSBNode.sh \$major \$minor \$attr{bDeviceClass}${USB_GROUP}\""
222 echo "SUBSYSTEM==\"usb\", ACTION==\"add\", ENV{DEVTYPE}==\"usb_device\", RUN+=\"$INSTALLATION_DIR/VBoxCreateUSBNode.sh \$major \$minor \$attr{bDeviceClass}${USB_GROUP}\""
223 echo "SUBSYSTEM==\"usb_device\", ACTION==\"remove\", RUN+=\"$INSTALLATION_DIR/VBoxCreateUSBNode.sh --remove \$major \$minor\""
224 echo "SUBSYSTEM==\"usb\", ACTION==\"remove\", ENV{DEVTYPE}==\"usb_device\", RUN+=\"$INSTALLATION_DIR/VBoxCreateUSBNode.sh --remove \$major \$minor\""
225}
226
227## Generate our udev rule file. This takes a change in udev rule syntax in
228## version 55 into account. It only creates rules for USB for udev versions
229## recent enough to support USB device nodes.
230generate_udev_rule() {
231 VBOXDRV_GRP="$1" # The group owning the vboxdrv device
232 VBOXDRV_MODE="$2" # The access mode for the vboxdrv device
233 INSTALLATION_DIR="$3" # The directory VirtualBox is installed in
234 USB_GROUP="$4" # The group that has permission to access USB devices
235 NO_INSTALL="$5" # Set this to "1" to remove but not re-install rules
236
237 # Extra space!
238 case "$USB_GROUP" in ?*) USB_GROUP=" $USB_GROUP" ;; esac
239 case "$NO_INSTALL" in "1") return ;; esac
240 udev_write_vboxdrv "$VBOXDRV_GRP" "$VBOXDRV_MODE"
241 udev_write_usb "$INSTALLATION_DIR" "$USB_GROUP"
242}
243
244## Install udev rule (disable with INSTALL_NO_UDEV=1 in
245## /etc/default/virtualbox).
246install_udev() {
247 VBOXDRV_GRP="$1" # The group owning the vboxdrv device
248 VBOXDRV_MODE="$2" # The access mode for the vboxdrv device
249 INSTALLATION_DIR="$3" # The directory VirtualBox is installed in
250 USB_GROUP="$4" # The group that has permission to access USB devices
251 NO_INSTALL="$5" # Set this to "1" to remove but not re-install rules
252
253 if test -d /etc/udev/rules.d; then
254 generate_udev_rule "$VBOXDRV_GRP" "$VBOXDRV_MODE" "$INSTALLATION_DIR" \
255 "$USB_GROUP" "$NO_INSTALL"
256 fi
257 # Remove old udev description file
258 rm -f /etc/udev/rules.d/10-vboxdrv.rules 2> /dev/null
259}
260
261## Create a usb device node for a given sysfs path to a USB device.
262install_create_usb_node_for_sysfs() {
263 path="$1" # sysfs path for the device
264 usb_createnode="$2" # Path to the USB device node creation script
265 usb_group="$3" # The group to give ownership of the node to
266 if test -r "${path}/dev"; then
267 dev="`cat "${path}/dev" 2> /dev/null`"
268 major="`expr "$dev" : '\(.*\):' 2> /dev/null`"
269 minor="`expr "$dev" : '.*:\(.*\)' 2> /dev/null`"
270 class="`cat ${path}/bDeviceClass 2> /dev/null`"
271 sh "${usb_createnode}" "$major" "$minor" "$class" \
272 "${usb_group}" 2>/dev/null
273 fi
274}
275
276udev_rule_file=/etc/udev/rules.d/60-vboxdrv.rules
277sysfs_usb_devices="/sys/bus/usb/devices/*"
278
279## Install udev rules and create device nodes for usb access
280setup_usb() {
281 VBOXDRV_GRP="$1" # The group that should own /dev/vboxdrv
282 VBOXDRV_MODE="$2" # The mode to be used for /dev/vboxdrv
283 INSTALLATION_DIR="$3" # The directory VirtualBox is installed in
284 USB_GROUP="$4" # The group that should own the /dev/vboxusb device
285 # nodes unless INSTALL_NO_GROUP=1 in
286 # /etc/default/virtualbox. Optional.
287 usb_createnode="$INSTALLATION_DIR/VBoxCreateUSBNode.sh"
288 # install udev rule (disable with INSTALL_NO_UDEV=1 in
289 # /etc/default/virtualbox)
290 if [ "$INSTALL_NO_GROUP" != "1" ]; then
291 usb_group=$USB_GROUP
292 vboxdrv_group=$VBOXDRV_GRP
293 else
294 usb_group=root
295 vboxdrv_group=root
296 fi
297 install_udev "${vboxdrv_group}" "$VBOXDRV_MODE" \
298 "$INSTALLATION_DIR" "${usb_group}" \
299 "$INSTALL_NO_UDEV" > ${udev_rule_file}
300 # Build our device tree
301 for i in ${sysfs_usb_devices}; do # This line intentionally without quotes.
302 install_create_usb_node_for_sysfs "$i" "${usb_createnode}" \
303 "${usb_group}"
304 done
305}
306
307cleanup_usb()
308{
309 # Remove udev description file
310 rm -f /etc/udev/rules.d/60-vboxdrv.rules
311 rm -f /etc/udev/rules.d/10-vboxdrv.rules
312
313 # Remove our USB device tree
314 rm -rf /dev/vboxusb
315}
316
317# Returns path to module file as seen by modinfo(8) or empty string.
318module_path()
319{
320 mod="$1"
321 [ -n "$mod" ] || return
322
323 modinfo "$mod" 2>/dev/null | grep -e "^filename:" | tr -s ' ' | cut -d " " -f2
324}
325
326# Returns module version if module is available or empty string.
327module_version()
328{
329 mod="$1"
330 [ -n "$mod" ] || return
331
332 modinfo "$mod" 2>/dev/null | grep -e "^version:" | tr -s ' ' | cut -d " " -f2
333}
334
335# Returns module revision if module is available in the system or empty string.
336module_revision()
337{
338 mod="$1"
339 [ -n "$mod" ] || return
340
341 modinfo "$mod" 2>/dev/null | grep -e "^version:" | tr -s ' ' | cut -d " " -f3
342}
343
344# Reads kernel configuration option.
345kernel_get_config_opt()
346{
347 opt_name="$1"
348 [ -n "$opt_name" ] || return
349
350 # Check if there is a kernel tool which can extract config option.
351 if test -x /lib/modules/"$KERN_VER"/build/scripts/config; then
352 /lib/modules/"$KERN_VER"/build/scripts/config \
353 --file /lib/modules/"$KERN_VER"/build/.config \
354 --state "$opt_name" 2>/dev/null
355 elif test -f /lib/modules/"$KERN_VER"/build/.config; then
356 # Extract config option manually.
357 grep "$opt_name" /lib/modules/"$KERN_VER"/build/.config | sed -e "s/^$opt_name=//" -e "s/\"//g"
358 fi
359}
360
361# Reads CONFIG_MODULE_SIG_HASH from kernel config.
362kernel_module_sig_hash()
363{
364 kernel_get_config_opt "CONFIG_MODULE_SIG_HASH"
365}
366
367# Returns "1" if kernel module signature hash algorithm
368# is supported by us. Or empty string otherwise.
369module_sig_hash_supported()
370{
371 sig_hashalgo="$1"
372 [ -n "$sig_hashalgo" ] || return
373
374 # Go through supported list.
375 [ "$sig_hashalgo" = "sha1" \
376 -o "$sig_hashalgo" = "sha224" \
377 -o "$sig_hashalgo" = "sha256" \
378 -o "$sig_hashalgo" = "sha384" \
379 -o "$sig_hashalgo" = "sha512" ] || return
380
381 echo "1"
382}
383
384# Returns "1" if module is signed and signature can be verified
385# with public key provided in DEB_PUB_KEY. Or empty string otherwise.
386module_signed()
387{
388 mod="$1"
389 [ -n "$mod" ] || return
390
391 # Be nice with distributions which do not provide tools which we
392 # use in order to verify module signature. This variable needs to
393 # be explicitly set by administrator. This script will look for it
394 # in /etc/vbox/vbox.cfg. Make sure that you know what you do!
395 if [ "$VBOX_BYPASS_MODULES_SIGNATURE_CHECK" = "1" ]; then
396 echo "1"
397 return
398 fi
399
400 extraction_tool=/lib/modules/"$(uname -r)"/build/scripts/extract-module-sig.pl
401 mod_path=$(module_path "$mod" 2>/dev/null)
402 openssl_tool=$(which openssl 2>/dev/null)
403 # Do not use built-in printf!
404 printf_tool=$(which printf 2>/dev/null)
405
406 # Make sure all the tools required for signature validation are available.
407 [ -x "$extraction_tool" ] || return
408 [ -n "$mod_path" ] || return
409 [ -n "$openssl_tool" ] || return
410 [ -n "$printf_tool" ] || return
411
412 # Make sure openssl can handle hash algorithm.
413 sig_hashalgo=$(modinfo -F sig_hashalgo "$mod" 2>/dev/null)
414 [ "$(module_sig_hash_supported $sig_hashalgo)" = "1" ] || return
415
416 # Generate file names for temporary stuff.
417 mod_pub_key=$(mktemp -u)
418 mod_signature=$(mktemp -u)
419 mod_unsigned=$(mktemp -u)
420
421 # Convert public key in DER format into X509 certificate form.
422 "$openssl_tool" x509 -pubkey -inform DER -in "$DEB_PUB_KEY" -out "$mod_pub_key" 2>/dev/null
423 # Extract raw module signature and convert it into binary format.
424 "$printf_tool" \\x$(modinfo -F signature "$mod" | sed -z 's/[ \t\n]//g' | sed -e "s/:/\\\x/g") 2>/dev/null > "$mod_signature"
425 # Extract unsigned module for further digest calculation.
426 "$extraction_tool" -0 "$mod_path" 2>/dev/null > "$mod_unsigned"
427
428 # Verify signature.
429 rc=""
430 "$openssl_tool" dgst "-$sig_hashalgo" -binary -verify "$mod_pub_key" -signature "$mod_signature" "$mod_unsigned" 2>&1 >/dev/null && rc="1"
431 # Clean up.
432 rm -f $mod_pub_key $mod_signature $mod_unsigned
433
434 # Check result.
435 [ "$rc" = "1" ] || return
436
437 echo "1"
438}
439
440# Returns "1" if externally built module is available in the system and its
441# version and revision number do match to current VirtualBox installation.
442# Or empty string otherwise.
443module_available()
444{
445 mod="$1"
446 [ -n "$mod" ] || return
447
448 [ "$VBOX_VERSION" = "$(module_version "$mod")" ] || return
449 [ "$VBOX_REVISION" = "$(module_revision "$mod")" ] || return
450
451 # Check if module belongs to VirtualBox installation.
452 #
453 # We have a convention that only modules from /lib/modules/*/misc
454 # belong to us. Modules from other locations are treated as
455 # externally built.
456 mod_path="$(module_path "$mod")"
457
458 # If module path points to a symbolic link, resolve actual file location.
459 [ -L "$mod_path" ] && mod_path="$(readlink -e -- "$mod_path")"
460
461 # File exists?
462 [ -f "$mod_path" ] || return
463
464 # Extract last component of module path and check whether it is located
465 # outside of /lib/modules/*/misc.
466 mod_dir="$(dirname "$mod_path" | sed 's;^.*/;;')"
467 [ "$mod_dir" = "misc" ] || return
468
469 # In case if system is running in Secure Boot mode, check if module is signed.
470 if test -n "$HAVE_SEC_BOOT"; then
471 [ "$(module_signed "$mod")" = "1" ] || return
472 fi
473
474 echo "1"
475}
476
477# Check if required modules are installed in the system and versions match.
478setup_complete()
479{
480 [ "$(module_available vboxdrv)" = "1" ] || return
481 [ "$(module_available vboxnetflt)" = "1" ] || return
482 [ "$(module_available vboxnetadp)" = "1" ] || return
483
484 # All modules are in place.
485 echo "1"
486}
487
488start()
489{
490 begin_msg "Starting VirtualBox services" console
491 if [ -d /proc/xen ]; then
492 failure "Running VirtualBox in a Xen environment is not supported"
493 fi
494 if test -n "$HAVE_SEC_BOOT" && test -z "$DEB_KEY_ENROLLED"; then
495 if test -n "$HAVE_DEB_KEY"; then
496 begin_msg "You must re-start your system to finish Debian secure boot set-up." console
497 else
498 begin_msg "You must sign these kernel modules before using VirtualBox:
499 $MODULE_LIST
500See the documentation for your Linux distribution." console
501 fi
502 fi
503
504 if ! running vboxdrv; then
505
506 # Check if system already has matching modules installed.
507 [ "$(setup_complete)" = "1" ] || setup
508
509 if ! rm -f $DEVICE; then
510 failure "Cannot remove $DEVICE"
511 fi
512 if ! $MODPROBE vboxdrv > /dev/null 2>&1; then
513 failure "modprobe vboxdrv failed. Please use 'dmesg' to find out why"
514 fi
515 sleep .2
516 fi
517 # ensure the character special exists
518 if [ ! -c $DEVICE ]; then
519 MAJOR=`sed -n 's;\([0-9]\+\) vboxdrv$;\1;p' /proc/devices`
520 if [ ! -z "$MAJOR" ]; then
521 MINOR=0
522 else
523 MINOR=`sed -n 's;\([0-9]\+\) vboxdrv$;\1;p' /proc/misc`
524 if [ ! -z "$MINOR" ]; then
525 MAJOR=10
526 fi
527 fi
528 if [ -z "$MAJOR" ]; then
529 rmmod vboxdrv 2>/dev/null
530 failure "Cannot locate the VirtualBox device"
531 fi
532 if ! mknod -m 0660 $DEVICE c $MAJOR $MINOR 2>/dev/null; then
533 rmmod vboxdrv 2>/dev/null
534 failure "Cannot create device $DEVICE with major $MAJOR and minor $MINOR"
535 fi
536 fi
537 # ensure permissions
538 if ! chown :"${GROUP}" $DEVICE 2>/dev/null; then
539 rmmod vboxpci 2>/dev/null
540 rmmod vboxnetadp 2>/dev/null
541 rmmod vboxnetflt 2>/dev/null
542 rmmod vboxdrv 2>/dev/null
543 failure "Cannot change group ${GROUP} for device $DEVICE"
544 fi
545 if ! $MODPROBE vboxnetflt > /dev/null 2>&1; then
546 failure "modprobe vboxnetflt failed. Please use 'dmesg' to find out why"
547 fi
548 if ! $MODPROBE vboxnetadp > /dev/null 2>&1; then
549 failure "modprobe vboxnetadp failed. Please use 'dmesg' to find out why"
550 fi
551 if test -e "${MODULE_SRC}/vboxpci" && ! $MODPROBE vboxpci > /dev/null 2>&1; then
552 failure "modprobe vboxpci failed. Please use 'dmesg' to find out why"
553 fi
554 # Create the /dev/vboxusb directory if the host supports that method
555 # of USB access. The USB code checks for the existance of that path.
556 if grep -q usb_device /proc/devices; then
557 mkdir -p -m 0750 /dev/vboxusb 2>/dev/null
558 chown root:vboxusers /dev/vboxusb 2>/dev/null
559 fi
560 # Remove any kernel modules left over from previously installed kernels.
561 cleanup only_old
562 succ_msg "VirtualBox services started"
563}
564
565stop()
566{
567 begin_msg "Stopping VirtualBox services" console
568
569 if running vboxpci; then
570 if ! rmmod vboxpci 2>/dev/null; then
571 failure "Cannot unload module vboxpci"
572 fi
573 fi
574 if running vboxnetadp; then
575 if ! rmmod vboxnetadp 2>/dev/null; then
576 failure "Cannot unload module vboxnetadp"
577 fi
578 fi
579 if running vboxdrv; then
580 if running vboxnetflt; then
581 if ! rmmod vboxnetflt 2>/dev/null; then
582 failure "Cannot unload module vboxnetflt"
583 fi
584 fi
585 if ! rmmod vboxdrv 2>/dev/null; then
586 failure "Cannot unload module vboxdrv"
587 fi
588 if ! rm -f $DEVICE; then
589 failure "Cannot unlink $DEVICE"
590 fi
591 fi
592 succ_msg "VirtualBox services stopped"
593}
594
595# enter the following variables in /etc/default/virtualbox:
596# SHUTDOWN_USERS="foo bar"
597# check for running VMs of user foo and user bar
598# SHUTDOWN=poweroff
599# SHUTDOWN=acpibutton
600# SHUTDOWN=savestate
601# select one of these shutdown methods for running VMs
602stop_vms()
603{
604 wait=0
605 for i in $SHUTDOWN_USERS; do
606 # don't create the ipcd directory with wrong permissions!
607 if [ -d /tmp/.vbox-$i-ipc ]; then
608 export VBOX_IPC_SOCKETID="$i"
609 VMS=`$VBOXMANAGE --nologo list runningvms | sed -e 's/^".*".*{\(.*\)}/\1/' 2>/dev/null`
610 if [ -n "$VMS" ]; then
611 if [ "$SHUTDOWN" = "poweroff" ]; then
612 begin_msg "Powering off remaining VMs"
613 for v in $VMS; do
614 $VBOXMANAGE --nologo controlvm $v poweroff
615 done
616 succ_msg "Remaining VMs powered off"
617 elif [ "$SHUTDOWN" = "acpibutton" ]; then
618 begin_msg "Sending ACPI power button event to remaining VMs"
619 for v in $VMS; do
620 $VBOXMANAGE --nologo controlvm $v acpipowerbutton
621 wait=30
622 done
623 succ_msg "ACPI power button event sent to remaining VMs"
624 elif [ "$SHUTDOWN" = "savestate" ]; then
625 begin_msg "Saving state of remaining VMs"
626 for v in $VMS; do
627 $VBOXMANAGE --nologo controlvm $v savestate
628 done
629 succ_msg "State of remaining VMs saved"
630 fi
631 fi
632 fi
633 done
634 # wait for some seconds when doing ACPI shutdown
635 if [ "$wait" -ne 0 ]; then
636 begin_msg "Waiting for $wait seconds for VM shutdown"
637 sleep $wait
638 succ_msg "Waited for $wait seconds for VM shutdown"
639 fi
640}
641
642cleanup()
643{
644 # If this is set, only remove kernel modules for no longer installed
645 # kernels. Note that only generated kernel modules should be placed
646 # in /lib/modules/*/misc. Anything that we should not remove automatically
647 # should go elsewhere.
648 only_old="${1}"
649 for i in /lib/modules/*; do
650 # Check whether we are only cleaning up for uninstalled kernels.
651 test -n "${only_old}" && test -e "${i}/kernel/drivers" && continue
652
653 unset do_update
654 for j in $MODULE_LIST; do
655 for mod_ext in ko ko.gz ko.xz ko.zst; do
656 test -f "${i}/misc/${j}.${mod_ext}" && do_update=1 && rm -f "${i}/misc/${j}.${mod_ext}"
657 done
658 done
659
660 # Trigger depmod(8) only in case if directory content was modified
661 # and save a bit of run time.
662 test -n "$do_update" && depmod -a "$(basename "$i")" && sync
663
664 # Remove the kernel version folder if it was empty except for us.
665 test "`echo ${i}/misc/* ${i}/misc/.?* ${i}/* ${i}/.?*`" \
666 = "${i}/misc/* ${i}/misc/.. ${i}/misc ${i}/.." &&
667 rmdir "${i}/misc" "${i}" # We used to leave empty folders.
668 done
669}
670
671# setup_script
672setup()
673{
674 begin_msg "Building VirtualBox kernel modules" console
675 log "Building the main VirtualBox module."
676
677 # Detect if kernel was built with clang.
678 unset LLVM
679 vbox_cc_is_clang=$(kernel_get_config_opt "CONFIG_CC_IS_CLANG")
680 if test "${vbox_cc_is_clang}" = "y"; then
681 log "Using clang compiler."
682 export LLVM=1
683 fi
684
685 if ! myerr=`$BUILDINTMP \
686 --save-module-symvers /tmp/vboxdrv-Module.symvers \
687 --module-source "$MODULE_SRC/vboxdrv" \
688 --no-print-directory install 2>&1`; then
689 "${INSTALL_DIR}/check_module_dependencies.sh" || exit 1
690 log "Error building the module:"
691 module_build_log "$myerr"
692 failure "Look at $LOG to find out what went wrong"
693 fi
694 log "Building the net filter module."
695 if ! myerr=`$BUILDINTMP \
696 --use-module-symvers /tmp/vboxdrv-Module.symvers \
697 --module-source "$MODULE_SRC/vboxnetflt" \
698 --no-print-directory install 2>&1`; then
699 log "Error building the module:"
700 module_build_log "$myerr"
701 failure "Look at $LOG to find out what went wrong"
702 fi
703 log "Building the net adaptor module."
704 if ! myerr=`$BUILDINTMP \
705 --use-module-symvers /tmp/vboxdrv-Module.symvers \
706 --module-source "$MODULE_SRC/vboxnetadp" \
707 --no-print-directory install 2>&1`; then
708 log "Error building the module:"
709 module_build_log "$myerr"
710 failure "Look at $LOG to find out what went wrong"
711 fi
712 if test -e "$MODULE_SRC/vboxpci"; then
713 log "Building the PCI pass-through module."
714 if ! myerr=`$BUILDINTMP \
715 --use-module-symvers /tmp/vboxdrv-Module.symvers \
716 --module-source "$MODULE_SRC/vboxpci" \
717 --no-print-directory install 2>&1`; then
718 log "Error building the module:"
719 module_build_log "$myerr"
720 failure "Look at $LOG to find out what went wrong"
721 fi
722 fi
723 rm -f /etc/vbox/module_not_compiled
724 depmod -a
725 sync
726 succ_msg "VirtualBox kernel modules built"
727
728 # Secure boot on Ubuntu, Debian and Oracle Linux.
729 if test -n "$HAVE_SEC_BOOT"; then
730 begin_msg "Signing VirtualBox kernel modules" console
731
732 # Generate new signing key if needed.
733 [ -n "$HAVE_UPDATE_SECUREBOOT_POLICY_TOOL" ] && SHIM_NOTRIGGER=y update-secureboot-policy --new-key
734
735 # Check if signing keys are in place.
736 if test ! -f "$DEB_PUB_KEY" || ! test -f "$DEB_PRIV_KEY"; then
737 # update-secureboot-policy tool present in the system, but keys were not generated.
738 [ -n "$HAVE_UPDATE_SECUREBOOT_POLICY_TOOL" ] && fail_msg "
739
740update-secureboot-policy tool does not generate signing keys
741in your distribution, see below on how to generate them manually
742"
743
744 # update-secureboot-policy not present in the system, recommend generate keys manually.
745 failure "
746
747System is running in Secure Boot mode, however your distribution
748does not provide tools for automatic generation of keys needed for
749modules signing. Please consider to generate and enroll them manually:
750
751 sudo mkdir -p /var/lib/shim-signed/mok
752 sudo openssl req -nodes -new -x509 -newkey rsa:2048 -outform DER -addext \"extendedKeyUsage=codeSigning\" -keyout $DEB_PRIV_KEY -out $DEB_PUB_KEY
753 sudo mokutil --import $DEB_PUB_KEY
754 sudo reboot
755
756Restart \"rcvboxdrv setup\" after system is rebooted
757"
758 fi
759
760 # Check if signing tool is available.
761 [ -n "$SIGN_TOOL" ] || failure "Unable to find signing tool"
762
763 # Get kernel signature hash algorithm from kernel config and validate it.
764 sig_hashalgo=$(kernel_module_sig_hash)
765 [ "$(module_sig_hash_supported $sig_hashalgo)" = "1" ] \
766 || failure "Unsupported kernel signature hash algorithm $sig_hashalgo"
767
768 # Sign modules.
769 for i in $MODULE_LIST; do
770 "$SIGN_TOOL" "$sig_hashalgo" "$DEB_PRIV_KEY" "$DEB_PUB_KEY" \
771 /lib/modules/"$KERN_VER"/misc/"$i".ko 2>/dev/null || failure "Unable to sign $i.ko"
772 done
773
774 # Enroll signing key if needed.
775 if test -n "$HAVE_UPDATE_SECUREBOOT_POLICY_TOOL"; then
776 # update-secureboot-policy "expects" DKMS modules.
777 # Work around this and talk to the authors as soon
778 # as possible to fix it.
779 mkdir -p /var/lib/dkms/vbox-temp
780 update-secureboot-policy --enroll-key 2>/dev/null ||
781 begin_msg "Failed to enroll secure boot key." console
782 rmdir -p /var/lib/dkms/vbox-temp 2>/dev/null
783
784 # Indicate that key has been enrolled and reboot is needed.
785 HAVE_DEB_KEY=true
786 fi
787 succ_msg "Signing completed"
788 fi
789}
790
791dmnstatus()
792{
793 if running vboxdrv; then
794 str="vboxdrv"
795 if running vboxnetflt; then
796 str="$str, vboxnetflt"
797 if running vboxnetadp; then
798 str="$str, vboxnetadp"
799 fi
800 fi
801 if running vboxpci; then
802 str="$str, vboxpci"
803 fi
804 echo "VirtualBox kernel modules ($str) are loaded."
805 for i in $SHUTDOWN_USERS; do
806 # don't create the ipcd directory with wrong permissions!
807 if [ -d /tmp/.vbox-$i-ipc ]; then
808 export VBOX_IPC_SOCKETID="$i"
809 VMS=`$VBOXMANAGE --nologo list runningvms | sed -e 's/^".*".*{\(.*\)}/\1/' 2>/dev/null`
810 if [ -n "$VMS" ]; then
811 echo "The following VMs are currently running:"
812 for v in $VMS; do
813 echo " $v"
814 done
815 fi
816 fi
817 done
818 else
819 echo "VirtualBox kernel module is not loaded."
820 fi
821}
822
823case "$1" in
824start)
825 start
826 ;;
827stop)
828 stop_vms
829 stop
830 ;;
831stop_vms)
832 stop_vms
833 ;;
834restart)
835 stop && start
836 ;;
837setup)
838 test -n "${2}" && export KERN_VER="${2}"
839 # Create udev rule and USB device nodes.
840 ## todo Wouldn't it make more sense to install the rule to /lib/udev? This
841 ## is not a user-created configuration file after all.
842 ## todo Do we need a udev rule to create /dev/vboxdrv[u] at all? We have
843 ## working fall-back code here anyway, and the "right" code is more complex
844 ## than the fall-back. Unnecessary duplication?
845 stop && cleanup
846 setup_usb "$GROUP" "$DEVICE_MODE" "$INSTALL_DIR"
847 start
848 ;;
849cleanup)
850 stop && cleanup
851 cleanup_usb
852 ;;
853force-reload)
854 stop
855 start
856 ;;
857status)
858 dmnstatus
859 ;;
860*)
861 echo "Usage: $0 {start|stop|stop_vms|restart|setup|cleanup|force-reload|status}"
862 exit 1
863esac
864
865exit 0
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette