VirtualBox

source: vbox/trunk/src/VBox/Additions/linux/installer/vboxadd.sh@ 98626

Last change on this file since 98626 was 98609, checked in by vboxsync, 2 years ago

Additions: Linux: rcvboxadd: Introduce "status-kernel" and "status-user" actions, bugref:10359.

"rcvboxadd status-kernel" is intended to verify if Guest Additions kernel modules are currently
loaded and running versions do match to Guest Additions installation version.

"rcvboxadd status-user" is intended to verify if user-space processes are currently running. At
the moment only checks if VBoxService is running, can be extended later on.

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 37.4 KB
Line 
1#! /bin/sh
2# $Id: vboxadd.sh 98609 2023-02-16 16:33:36Z vboxsync $
3## @file
4# Linux Additions kernel module init script ($Revision: 98609 $)
5#
6
7#
8# Copyright (C) 2006-2023 Oracle and/or its affiliates.
9#
10# This file is part of VirtualBox base platform packages, as
11# available from https://www.virtualbox.org.
12#
13# This program is free software; you can redistribute it and/or
14# modify it under the terms of the GNU General Public License
15# as published by the Free Software Foundation, in version 3 of the
16# License.
17#
18# This program is distributed in the hope that it will be useful, but
19# WITHOUT ANY WARRANTY; without even the implied warranty of
20# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21# General Public License for more details.
22#
23# You should have received a copy of the GNU General Public License
24# along with this program; if not, see <https://www.gnu.org/licenses>.
25#
26# SPDX-License-Identifier: GPL-3.0-only
27#
28
29# X-Start-Before is a Debian Addition which we use when converting to
30# a systemd unit. X-Service-Type is our own invention, also for systemd.
31
32# chkconfig: 345 10 90
33# description: VirtualBox Linux Additions kernel modules
34#
35### BEGIN INIT INFO
36# Provides: vboxadd
37# Required-Start:
38# Required-Stop:
39# Default-Start: 2 3 4 5
40# Default-Stop: 0 1 6
41# X-Start-Before: display-manager
42# X-Service-Type: oneshot
43# Description: VirtualBox Linux Additions kernel modules
44### END INIT INFO
45
46## @todo This file duplicates a lot of script with vboxdrv.sh. When making
47# changes please try to reduce differences between the two wherever possible.
48
49# Testing:
50# * Should fail if the configuration file is missing or missing INSTALL_DIR or
51# INSTALL_VER entries.
52# * vboxadd, vboxsf and vboxdrmipc user groups should be created if they do not exist - test
53# by removing them before installing.
54# * Shared folders can be mounted and auto-mounts accessible to vboxsf group,
55# including on recent Fedoras with SELinux.
56# * Setting INSTALL_NO_MODULE_BUILDS inhibits modules and module automatic
57# rebuild script creation; otherwise modules, user, group, rebuild script,
58# udev rule and shared folder mount helper should be created/set up.
59# * Setting INSTALL_NO_MODULE_BUILDS inhibits module load and unload on start
60# and stop.
61# * Uninstalling the Additions and re-installing them does not trigger warnings.
62
63export LC_ALL=C
64PATH=$PATH:/bin:/sbin:/usr/sbin
65PACKAGE=VBoxGuestAdditions
66MODPROBE=/sbin/modprobe
67OLDMODULES="vboxguest vboxadd vboxsf vboxvfs vboxvideo"
68SERVICE="VirtualBox Guest Additions"
69## systemd logs information about service status, otherwise do that ourselves.
70QUIET=
71test -z "${TARGET_VER}" && TARGET_VER=`uname -r`
72
73export VBOX_KBUILD_TYPE
74export USERNAME
75
76setup_log()
77{
78 test -z "${LOG}" || return 0
79 # Rotate log files
80 LOG="/var/log/vboxadd-setup.log"
81 mv "${LOG}.3" "${LOG}.4" 2>/dev/null
82 mv "${LOG}.2" "${LOG}.3" 2>/dev/null
83 mv "${LOG}.1" "${LOG}.2" 2>/dev/null
84 mv "${LOG}" "${LOG}.1" 2>/dev/null
85}
86
87if $MODPROBE -c 2>/dev/null | grep -q '^allow_unsupported_modules *0'; then
88 MODPROBE="$MODPROBE --allow-unsupported-modules"
89fi
90
91# Preamble for Gentoo
92if [ "`which $0`" = "/sbin/rc" ]; then
93 shift
94fi
95
96begin()
97{
98 test -n "${QUIET}" || echo "${SERVICE}: ${1}"
99}
100
101info()
102{
103 if test -z "${QUIET}"; then
104 echo "${SERVICE}: $1" | fold -s
105 else
106 echo "$1" | fold -s
107 fi
108}
109
110fail()
111{
112 log "${1}"
113 echo "$1" >&2
114 echo "The log file $LOG may contain further information." >&2
115 exit 1
116}
117
118log()
119{
120 setup_log
121 echo "${1}" >> "${LOG}"
122}
123
124module_build_log()
125{
126 log "Error building the module. Build output follows."
127 echo ""
128 echo "${1}" >> "${LOG}"
129}
130
131dev=/dev/vboxguest
132userdev=/dev/vboxuser
133config=/var/lib/VBoxGuestAdditions/config
134user_config=/etc/virtualbox-guest-additions.conf
135owner=vboxadd
136group=1
137
138# Include custom user configuration file.
139[ -r "$user_config" ] && . "$user_config"
140
141if test -r $config; then
142 . $config
143else
144 fail "Configuration file $config not found"
145fi
146test -n "$INSTALL_DIR" -a -n "$INSTALL_VER" ||
147 fail "Configuration file $config not complete"
148MODULE_SRC="$INSTALL_DIR/src/vboxguest-$INSTALL_VER"
149BUILDINTMP="$MODULE_SRC/build_in_tmp"
150
151# Attempt to detect VirtualBox Guest Additions version and revision information.
152VBOXCLIENT="${INSTALL_DIR}/bin/VBoxClient"
153VBOX_VERSION="`"$VBOXCLIENT" --version | cut -d r -f1`"
154[ -n "$VBOX_VERSION" ] || VBOX_VERSION='unknown'
155VBOX_REVISION="r`"$VBOXCLIENT" --version | cut -d r -f2`"
156[ "$VBOX_REVISION" != "r" ] || VBOX_REVISION='unknown'
157
158running_vboxguest()
159{
160 lsmod | grep -q "vboxguest[^_-]"
161}
162
163running_vboxadd()
164{
165 lsmod | grep -q "vboxadd[^_-]"
166}
167
168running_vboxsf()
169{
170 lsmod | grep -q "vboxsf[^_-]"
171}
172
173running_vboxvideo()
174{
175 lsmod | grep -q "vboxvideo[^_-]"
176}
177
178running_module()
179{
180 lsmod | grep -q $1
181}
182
183# Get version string of currently running kernel module.
184running_module_version()
185{
186 mod=$1
187 version_string_path="/sys/module/"$mod"/version"
188
189 [ -n "$mod" ] || return
190 [ -r "$version_string_path" ] || return
191
192 cat "$version_string_path"
193}
194
195# Check if currently loaded kernel module version matches to
196# current Guest Additions installed version and revision.
197check_running_module_version()
198{
199 mod=$1
200 expected="$VBOX_VERSION $VBOX_REVISION"
201
202 [ -n "$mod" ] || return
203 [ -n "$expected" ] || return
204
205 [ "$expected" = "$(running_module_version "$mod")" ] || return
206}
207
208# A wrapper for check_running_module_version.
209# Go through the list of Guest Additions' modules and
210# verify if they are loaded and running version matches
211# to current installation version. Skip vboxvideo since
212# it is not loaded for old guests.
213check_status_kernel()
214{
215 for mod in vboxguest vboxsf; do
216 running_module "$mod" || fail "module $mod not loaded"
217 check_running_module_version "$mod" || fail "currently loaded module $mod version ($(running_module_version "$mod")) does not match to VirtualBox Guest Additions installation version ($VBOX_VERSION $VBOX_REVISION)"
218 done
219}
220
221# Checks if systemctl is present and functional (i.e., systemd is the init process).
222use_systemd()
223{
224 systemctl status >/dev/null 2>&1
225}
226
227## Did we install a systemd service?
228systemd_service_installed()
229{
230 ## Name of service to test.
231 name="${1}"
232
233 test -f /lib/systemd/system/"${name}".service ||
234 test -f /usr/lib/systemd/system/"${name}".service
235}
236
237## Perform an action on a service
238do_sysvinit_action()
239{
240 ## Name of service to start.
241 name="${1}"
242 ## The action to perform, normally "start", "stop" or "status".
243 action="${2}"
244
245 if use_systemd -a systemd_service_installed "${name}"; then
246 systemctl -q ${action} "${name}"
247 elif test -x "/etc/rc.d/init.d/${name}"; then
248 "/etc/rc.d/init.d/${name}" "${action}" quiet
249 elif test -x "/etc/init.d/${name}"; then
250 "/etc/init.d/${name}" "${action}" quiet
251 fi
252}
253
254# Check whether user-land processes are running.
255# Currently only check for VBoxService.
256check_status_user()
257{
258 do_sysvinit_action vboxadd-service status >/dev/null 2>&1
259}
260
261do_vboxguest_non_udev()
262{
263 if [ ! -c $dev ]; then
264 maj=`sed -n 's;\([0-9]\+\) vboxguest;\1;p' /proc/devices`
265 if [ ! -z "$maj" ]; then
266 min=0
267 else
268 min=`sed -n 's;\([0-9]\+\) vboxguest;\1;p' /proc/misc`
269 if [ ! -z "$min" ]; then
270 maj=10
271 fi
272 fi
273 test -n "$maj" || {
274 rmmod vboxguest 2>/dev/null
275 fail "Cannot locate the VirtualBox device"
276 }
277
278 mknod -m 0664 $dev c $maj $min || {
279 rmmod vboxguest 2>/dev/null
280 fail "Cannot create device $dev with major $maj and minor $min"
281 }
282 fi
283 chown $owner:$group $dev 2>/dev/null || {
284 rm -f $dev 2>/dev/null
285 rm -f $userdev 2>/dev/null
286 rmmod vboxguest 2>/dev/null
287 fail "Cannot change owner $owner:$group for device $dev"
288 }
289
290 if [ ! -c $userdev ]; then
291 maj=10
292 min=`sed -n 's;\([0-9]\+\) vboxuser;\1;p' /proc/misc`
293 if [ ! -z "$min" ]; then
294 mknod -m 0666 $userdev c $maj $min || {
295 rm -f $dev 2>/dev/null
296 rmmod vboxguest 2>/dev/null
297 fail "Cannot create device $userdev with major $maj and minor $min"
298 }
299 chown $owner:$group $userdev 2>/dev/null || {
300 rm -f $dev 2>/dev/null
301 rm -f $userdev 2>/dev/null
302 rmmod vboxguest 2>/dev/null
303 fail "Cannot change owner $owner:$group for device $userdev"
304 }
305 fi
306 fi
307}
308
309restart()
310{
311 stop && start
312 return 0
313}
314
315## Update the initramfs. Debian and Ubuntu put the graphics driver in, and
316# need the touch(1) command below. Everyone else that I checked just need
317# the right module alias file from depmod(1) and only use the initramfs to
318# load the root filesystem, not the boot splash. update-initramfs works
319# for the first two and dracut for every one else I checked. We are only
320# interested in distributions recent enough to use the KMS vboxvideo driver.
321update_initramfs()
322{
323 ## kernel version to update for.
324 version="${1}"
325 depmod "${version}"
326 rm -f "/lib/modules/${version}/initrd/vboxvideo"
327 test ! -d "/lib/modules/${version}/initrd" ||
328 test ! -f "/lib/modules/${version}/misc/vboxvideo.ko" ||
329 touch "/lib/modules/${version}/initrd/vboxvideo"
330
331 # Systems without systemd-inhibit probably don't need their initramfs
332 # rebuild here anyway.
333 type systemd-inhibit >/dev/null 2>&1 || return
334 if type dracut >/dev/null 2>&1; then
335 systemd-inhibit --why="Installing VirtualBox Guest Additions" \
336 dracut -f --kver "${version}"
337 elif type update-initramfs >/dev/null 2>&1; then
338 systemd-inhibit --why="Installing VirtualBox Guest Additions" \
339 update-initramfs -u -k "${version}"
340 fi
341}
342
343# Remove any existing VirtualBox guest kernel modules from the disk, but not
344# from the kernel as they may still be in use
345cleanup_modules()
346{
347 # Needed for Ubuntu and Debian, see update_initramfs
348 rm -f /lib/modules/*/initrd/vboxvideo
349 for i in /lib/modules/*/misc; do
350 KERN_VER="${i%/misc}"
351 KERN_VER="${KERN_VER#/lib/modules/}"
352 unset do_update
353 for j in ${OLDMODULES}; do
354 for mod_ext in ko ko.gz ko.xz ko.zst; do
355 test -f "${i}/${j}.${mod_ext}" && do_update=1 && rm -f "${i}/${j}.${mod_ext}"
356 done
357 done
358 test -z "$do_update" || update_initramfs "$KERN_VER"
359 # Remove empty /lib/modules folders which may have been kept around
360 rmdir -p "${i}" 2>/dev/null || true
361 unset keep
362 for j in /lib/modules/"${KERN_VER}"/*; do
363 name="${j##*/}"
364 test -d "${name}" || test "${name%%.*}" != modules && keep=1
365 done
366 if test -z "${keep}"; then
367 rm -rf /lib/modules/"${KERN_VER}"
368 rm -f /boot/initrd.img-"${KERN_VER}"
369 fi
370 done
371 for i in ${OLDMODULES}; do
372 # We no longer support DKMS, remove any leftovers.
373 rm -rf "/var/lib/dkms/${i}"*
374 done
375 rm -f /etc/depmod.d/vboxvideo-upstream.conf
376}
377
378# Secure boot state.
379case "`mokutil --sb-state 2>/dev/null`" in
380 *"disabled in shim"*) unset HAVE_SEC_BOOT;;
381 *"SecureBoot enabled"*) HAVE_SEC_BOOT=true;;
382 *) unset HAVE_SEC_BOOT;;
383esac
384# So far we can only sign modules on Ubuntu and on Debian 10 and later.
385DEB_PUB_KEY=/var/lib/shim-signed/mok/MOK.der
386DEB_PRIV_KEY=/var/lib/shim-signed/mok/MOK.priv
387# Check if key already enrolled.
388unset HAVE_DEB_KEY
389case "`mokutil --test-key "$DEB_PUB_KEY" 2>/dev/null`" in
390 *"is already"*) DEB_KEY_ENROLLED=true;;
391 *) unset DEB_KEY_ENROLLED;;
392esac
393
394# Check if update-secureboot-policy tool supports required commandline options.
395update_secureboot_policy_supports()
396{
397 opt_name="$1"
398 [ -n "$opt_name" ] || return
399
400 [ -z "$(update-secureboot-policy --help 2>&1 | grep "$opt_name")" ] && return
401 echo "1"
402}
403
404HAVE_UPDATE_SECUREBOOT_POLICY_TOOL=
405if type update-secureboot-policy >/dev/null 2>&1; then
406 [ "$(update_secureboot_policy_supports new-key)" = "1" -a "$(update_secureboot_policy_supports enroll-key)" = "1" ] && \
407 HAVE_UPDATE_SECUREBOOT_POLICY_TOOL=true
408fi
409
410# Reads kernel configuration option.
411kernel_get_config_opt()
412{
413 opt_name="$1"
414 [ -n "$opt_name" ] || return
415
416 # Check if there is a kernel tool which can extract config option.
417 if test -x /lib/modules/"$KERN_VER"/build/scripts/config; then
418 /lib/modules/"$KERN_VER"/build/scripts/config \
419 --file /lib/modules/"$KERN_VER"/build/.config \
420 --state "$opt_name" 2>/dev/null
421 elif test -f /lib/modules/"$KERN_VER"/build/.config; then
422 # Extract config option manually.
423 grep "$opt_name" /lib/modules/"$KERN_VER"/build/.config | sed -e "s/^$opt_name=//" -e "s/\"//g"
424 fi
425}
426
427# Reads CONFIG_MODULE_SIG_HASH from kernel config.
428kernel_module_sig_hash()
429{
430 kernel_get_config_opt "CONFIG_MODULE_SIG_HASH"
431}
432
433# Returns "1" if kernel module signature hash algorithm
434# is supported by us. Or empty string otherwise.
435module_sig_hash_supported()
436{
437 sig_hashalgo="$1"
438 [ -n "$sig_hashalgo" ] || return
439
440 # Go through supported list.
441 [ "$sig_hashalgo" = "sha1" \
442 -o "$sig_hashalgo" = "sha224" \
443 -o "$sig_hashalgo" = "sha256" \
444 -o "$sig_hashalgo" = "sha384" \
445 -o "$sig_hashalgo" = "sha512" ] || return
446
447 echo "1"
448}
449
450sign_modules()
451{
452 KERN_VER="$1"
453 test -n "$KERN_VER" || return 1
454
455 # Make list of mudules to sign.
456 MODULE_LIST="vboxguest vboxsf"
457 # vboxvideo might not present on for older kernels.
458 [ -f "/lib/modules/"$KERN_VER"/misc/vboxvideo.ko" ] && MODULE_LIST="$MODULE_LIST vboxvideo"
459
460 # Secure boot on Ubuntu, Debian and Oracle Linux.
461 if test -n "$HAVE_SEC_BOOT"; then
462 begin "Signing VirtualBox Guest Additions kernel modules"
463
464 # Generate new signing key if needed.
465 [ -n "$HAVE_UPDATE_SECUREBOOT_POLICY_TOOL" ] && SHIM_NOTRIGGER=y update-secureboot-policy --new-key
466
467 # Check if signing keys are in place.
468 if test ! -f "$DEB_PUB_KEY" || ! test -f "$DEB_PRIV_KEY"; then
469 # update-secureboot-policy tool present in the system, but keys were not generated.
470 [ -n "$HAVE_UPDATE_SECUREBOOT_POLICY_TOOL" ] && info "
471
472update-secureboot-policy tool does not generate signing keys
473in your distribution, see below on how to generate them manually."
474 # update-secureboot-policy not present in the system, recommend generate keys manually.
475 fail "
476
477System is running in Secure Boot mode, however your distribution
478does not provide tools for automatic generation of keys needed for
479modules signing. Please consider to generate and enroll them manually:
480
481 sudo mkdir -p /var/lib/shim-signed/mok
482 sudo openssl req -nodes -new -x509 -newkey rsa:2048 -outform DER -addext \"extendedKeyUsage=codeSigning\" -keyout $DEB_PRIV_KEY -out $DEB_PUB_KEY
483 sudo mokutil --import $DEB_PUB_KEY
484 sudo reboot
485
486Restart \"rcvboxadd setup\" after system is rebooted.
487"
488 fi
489
490 # Get kernel signature hash algorithm from kernel config and validate it.
491 sig_hashalgo=$(kernel_module_sig_hash)
492 [ "$(module_sig_hash_supported $sig_hashalgo)" = "1" ] \
493 || fail "Unsupported kernel signature hash algorithm $sig_hashalgo"
494
495 # Sign modules.
496 for i in $MODULE_LIST; do
497
498 # Try to find a tool for modules signing.
499 SIGN_TOOL=$(which kmodsign 2>/dev/null)
500 # Attempt to use in-kernel signing tool if kmodsign not found.
501 if test -z "$SIGN_TOOL"; then
502 if test -x "/lib/modules/$KERN_VER/build/scripts/sign-file"; then
503 SIGN_TOOL="/lib/modules/$KERN_VER/build/scripts/sign-file"
504 fi
505 fi
506
507 # Check if signing tool is available.
508 [ -n "$SIGN_TOOL" ] || fail "Unable to find signing tool"
509
510 "$SIGN_TOOL" "$sig_hashalgo" "$DEB_PRIV_KEY" "$DEB_PUB_KEY" \
511 /lib/modules/"$KERN_VER"/misc/"$i".ko || fail "Unable to sign $i.ko"
512 done
513 # Enroll signing key if needed.
514 if test -n "$HAVE_UPDATE_SECUREBOOT_POLICY_TOOL"; then
515 # update-secureboot-policy "expects" DKMS modules.
516 # Work around this and talk to the authors as soon
517 # as possible to fix it.
518 mkdir -p /var/lib/dkms/vbox-temp
519 update-secureboot-policy --enroll-key 2>/dev/null ||
520 fail "Failed to enroll secure boot key."
521 rmdir -p /var/lib/dkms/vbox-temp 2>/dev/null
522
523 # Indicate that key has been enrolled and reboot is needed.
524 HAVE_DEB_KEY=true
525 fi
526 fi
527}
528
529# Build and install the VirtualBox guest kernel modules
530setup_modules()
531{
532 KERN_VER="$1"
533 test -n "$KERN_VER" || return 1
534 # Match (at least): vboxguest.o; vboxguest.ko; vboxguest.ko.xz
535 set /lib/modules/"$KERN_VER"/misc/vboxguest.*o*
536 #test ! -f "$1" || return 0
537 test -d /lib/modules/"$KERN_VER"/build || return 0
538 export KERN_VER
539 info "Building the modules for kernel $KERN_VER."
540
541 # Prepend PATH for building UEK7 on OL8 distribution.
542 case "$KERN_VER" in
543 5.15.0-*.el8uek*) PATH="/opt/rh/gcc-toolset-11/root/usr/bin:$PATH";;
544 esac
545
546 # Detect if kernel was built with clang.
547 unset LLVM
548 vbox_cc_is_clang=$(kernel_get_config_opt "CONFIG_CC_IS_CLANG")
549 if test "${vbox_cc_is_clang}" = "y"; then
550 info "Using clang compiler."
551 export LLVM=1
552 fi
553
554 log "Building the main Guest Additions $INSTALL_VER module for kernel $KERN_VER."
555 if ! myerr=`$BUILDINTMP \
556 --save-module-symvers /tmp/vboxguest-Module.symvers \
557 --module-source $MODULE_SRC/vboxguest \
558 --no-print-directory install 2>&1`; then
559 # If check_module_dependencies.sh fails it prints a message itself.
560 module_build_log "$myerr"
561 "${INSTALL_DIR}"/other/check_module_dependencies.sh 2>&1 &&
562 info "Look at $LOG to find out what went wrong"
563 return 0
564 fi
565 log "Building the shared folder support module."
566 if ! myerr=`$BUILDINTMP \
567 --use-module-symvers /tmp/vboxguest-Module.symvers \
568 --module-source $MODULE_SRC/vboxsf \
569 --no-print-directory install 2>&1`; then
570 module_build_log "$myerr"
571 info "Look at $LOG to find out what went wrong"
572 return 0
573 fi
574 log "Building the graphics driver module."
575 if ! myerr=`$BUILDINTMP \
576 --use-module-symvers /tmp/vboxguest-Module.symvers \
577 --module-source $MODULE_SRC/vboxvideo \
578 --no-print-directory install 2>&1`; then
579 module_build_log "$myerr"
580 info "Look at $LOG to find out what went wrong"
581 fi
582 [ -d /etc/depmod.d ] || mkdir /etc/depmod.d
583 echo "override vboxguest * misc" > /etc/depmod.d/vboxvideo-upstream.conf
584 echo "override vboxsf * misc" >> /etc/depmod.d/vboxvideo-upstream.conf
585 echo "override vboxvideo * misc" >> /etc/depmod.d/vboxvideo-upstream.conf
586
587 sign_modules "${KERN_VER}"
588
589 update_initramfs "${KERN_VER}"
590
591 return 0
592}
593
594create_vbox_user()
595{
596 # This is the LSB version of useradd and should work on recent
597 # distributions
598 useradd -d /var/run/vboxadd -g 1 -r -s /bin/false vboxadd >/dev/null 2>&1 || true
599 # And for the others, we choose a UID ourselves
600 useradd -d /var/run/vboxadd -g 1 -u 501 -o -s /bin/false vboxadd >/dev/null 2>&1 || true
601
602}
603
604create_udev_rule()
605{
606 # Create udev description file
607 if [ -d /etc/udev/rules.d ]; then
608 udev_call=""
609 udev_app=`which udevadm 2> /dev/null`
610 if [ $? -eq 0 ]; then
611 udev_call="${udev_app} version 2> /dev/null"
612 else
613 udev_app=`which udevinfo 2> /dev/null`
614 if [ $? -eq 0 ]; then
615 udev_call="${udev_app} -V 2> /dev/null"
616 fi
617 fi
618 udev_fix="="
619 if [ "${udev_call}" != "" ]; then
620 udev_out=`${udev_call}`
621 udev_ver=`expr "$udev_out" : '[^0-9]*\([0-9]*\)'`
622 if [ "$udev_ver" = "" -o "$udev_ver" -lt 55 ]; then
623 udev_fix=""
624 fi
625 fi
626 ## @todo 60-vboxadd.rules -> 60-vboxguest.rules ?
627 echo "KERNEL=${udev_fix}\"vboxguest\", NAME=\"vboxguest\", OWNER=\"vboxadd\", MODE=\"0660\"" > /etc/udev/rules.d/60-vboxadd.rules
628 echo "KERNEL=${udev_fix}\"vboxuser\", NAME=\"vboxuser\", OWNER=\"vboxadd\", MODE=\"0666\"" >> /etc/udev/rules.d/60-vboxadd.rules
629 # Make sure the new rule is noticed.
630 udevadm control --reload >/dev/null 2>&1 || true
631 udevcontrol reload_rules >/dev/null 2>&1 || true
632 fi
633}
634
635create_module_rebuild_script()
636{
637 # And a post-installation script for rebuilding modules when a new kernel
638 # is installed.
639 mkdir -p /etc/kernel/postinst.d /etc/kernel/prerm.d
640 cat << EOF > /etc/kernel/postinst.d/vboxadd
641#!/bin/sh
642# This only works correctly on Debian derivatives - Red Hat calls it before
643# installing the right header files.
644/sbin/rcvboxadd quicksetup "\${1}"
645exit 0
646EOF
647 cat << EOF > /etc/kernel/prerm.d/vboxadd
648#!/bin/sh
649for i in ${OLDMODULES}; do rm -f /lib/modules/"\${1}"/misc/"\${i}".ko; done
650rmdir -p /lib/modules/"\$1"/misc 2>/dev/null || true
651exit 0
652EOF
653 chmod 0755 /etc/kernel/postinst.d/vboxadd /etc/kernel/prerm.d/vboxadd
654}
655
656shared_folder_setup()
657{
658 # Add a group "vboxsf" for Shared Folders access
659 # All users which want to access the auto-mounted Shared Folders have to
660 # be added to this group.
661 groupadd -r -f vboxsf >/dev/null 2>&1
662
663 # Put the mount.vboxsf mount helper in the right place.
664 ## @todo It would be nicer if the kernel module just parsed parameters
665 # itself instead of needing a separate binary to do that.
666 ln -sf "${INSTALL_DIR}/other/mount.vboxsf" /sbin
667 # SELinux security context for the mount helper.
668 if test -e /etc/selinux/config; then
669 # This is correct. semanage maps this to the real path, and it aborts
670 # with an error, telling you what you should have typed, if you specify
671 # the real path. The "chcon" is there as a back-up for old guests.
672 command -v semanage > /dev/null &&
673 semanage fcontext -a -t mount_exec_t "${INSTALL_DIR}/other/mount.vboxsf"
674 chcon -t mount_exec_t "${INSTALL_DIR}/other/mount.vboxsf" 2>/dev/null
675 fi
676}
677
678# Returns path to module file as seen by modinfo(8) or empty string.
679module_path()
680{
681 mod="$1"
682 [ -n "$mod" ] || return
683
684 modinfo "$mod" 2>/dev/null | grep -e "^filename:" | tr -s ' ' | cut -d " " -f2
685}
686
687# Returns module version if module is available or empty string.
688module_version()
689{
690 mod="$1"
691 [ -n "$mod" ] || return
692
693 modinfo "$mod" 2>/dev/null | grep -e "^version:" | tr -s ' ' | cut -d " " -f2
694}
695
696# Returns module revision if module is available in the system or empty string.
697module_revision()
698{
699 mod="$1"
700 [ -n "$mod" ] || return
701
702 modinfo "$mod" 2>/dev/null | grep -e "^version:" | tr -s ' ' | cut -d " " -f3
703}
704
705# Returns "1" if module is signed and signature can be verified
706# with public key provided in DEB_PUB_KEY. Or empty string otherwise.
707module_signed()
708{
709 mod="$1"
710 [ -n "$mod" ] || return
711
712 # Be nice with distributions which do not provide tools which we
713 # use in order to verify module signature. This variable needs to
714 # be explicitly set by administrator. This script will look for it
715 # in /etc/virtualbox-guest-additions.conf. Make sure that you know
716 # what you do!
717 if [ "$VBOX_BYPASS_MODULES_SIGNATURE_CHECK" = "1" ]; then
718 echo "1"
719 return
720 fi
721
722 extraction_tool=/lib/modules/"$(uname -r)"/build/scripts/extract-module-sig.pl
723 mod_path=$(module_path "$mod" 2>/dev/null)
724 openssl_tool=$(which openssl 2>/dev/null)
725 # Do not use built-in printf!
726 printf_tool=$(which printf 2>/dev/null)
727
728 # Make sure all the tools required for signature validation are available.
729 [ -x "$extraction_tool" ] || return
730 [ -n "$mod_path" ] || return
731 [ -n "$openssl_tool" ] || return
732 [ -n "$printf_tool" ] || return
733
734 # Make sure openssl can handle hash algorithm.
735 sig_hashalgo=$(modinfo -F sig_hashalgo "$mod" 2>/dev/null)
736 [ "$(module_sig_hash_supported $sig_hashalgo)" = "1" ] || return
737
738 # Generate file names for temporary stuff.
739 mod_pub_key=$(mktemp -u)
740 mod_signature=$(mktemp -u)
741 mod_unsigned=$(mktemp -u)
742
743 # Convert public key in DER format into X509 certificate form.
744 "$openssl_tool" x509 -pubkey -inform DER -in "$DEB_PUB_KEY" -out "$mod_pub_key" 2>/dev/null
745 # Extract raw module signature and convert it into binary format.
746 "$printf_tool" \\x$(modinfo -F signature "$mod" | sed -z 's/[ \t\n]//g' | sed -e "s/:/\\\x/g") 2>/dev/null > "$mod_signature"
747 # Extract unsigned module for further digest calculation.
748 "$extraction_tool" -0 "$mod_path" 2>/dev/null > "$mod_unsigned"
749
750 # Verify signature.
751 rc=""
752 "$openssl_tool" dgst "-$sig_hashalgo" -binary -verify "$mod_pub_key" -signature "$mod_signature" "$mod_unsigned" 2>&1 >/dev/null && rc="1"
753 # Clean up.
754 rm -f $mod_pub_key $mod_signature $mod_unsigned
755
756 # Check result.
757 [ "$rc" = "1" ] || return
758
759 echo "1"
760}
761
762# Returns "1" if externally built module is available in the system and its
763# version and revision number do match to current VirtualBox installation.
764# Or empty string otherwise.
765module_available()
766{
767 mod="$1"
768 [ -n "$mod" ] || return
769
770 [ "$VBOX_VERSION" = "$(module_version "$mod")" ] || return
771 [ "$VBOX_REVISION" = "$(module_revision "$mod")" ] || return
772
773 # Check if module belongs to VirtualBox installation.
774 #
775 # We have a convention that only modules from /lib/modules/*/misc
776 # belong to us. Modules from other locations are treated as
777 # externally built.
778 mod_path="$(module_path "$mod")"
779
780 # If module path points to a symbolic link, resolve actual file location.
781 [ -L "$mod_path" ] && mod_path="$(readlink -e -- "$mod_path")"
782
783 # File exists?
784 [ -f "$mod_path" ] || return
785
786 # Extract last component of module path and check whether it is located
787 # outside of /lib/modules/*/misc.
788 mod_dir="$(dirname "$mod_path" | sed 's;^.*/;;')"
789 [ "$mod_dir" = "misc" ] || return
790
791 # In case if system is running in Secure Boot mode, check if module is signed.
792 if test -n "$HAVE_SEC_BOOT"; then
793 [ "$(module_signed "$mod")" = "1" ] || return
794 fi
795
796 echo "1"
797}
798
799# Check if required modules are installed in the system and versions match.
800setup_complete()
801{
802 [ "$(module_available vboxguest)" = "1" ] || return
803 [ "$(module_available vboxsf)" = "1" ] || return
804
805 # All modules are in place.
806 echo "1"
807}
808
809# setup_script
810setup()
811{
812 info "Setting up modules"
813
814 # chcon is needed on old Fedora/Redhat systems. No one remembers which.
815 test ! -e /etc/selinux/config ||
816 chcon -t bin_t "$BUILDINTMP" 2>/dev/null
817
818 if test -z "$INSTALL_NO_MODULE_BUILDS"; then
819 # Check whether modules setup is already complete for currently running kernel.
820 # Prevent unnecessary rebuilding in order to speed up booting process.
821 if test "$(setup_complete)" = "1"; then
822 info "VirtualBox Guest Additions kernel modules $VBOX_VERSION $VBOX_REVISION are \
823already available for kernel $TARGET_VER and do not require to be rebuilt."
824 else
825 info "Building the VirtualBox Guest Additions kernel modules. This may take a while."
826 info "To build modules for other installed kernels, run"
827 info " /sbin/rcvboxadd quicksetup <version>"
828 info "or"
829 info " /sbin/rcvboxadd quicksetup all"
830 if test -d /lib/modules/"$TARGET_VER"/build; then
831 setup_modules "$TARGET_VER"
832 depmod
833 else
834 info "Kernel headers not found for target kernel $TARGET_VER. \
835Please install them and execute
836 /sbin/rcvboxadd setup"
837 fi
838 fi
839 fi
840 create_vbox_user
841 create_udev_rule
842 test -n "${INSTALL_NO_MODULE_BUILDS}" || create_module_rebuild_script
843 shared_folder_setup
844 # Create user group which will have permissive access to DRP IPC server socket.
845 groupadd -r -f vboxdrmipc >/dev/null 2>&1
846
847 if running_vboxguest || running_vboxadd; then
848 # Only warn user if currently loaded modules version do not match Guest Additions Installation.
849 check_running_module_version "vboxguest" || info "Running kernel modules will not be replaced until the system is restarted or 'rcvboxadd reload' triggered"
850 fi
851
852 # Put the X.Org driver in place. This is harmless if it is not needed.
853 # Also set up the OpenGL library.
854 myerr=`"${INSTALL_DIR}/init/vboxadd-x11" setup 2>&1`
855 test -z "${myerr}" || log "${myerr}"
856
857 return 0
858}
859
860# cleanup_script
861cleanup()
862{
863 if test -z "${INSTALL_NO_MODULE_BUILDS}"; then
864 # Delete old versions of VBox modules.
865 cleanup_modules
866 depmod
867
868 # Remove old module sources
869 for i in $OLDMODULES; do
870 rm -rf /usr/src/$i-*
871 done
872 fi
873
874 # Clean-up X11-related bits
875 "${INSTALL_DIR}/init/vboxadd-x11" cleanup
876
877 # Remove other files
878 if test -z "${INSTALL_NO_MODULE_BUILDS}"; then
879 rm -f /etc/kernel/postinst.d/vboxadd /etc/kernel/prerm.d/vboxadd
880 rmdir -p /etc/kernel/postinst.d /etc/kernel/prerm.d 2>/dev/null || true
881 fi
882 rm -f /sbin/mount.vboxsf 2>/dev/null
883 rm -f /etc/udev/rules.d/60-vboxadd.rules 2>/dev/null
884 udevadm control --reload >/dev/null 2>&1 || true
885 udevcontrol reload_rules >/dev/null 2>&1 || true
886}
887
888start()
889{
890 begin "Starting."
891
892 # Check if kernel modules for currently running kernel are ready
893 # and rebuild them if needed.
894 test "$(setup_complete)" = "1" || setup
895
896 # Warn if Secure Boot setup not yet complete.
897 if test -n "$HAVE_SEC_BOOT" && test -z "$DEB_KEY_ENROLLED"; then
898 if test -n "$HAVE_DEB_KEY"; then
899 info "You must re-start your system to finish secure boot set-up."
900 else
901 info "You must sign vboxguest, vboxsf and
902vboxvideo (if present) kernel modules before using
903VirtualBox Guest Additions. See the documentation
904for your Linux distribution."
905 fi
906 fi
907
908 if test -z "${INSTALL_NO_MODULE_BUILDS}"; then
909 test -d /sys &&
910 ps -A -o comm | grep -q '/*udevd$' 2>/dev/null ||
911 no_udev=1
912 check_running_module_version "vboxguest" || {
913 rm -f $dev || {
914 fail "Cannot remove $dev"
915 }
916 rm -f $userdev || {
917 fail "Cannot remove $userdev"
918 }
919 # Assuming modules were just (re-)built, try to reload everything.
920 reload
921 }
922 case "$no_udev" in 1)
923 do_vboxguest_non_udev;;
924 esac
925 fi # INSTALL_NO_MODULE_BUILDS
926
927 return 0
928}
929
930stop()
931{
932 begin "Stopping."
933
934 if test -r /etc/ld.so.conf.d/00vboxvideo.conf; then
935 rm /etc/ld.so.conf.d/00vboxvideo.conf
936 ldconfig
937 fi
938 if ! umount -a -t vboxsf 2>/dev/null; then
939 # Make sure we only fail, if there are truly no more vboxsf
940 # mounts in the system.
941 [ -n "$(findmnt -t vboxsf)" ] && fail "Cannot unmount vboxsf folders"
942 fi
943 test -n "${INSTALL_NO_MODULE_BUILDS}" ||
944 info "You may need to restart your guest system to finish removing guest drivers or consider running 'rcvboxadd reload'."
945 return 0
946}
947
948# Check if process with this PID is running.
949check_pid()
950{
951 pid=$1
952
953 [ -d "/proc/$pid" ] && true
954}
955
956send_sig_usr1_by_pidfile()
957{
958 pidfile=$1
959
960 if [ -f "$pidfile" ]; then
961 check_pid $(cat "$pidfile")
962 if [ $? -eq 0 ]; then
963 kill -USR1 $(cat "$pidfile") >/dev/null 2>&1
964 else
965 # Do not spoil $?.
966 true
967 fi
968 else
969 # Do not spoil $?.
970 true
971 fi
972}
973
974# SIGUSR1 is used in order to notify VBoxClient processes that system
975# update is started or kernel modules are going to be reloaded,
976# so VBoxClient can release vboxguest.ko resources and then restart itself.
977send_sig_usr1()
978{
979 # Specify whether we sending signal to VBoxClient parent (control)
980 # process or a child (actual service) process.
981 process_type="$1"
982
983 pidfile_postfix=""
984 [ -z "$process_type" ] || pidfile_postfix="-$process_type"
985
986 for user_home in $(getent passwd | cut -d ':' -f 6); do
987 if [ -d "$user_home" ]; then
988
989 for pid_file in "$user_home"/.vboxclient-*"$pidfile_postfix".pid; do
990
991 # If process type was not specified, we assume that signal supposed
992 # to be sent to legacy VBoxClient processes which have different
993 # pidfile name pattern (it does not contain "control" or "service").
994 # Skip those pidfiles who has.
995 [ -z "$process_type" -a -n "$(echo "$pid_file" | grep "control")" ] && continue
996 [ -z "$process_type" -a -n "$(echo "$pid_file" | grep "service")" ] && continue
997
998 send_sig_usr1_by_pidfile "$pid_file"
999 done
1000
1001 fi
1002 done
1003}
1004
1005reload()
1006{
1007 begin "reloading kernel modules and services"
1008
1009 # Check if script was started with root privileges.
1010 [ `id -u` -eq 0 ] || fail "root privileges are required"
1011
1012 # Check if modules were previously build.
1013 [ "$(setup_complete)" = "1" ] || fail "kernel modules were set up yet, please consider running 'rcvboxadd setup' first."
1014
1015 # Stop VBoxService (systemctl stop vboxadd-service.service).
1016 do_sysvinit_action vboxadd-service stop >/dev/null 2>&1
1017
1018 # Unmount Shared Folders.
1019 [ $? -eq 0 ] && umount -a -t vboxsf >/dev/null 2>&1
1020
1021 # Stop VBoxDRMClient.
1022 [ $? -eq 0 ] && send_sig_usr1_by_pidfile "/var/run/VBoxDRMClient"
1023
1024 if [ $? -eq 0 ]; then
1025 # Tell legacy VBoxClient processes to release vboxguest.ko references.
1026 send_sig_usr1 ""
1027
1028 # Tell compatible VBoxClient processes to release vboxguest.ko references.
1029 send_sig_usr1 "service"
1030
1031 # Try unload.
1032 for attempt in 1 2 3 4 5; do
1033
1034 # Give VBoxClient processes some time to close reference to vboxguest module.
1035 [ $? -ne 0 ] && sleep 1
1036
1037 # Try unload drivers unconditionally (ignore previous command exit code).
1038 # If final goal of unloading vboxguest.ko won't be met, we will fail on
1039 # the next step anyway.
1040 running_vboxvideo && modprobe -r vboxvideo >/dev/null 2>&1
1041 running_vboxsf && modprobe -r vboxsf >/dev/null 2>&1
1042 running_vboxguest
1043 if [ $? -eq 0 ]; then
1044 modprobe -r vboxguest >/dev/null 2>&1
1045 else
1046 # Do not spoil $?.
1047 true
1048 fi
1049 done
1050
1051 # Check if we succeeded with unloading vboxguest after several attempts.
1052 running_vboxguest
1053 if [ $? -eq 0 ]; then
1054 fail "Cannot reload kernel modules: one or more module(s) is still in use"
1055 else
1056 # Do not spoil $?.
1057 true
1058 fi
1059
1060 # Load drivers (skip vboxvideo since it is not loaded for very old guests).
1061 [ $? -eq 0 ] && modprobe vboxguest >/dev/null 2>&1
1062 [ $? -eq 0 ] && modprobe vboxsf >/dev/null 2>&1
1063
1064 # Start VBoxService and VBoxDRMClient (systemctl start vboxadd-service.service).
1065 [ $? -eq 0 ] && do_sysvinit_action vboxadd-service start >/dev/null 2>&1
1066
1067 # Reload VBoxClient processes.
1068 [ $? -eq 0 ] && send_sig_usr1 "control"
1069 fi
1070
1071 if [ $? -eq 0 ]; then
1072
1073 # Check if we just loaded modules of correct version.
1074 check_status_kernel
1075
1076 # Check if user-land processes were restarted as well.
1077 check_status_user
1078
1079 # Take reported version of running Guest Additions from running vboxguest module (as a paranoia check).
1080 info "kernel modules and services $(running_module_version "vboxguest") reloaded"
1081 info "NOTE: you may still consider to re-login if some user session specific services (Shared Clipboard, Drag and Drop, Seamless or Guest Screen Resize) were not restarted automatically"
1082 else
1083 fail "cannot reload kernel modules and restart services"
1084 fi
1085}
1086
1087dmnstatus()
1088{
1089 if running_vboxguest; then
1090 echo "The VirtualBox Additions are currently running."
1091 else
1092 echo "The VirtualBox Additions are not currently running."
1093 fi
1094}
1095
1096for i; do
1097 case "$i" in quiet) QUIET=yes;; esac
1098done
1099case "$1" in
1100# Does setup without clean-up first and marks all kernels currently found on the
1101# system so that we can see later if any were added.
1102start)
1103 start
1104 ;;
1105# Tries to build kernel modules for kernels added since start. Tries to unmount
1106# shared folders. Uninstalls our Chromium 3D libraries since we can't always do
1107# this fast enough at start time if we discover we do not want to use them.
1108stop)
1109 stop
1110 ;;
1111restart)
1112 restart
1113 ;;
1114# Tries to reload kernel modules and restart user processes.
1115reload)
1116 reload
1117 ;;
1118# Setup does a clean-up (see below) and re-does all Additions-specific
1119# configuration of the guest system, including building kernel modules for the
1120# current kernel.
1121setup)
1122 cleanup && start
1123 ;;
1124# Builds kernel modules for the specified kernels if they are not already built.
1125quicksetup)
1126 if test x"$2" = xall; then
1127 for topi in /lib/modules/*; do
1128 KERN_VER="${topi%/misc}"
1129 KERN_VER="${KERN_VER#/lib/modules/}"
1130 setup_modules "$KERN_VER"
1131 done
1132 elif test -n "$2"; then
1133 setup_modules "$2"
1134 else
1135 setup_modules "$TARGET_VER"
1136 fi
1137 ;;
1138# Clean-up removes all Additions-specific configuration of the guest system,
1139# including all kernel modules.
1140cleanup)
1141 cleanup
1142 ;;
1143status)
1144 dmnstatus
1145 ;;
1146status-kernel)
1147 check_status_kernel && info "Kernel modules are loaded"
1148 ;;
1149status-user)
1150 check_status_user
1151 if [ $? -eq 0 ]; then
1152 info "User-land services are running"
1153 else
1154 fail "User-land services are not running"
1155 fi
1156 ;;
1157*)
1158 echo "Usage: $0 {start|stop|restart|reload|status|status-kernel|status-user|setup|quicksetup|cleanup} [quiet]"
1159 exit 1
1160esac
1161
1162exit
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