VirtualBox

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

Last change on this file since 109051 was 109051, checked in by vboxsync, 3 weeks ago

Linux: Adjust startup scripts for building kernel modules for UEK8 on OL9 distribution, bugdbref:37834896.

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

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