VirtualBox

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

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

Additions: Linux: rcvboxadd.sh: Do not use update-secureboot-policy tool if it does not support required commandline switches, bugref:10287.

Unlike Ubuntu and simillar distributions, on Debian, update-secureboot-policy tool
does not support '--new-key' and '--enroll-key' command line switches. This makes it
no use for us on Debian. Moreover, 'update-secureboot-policy --enroll-key' will open
interactive user-input dialog which will result in 5 minutes hang on guest boot. So,
just don't use it in this case and let user to generate and enroll keys manually.

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 30.2 KB
Line 
1#! /bin/sh
2# $Id: vboxadd.sh 97013 2022-10-05 19:27:55Z vboxsync $
3## @file
4# Linux Additions kernel module init script ($Revision: 97013 $)
5#
6
7#
8# Copyright (C) 2006-2022 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# Marker to ignore a particular kernel version which was already installed.
73SKIPFILE_BASE=/var/lib/VBoxGuestAdditions/skip
74export VBOX_KBUILD_TYPE
75export USERNAME
76
77setup_log()
78{
79 test -z "${LOG}" || return 0
80 # Rotate log files
81 LOG="/var/log/vboxadd-setup.log"
82 mv "${LOG}.3" "${LOG}.4" 2>/dev/null
83 mv "${LOG}.2" "${LOG}.3" 2>/dev/null
84 mv "${LOG}.1" "${LOG}.2" 2>/dev/null
85 mv "${LOG}" "${LOG}.1" 2>/dev/null
86}
87
88if $MODPROBE -c 2>/dev/null | grep -q '^allow_unsupported_modules *0'; then
89 MODPROBE="$MODPROBE --allow-unsupported-modules"
90fi
91
92# Preamble for Gentoo
93if [ "`which $0`" = "/sbin/rc" ]; then
94 shift
95fi
96
97begin()
98{
99 test -n "${QUIET}" || echo "${SERVICE}: ${1}"
100}
101
102info()
103{
104 if test -z "${QUIET}"; then
105 echo "${SERVICE}: $1" | fold -s
106 else
107 echo "$1" | fold -s
108 fi
109}
110
111fail()
112{
113 log "${1}"
114 echo "$1" >&2
115 echo "The log file $LOG may contain further information." >&2
116 exit 1
117}
118
119log()
120{
121 setup_log
122 echo "${1}" >> "${LOG}"
123}
124
125module_build_log()
126{
127 log "Error building the module. Build output follows."
128 echo ""
129 echo "${1}" >> "${LOG}"
130}
131
132dev=/dev/vboxguest
133userdev=/dev/vboxuser
134config=/var/lib/VBoxGuestAdditions/config
135owner=vboxadd
136group=1
137
138if test -r $config; then
139 . $config
140else
141 fail "Configuration file $config not found"
142fi
143test -n "$INSTALL_DIR" -a -n "$INSTALL_VER" ||
144 fail "Configuration file $config not complete"
145MODULE_SRC="$INSTALL_DIR/src/vboxguest-$INSTALL_VER"
146BUILDINTMP="$MODULE_SRC/build_in_tmp"
147
148# Attempt to detect VirtualBox Guest Additions version and revision information.
149VBOXCLIENT="${INSTALL_DIR}/bin/VBoxClient"
150VBOX_VERSION="`"$VBOXCLIENT" --version | cut -d r -f1`"
151[ -n "$VBOX_VERSION" ] || VBOX_VERSION='unknown'
152VBOX_REVISION="r`"$VBOXCLIENT" --version | cut -d r -f2`"
153[ "$VBOX_REVISION" != "r" ] || VBOX_REVISION='unknown'
154
155running_vboxguest()
156{
157 lsmod | grep -q "vboxguest[^_-]"
158}
159
160running_vboxadd()
161{
162 lsmod | grep -q "vboxadd[^_-]"
163}
164
165running_vboxsf()
166{
167 lsmod | grep -q "vboxsf[^_-]"
168}
169
170running_vboxvideo()
171{
172 lsmod | grep -q "vboxvideo[^_-]"
173}
174
175do_vboxguest_non_udev()
176{
177 if [ ! -c $dev ]; then
178 maj=`sed -n 's;\([0-9]\+\) vboxguest;\1;p' /proc/devices`
179 if [ ! -z "$maj" ]; then
180 min=0
181 else
182 min=`sed -n 's;\([0-9]\+\) vboxguest;\1;p' /proc/misc`
183 if [ ! -z "$min" ]; then
184 maj=10
185 fi
186 fi
187 test -n "$maj" || {
188 rmmod vboxguest 2>/dev/null
189 fail "Cannot locate the VirtualBox device"
190 }
191
192 mknod -m 0664 $dev c $maj $min || {
193 rmmod vboxguest 2>/dev/null
194 fail "Cannot create device $dev with major $maj and minor $min"
195 }
196 fi
197 chown $owner:$group $dev 2>/dev/null || {
198 rm -f $dev 2>/dev/null
199 rm -f $userdev 2>/dev/null
200 rmmod vboxguest 2>/dev/null
201 fail "Cannot change owner $owner:$group for device $dev"
202 }
203
204 if [ ! -c $userdev ]; then
205 maj=10
206 min=`sed -n 's;\([0-9]\+\) vboxuser;\1;p' /proc/misc`
207 if [ ! -z "$min" ]; then
208 mknod -m 0666 $userdev c $maj $min || {
209 rm -f $dev 2>/dev/null
210 rmmod vboxguest 2>/dev/null
211 fail "Cannot create device $userdev with major $maj and minor $min"
212 }
213 chown $owner:$group $userdev 2>/dev/null || {
214 rm -f $dev 2>/dev/null
215 rm -f $userdev 2>/dev/null
216 rmmod vboxguest 2>/dev/null
217 fail "Cannot change owner $owner:$group for device $userdev"
218 }
219 fi
220 fi
221}
222
223restart()
224{
225 stop && start
226 return 0
227}
228
229## Update the initramfs. Debian and Ubuntu put the graphics driver in, and
230# need the touch(1) command below. Everyone else that I checked just need
231# the right module alias file from depmod(1) and only use the initramfs to
232# load the root filesystem, not the boot splash. update-initramfs works
233# for the first two and dracut for every one else I checked. We are only
234# interested in distributions recent enough to use the KMS vboxvideo driver.
235update_initramfs()
236{
237 ## kernel version to update for.
238 version="${1}"
239 depmod "${version}"
240 rm -f "/lib/modules/${version}/initrd/vboxvideo"
241 test ! -d "/lib/modules/${version}/initrd" ||
242 test ! -f "/lib/modules/${version}/misc/vboxvideo.ko" ||
243 touch "/lib/modules/${version}/initrd/vboxvideo"
244
245 # Systems without systemd-inhibit probably don't need their initramfs
246 # rebuild here anyway.
247 type systemd-inhibit >/dev/null 2>&1 || return
248 if type dracut >/dev/null 2>&1; then
249 systemd-inhibit --why="Installing VirtualBox Guest Additions" \
250 dracut -f --kver "${version}"
251 elif type update-initramfs >/dev/null 2>&1; then
252 systemd-inhibit --why="Installing VirtualBox Guest Additions" \
253 update-initramfs -u -k "${version}"
254 fi
255}
256
257# Remove any existing VirtualBox guest kernel modules from the disk, but not
258# from the kernel as they may still be in use
259cleanup_modules()
260{
261 # Needed for Ubuntu and Debian, see update_initramfs
262 rm -f /lib/modules/*/initrd/vboxvideo
263 for i in /lib/modules/*/misc; do
264 KERN_VER="${i%/misc}"
265 KERN_VER="${KERN_VER#/lib/modules/}"
266 unset do_update
267 for j in ${OLDMODULES}; do
268 test -f "${i}/${j}.ko" && do_update=1 && rm -f "${i}/${j}.ko"
269 done
270 test -z "$do_update" || update_initramfs "$KERN_VER"
271 # Remove empty /lib/modules folders which may have been kept around
272 rmdir -p "${i}" 2>/dev/null || true
273 unset keep
274 for j in /lib/modules/"${KERN_VER}"/*; do
275 name="${j##*/}"
276 test -d "${name}" || test "${name%%.*}" != modules && keep=1
277 done
278 if test -z "${keep}"; then
279 rm -rf /lib/modules/"${KERN_VER}"
280 rm -f /boot/initrd.img-"${KERN_VER}"
281 fi
282 done
283 for i in ${OLDMODULES}; do
284 # We no longer support DKMS, remove any leftovers.
285 rm -rf "/var/lib/dkms/${i}"*
286 done
287 rm -f /etc/depmod.d/vboxvideo-upstream.conf
288 rm -f "$SKIPFILE_BASE"-*
289}
290
291# Secure boot state.
292case "`mokutil --sb-state 2>/dev/null`" in
293 *"disabled in shim"*) unset HAVE_SEC_BOOT;;
294 *"SecureBoot enabled"*) HAVE_SEC_BOOT=true;;
295 *) unset HAVE_SEC_BOOT;;
296esac
297# So far we can only sign modules on Ubuntu and on Debian 10 and later.
298DEB_PUB_KEY=/var/lib/shim-signed/mok/MOK.der
299DEB_PRIV_KEY=/var/lib/shim-signed/mok/MOK.priv
300# Check if key already enrolled.
301unset HAVE_DEB_KEY
302case "`mokutil --test-key "$DEB_PUB_KEY" 2>/dev/null`" in
303 *"is already"*) DEB_KEY_ENROLLED=true;;
304 *) unset DEB_KEY_ENROLLED;;
305esac
306
307# Check if update-secureboot-policy tool supports required commandline options.
308update_secureboot_policy_supports()
309{
310 opt_name="$1"
311 [ -n "$opt_name" ] || return
312
313 [ -z "$(update-secureboot-policy --help 2>&1 | grep "$opt_name")" ] && return
314 echo "1"
315}
316
317HAVE_UPDATE_SECUREBOOT_POLICY_TOOL=
318if type update-secureboot-policy >/dev/null 2>&1; then
319 [ "$(update_secureboot_policy_supports new-key)" = "1" -a "$(update_secureboot_policy_supports enroll-key)" = "1" ] && \
320 HAVE_UPDATE_SECUREBOOT_POLICY_TOOL=true
321fi
322
323# Reads kernel configuration option.
324kernel_get_config_opt()
325{
326 opt_name="$1"
327 [ -n "$opt_name" ] || return
328
329 # Check if there is a kernel tool which can extract config option.
330 if test -x /lib/modules/"$KERN_VER"/build/scripts/config; then
331 /lib/modules/"$KERN_VER"/build/scripts/config \
332 --file /lib/modules/"$KERN_VER"/build/.config \
333 --state "$opt_name" 2>/dev/null
334 elif test -f /lib/modules/"$KERN_VER"/build/.config; then
335 # Extract config option manually.
336 grep "$opt_name" /lib/modules/"$KERN_VER"/build/.config | sed -e "s/^$opt_name=//" -e "s/\"//g"
337 fi
338}
339
340# Reads CONFIG_MODULE_SIG_HASH from kernel config.
341kernel_module_sig_hash()
342{
343 kernel_get_config_opt "CONFIG_MODULE_SIG_HASH"
344}
345
346# Returns "1" if kernel module signature hash algorithm
347# is supported by us. Or empty string otherwise.
348module_sig_hash_supported()
349{
350 sig_hashalgo="$1"
351 [ -n "$sig_hashalgo" ] || return
352
353 # Go through supported list.
354 [ "$sig_hashalgo" = "sha1" \
355 -o "$sig_hashalgo" = "sha224" \
356 -o "$sig_hashalgo" = "sha256" \
357 -o "$sig_hashalgo" = "sha384" \
358 -o "$sig_hashalgo" = "sha512" ] || return
359
360 echo "1"
361}
362
363sign_modules()
364{
365 KERN_VER="$1"
366 test -n "$KERN_VER" || return 1
367
368 # Make list of mudules to sign.
369 MODULE_LIST="vboxguest vboxsf"
370 # vboxvideo might not present on for older kernels.
371 [ -f "/lib/modules/"$KERN_VER"/misc/vboxvideo.ko" ] && MODULE_LIST="$MODULE_LIST vboxvideo"
372
373 # Secure boot on Ubuntu, Debian and Oracle Linux.
374 if test -n "$HAVE_SEC_BOOT"; then
375 begin "Signing VirtualBox Guest Additions kernel modules"
376
377 # Generate new signing key if needed.
378 [ -n "$HAVE_UPDATE_SECUREBOOT_POLICY_TOOL" ] && SHIM_NOTRIGGER=y update-secureboot-policy --new-key
379
380 # Check if signing keys are in place.
381 if test ! -f "$DEB_PUB_KEY" || ! test -f "$DEB_PRIV_KEY"; then
382 # update-secureboot-policy tool present in the system, but keys were not generated.
383 [ -n "$HAVE_UPDATE_SECUREBOOT_POLICY_TOOL" ] && info "
384
385update-secureboot-policy tool does not generate signing keys
386in your distribution, see below on how to generate them manually."
387 # update-secureboot-policy not present in the system, recommend generate keys manually.
388 fail "
389
390System is running in Secure Boot mode, however your distribution
391does not provide tools for automatic generation of keys needed for
392modules signing. Please consider to generate and enroll them manually:
393
394 sudo mkdir -p /var/lib/shim-signed/mok
395 sudo openssl req -nodes -new -x509 -newkey rsa:2048 -outform DER -keyout $DEB_PRIV_KEY -out $DEB_PUB_KEY
396 sudo sudo mokutil --import $DEB_PUB_KEY
397 sudo reboot
398
399Restart \"rcvboxadd setup\" after system is rebooted.
400"
401 fi
402
403 # Get kernel signature hash algorithm from kernel config and validate it.
404 sig_hashalgo=$(kernel_module_sig_hash)
405 [ "$(module_sig_hash_supported $sig_hashalgo)" = "1" ] \
406 || fail "Unsupported kernel signature hash algorithm $sig_hashalgo"
407
408 # Sign modules.
409 for i in $MODULE_LIST; do
410
411 # Try to find a tool for modules signing.
412 SIGN_TOOL=$(which kmodsign 2>/dev/null)
413 # Attempt to use in-kernel signing tool if kmodsign not found.
414 if test -z "$SIGN_TOOL"; then
415 if test -x "/lib/modules/$KERN_VER/build/scripts/sign-file"; then
416 SIGN_TOOL="/lib/modules/$KERN_VER/build/scripts/sign-file"
417 fi
418 fi
419
420 # Check if signing tool is available.
421 [ -n "$SIGN_TOOL" ] || fail "Unable to find signing tool"
422
423 "$SIGN_TOOL" "$sig_hashalgo" "$DEB_PRIV_KEY" "$DEB_PUB_KEY" \
424 /lib/modules/"$KERN_VER"/misc/"$i".ko || fail "Unable to sign $i.ko"
425 done
426 # Enroll signing key if needed.
427 if test -n "$HAVE_UPDATE_SECUREBOOT_POLICY_TOOL"; then
428 # update-secureboot-policy "expects" DKMS modules.
429 # Work around this and talk to the authors as soon
430 # as possible to fix it.
431 mkdir -p /var/lib/dkms/vbox-temp
432 update-secureboot-policy --enroll-key 2>/dev/null ||
433 fail "Failed to enroll secure boot key."
434 rmdir -p /var/lib/dkms/vbox-temp 2>/dev/null
435
436 # Indicate that key has been enrolled and reboot is needed.
437 HAVE_DEB_KEY=true
438 fi
439 fi
440}
441
442# Build and install the VirtualBox guest kernel modules
443setup_modules()
444{
445 KERN_VER="$1"
446 test -n "$KERN_VER" || return 1
447 # Match (at least): vboxguest.o; vboxguest.ko; vboxguest.ko.xz
448 set /lib/modules/"$KERN_VER"/misc/vboxguest.*o*
449 #test ! -f "$1" || return 0
450 test -d /lib/modules/"$KERN_VER"/build || return 0
451 export KERN_VER
452 info "Building the modules for kernel $KERN_VER."
453
454 # Detect if kernel was built with clang.
455 unset LLVM
456 vbox_cc_is_clang=$(kernel_get_config_opt "CONFIG_MODULE_SIG_HASH")
457 if test "${vbox_cc_is_clang}" = "y"; then
458 info "Using clang compiler."
459 export LLVM=1
460 fi
461
462 log "Building the main Guest Additions $INSTALL_VER module for kernel $KERN_VER."
463 if ! myerr=`$BUILDINTMP \
464 --save-module-symvers /tmp/vboxguest-Module.symvers \
465 --module-source $MODULE_SRC/vboxguest \
466 --no-print-directory install 2>&1`; then
467 # If check_module_dependencies.sh fails it prints a message itself.
468 module_build_log "$myerr"
469 "${INSTALL_DIR}"/other/check_module_dependencies.sh 2>&1 &&
470 info "Look at $LOG to find out what went wrong"
471 return 0
472 fi
473 log "Building the shared folder support module."
474 if ! myerr=`$BUILDINTMP \
475 --use-module-symvers /tmp/vboxguest-Module.symvers \
476 --module-source $MODULE_SRC/vboxsf \
477 --no-print-directory install 2>&1`; then
478 module_build_log "$myerr"
479 info "Look at $LOG to find out what went wrong"
480 return 0
481 fi
482 log "Building the graphics driver module."
483 if ! myerr=`$BUILDINTMP \
484 --use-module-symvers /tmp/vboxguest-Module.symvers \
485 --module-source $MODULE_SRC/vboxvideo \
486 --no-print-directory install 2>&1`; then
487 module_build_log "$myerr"
488 info "Look at $LOG to find out what went wrong"
489 fi
490 [ -d /etc/depmod.d ] || mkdir /etc/depmod.d
491 echo "override vboxguest * misc" > /etc/depmod.d/vboxvideo-upstream.conf
492 echo "override vboxsf * misc" >> /etc/depmod.d/vboxvideo-upstream.conf
493 echo "override vboxvideo * misc" >> /etc/depmod.d/vboxvideo-upstream.conf
494
495 sign_modules "${KERN_VER}"
496
497 update_initramfs "${KERN_VER}"
498 return 0
499}
500
501create_vbox_user()
502{
503 # This is the LSB version of useradd and should work on recent
504 # distributions
505 useradd -d /var/run/vboxadd -g 1 -r -s /bin/false vboxadd >/dev/null 2>&1 || true
506 # And for the others, we choose a UID ourselves
507 useradd -d /var/run/vboxadd -g 1 -u 501 -o -s /bin/false vboxadd >/dev/null 2>&1 || true
508
509}
510
511create_udev_rule()
512{
513 # Create udev description file
514 if [ -d /etc/udev/rules.d ]; then
515 udev_call=""
516 udev_app=`which udevadm 2> /dev/null`
517 if [ $? -eq 0 ]; then
518 udev_call="${udev_app} version 2> /dev/null"
519 else
520 udev_app=`which udevinfo 2> /dev/null`
521 if [ $? -eq 0 ]; then
522 udev_call="${udev_app} -V 2> /dev/null"
523 fi
524 fi
525 udev_fix="="
526 if [ "${udev_call}" != "" ]; then
527 udev_out=`${udev_call}`
528 udev_ver=`expr "$udev_out" : '[^0-9]*\([0-9]*\)'`
529 if [ "$udev_ver" = "" -o "$udev_ver" -lt 55 ]; then
530 udev_fix=""
531 fi
532 fi
533 ## @todo 60-vboxadd.rules -> 60-vboxguest.rules ?
534 echo "KERNEL=${udev_fix}\"vboxguest\", NAME=\"vboxguest\", OWNER=\"vboxadd\", MODE=\"0660\"" > /etc/udev/rules.d/60-vboxadd.rules
535 echo "KERNEL=${udev_fix}\"vboxuser\", NAME=\"vboxuser\", OWNER=\"vboxadd\", MODE=\"0666\"" >> /etc/udev/rules.d/60-vboxadd.rules
536 # Make sure the new rule is noticed.
537 udevadm control --reload >/dev/null 2>&1 || true
538 udevcontrol reload_rules >/dev/null 2>&1 || true
539 fi
540}
541
542create_module_rebuild_script()
543{
544 # And a post-installation script for rebuilding modules when a new kernel
545 # is installed.
546 mkdir -p /etc/kernel/postinst.d /etc/kernel/prerm.d
547 cat << EOF > /etc/kernel/postinst.d/vboxadd
548#!/bin/sh
549# This only works correctly on Debian derivatives - Red Hat calls it before
550# installing the right header files.
551/sbin/rcvboxadd quicksetup "\${1}"
552exit 0
553EOF
554 cat << EOF > /etc/kernel/prerm.d/vboxadd
555#!/bin/sh
556for i in ${OLDMODULES}; do rm -f /lib/modules/"\${1}"/misc/"\${i}".ko; done
557rmdir -p /lib/modules/"\$1"/misc 2>/dev/null || true
558exit 0
559EOF
560 chmod 0755 /etc/kernel/postinst.d/vboxadd /etc/kernel/prerm.d/vboxadd
561}
562
563shared_folder_setup()
564{
565 # Add a group "vboxsf" for Shared Folders access
566 # All users which want to access the auto-mounted Shared Folders have to
567 # be added to this group.
568 groupadd -r -f vboxsf >/dev/null 2>&1
569
570 # Put the mount.vboxsf mount helper in the right place.
571 ## @todo It would be nicer if the kernel module just parsed parameters
572 # itself instead of needing a separate binary to do that.
573 ln -sf "${INSTALL_DIR}/other/mount.vboxsf" /sbin
574 # SELinux security context for the mount helper.
575 if test -e /etc/selinux/config; then
576 # This is correct. semanage maps this to the real path, and it aborts
577 # with an error, telling you what you should have typed, if you specify
578 # the real path. The "chcon" is there as a back-up for old guests.
579 command -v semanage > /dev/null &&
580 semanage fcontext -a -t mount_exec_t "${INSTALL_DIR}/other/mount.vboxsf"
581 chcon -t mount_exec_t "${INSTALL_DIR}/other/mount.vboxsf" 2>/dev/null
582 fi
583}
584
585# Returns path to module file as seen by modinfo(8) or empty string.
586module_path()
587{
588 mod="$1"
589 [ -n "$mod" ] || return
590
591 modinfo "$mod" 2>/dev/null | grep -e "^filename:" | tr -s ' ' | cut -d " " -f2
592}
593
594# Returns module version if module is available or empty string.
595module_version()
596{
597 mod="$1"
598 [ -n "$mod" ] || return
599
600 modinfo "$mod" 2>/dev/null | grep -e "^version:" | tr -s ' ' | cut -d " " -f2
601}
602
603# Returns module revision if module is available in the system or empty string.
604module_revision()
605{
606 mod="$1"
607 [ -n "$mod" ] || return
608
609 modinfo "$mod" 2>/dev/null | grep -e "^version:" | tr -s ' ' | cut -d " " -f3
610}
611
612
613# Returns "1" if module is signed and signature can be verified
614# with public key provided in DEB_PUB_KEY. Or empty string otherwise.
615module_signed()
616{
617 mod="$1"
618 [ -n "$mod" ] || return
619
620 extraction_tool=/lib/modules/"$(uname -r)"/build/scripts/extract-module-sig.pl
621 mod_path=$(module_path "$mod" 2>/dev/null)
622 openssl_tool=$(which openssl 2>/dev/null)
623 # Do not use built-in printf!
624 printf_tool=$(which printf 2>/dev/null)
625
626 # Make sure all the tools required for signature validation are available.
627 [ -x "$extraction_tool" ] || return
628 [ -n "$mod_path" ] || return
629 [ -n "$openssl_tool" ] || return
630 [ -n "$printf_tool" ] || return
631
632 # Make sure openssl can handle hash algorithm.
633 sig_hashalgo=$(modinfo -F sig_hashalgo vboxdrv 2>/dev/null)
634 [ "$(module_sig_hash_supported $sig_hashalgo)" = "1" ] || return
635
636 # Generate file names for temporary stuff.
637 mod_pub_key=$(mktemp -u)
638 mod_signature=$(mktemp -u)
639 mod_unsigned=$(mktemp -u)
640
641 # Convert public key in DER format into X509 certificate form.
642 "$openssl_tool" x509 -pubkey -inform DER -in "$DEB_PUB_KEY" -out "$mod_pub_key" 2>/dev/null
643 # Extract raw module signature and convert it into binary format.
644 "$printf_tool" \\x$(modinfo -F signature "$mod" | sed -z 's/[ \t\n]//g' | sed -e "s/:/\\\x/g") 2>/dev/null > "$mod_signature"
645 # Extract unsigned module for further digest calculation.
646 "$extraction_tool" -0 "$mod_path" 2>/dev/null > "$mod_unsigned"
647
648 # Verify signature.
649 rc=""
650 "$openssl_tool" dgst "-$sig_hashalgo" -binary -verify "$mod_pub_key" -signature "$mod_signature" "$mod_unsigned" 2>&1 >/dev/null && rc="1"
651 # Clean up.
652 rm -f $mod_pub_key $mod_signature $mod_unsigned
653
654 # Check result.
655 [ "$rc" = "1" ] || return
656
657 echo "1"
658}
659
660# Returns "1" if externally built module is available in the system and its
661# version and revision number do match to current VirtualBox installation.
662# Or empty string otherwise.
663module_available()
664{
665 mod="$1"
666 [ -n "$mod" ] || return
667
668 [ "$VBOX_VERSION" = "$(module_version "$mod")" ] || return
669 [ "$VBOX_REVISION" = "$(module_revision "$mod")" ] || return
670
671 # Check if module belongs to VirtualBox installation.
672 #
673 # We have a convention that only modules from /lib/modules/*/misc
674 # belong to us. Modules from other locations are treated as
675 # externally built.
676 mod_path="$(module_path "$mod")"
677
678 # If module path points to a symbolic link, resolve actual file location.
679 [ -L "$mod_path" ] && mod_path="$(readlink -e -- "$mod_path")"
680
681 # File exists?
682 [ -f "$mod_path" ] || return
683
684 # Extract last component of module path and check whether it is located
685 # outside of /lib/modules/*/misc.
686 mod_dir="$(dirname "$mod_path" | sed 's;^.*/;;')"
687 [ "$mod_dir" = "misc" ] || return
688
689 # In case if system is running in Secure Boot mode, check if module is signed.
690 if test -n "$HAVE_SEC_BOOT"; then
691 [ "$(module_signed "$mod")" = "1" ] || return
692 fi
693
694 echo "1"
695}
696
697# Check if required modules are installed in the system and versions match.
698setup_complete()
699{
700 [ "$(module_available vboxguest)" = "1" ] || return
701 [ "$(module_available vboxsf)" = "1" ] || return
702
703 # All modules are in place.
704 echo "1"
705}
706
707# setup_script
708setup()
709{
710 info "Setting up modules"
711
712 # chcon is needed on old Fedora/Redhat systems. No one remembers which.
713 test ! -e /etc/selinux/config ||
714 chcon -t bin_t "$BUILDINTMP" 2>/dev/null
715
716 if test -z "$INSTALL_NO_MODULE_BUILDS"; then
717 # Check whether modules setup is already complete for currently running kernel.
718 # Prevent unnecessary rebuilding in order to speed up booting process.
719 if test "$(setup_complete)" = "1"; then
720 info "VirtualBox Guest Additions kernel modules $VBOX_VERSION $VBOX_REVISION are \
721already available for kernel $TARGET_VER and do not require to be rebuilt."
722 else
723 info "Building the VirtualBox Guest Additions kernel modules. This may take a while."
724 info "To build modules for other installed kernels, run"
725 info " /sbin/rcvboxadd quicksetup <version>"
726 info "or"
727 info " /sbin/rcvboxadd quicksetup all"
728 if test -d /lib/modules/"$TARGET_VER"/build; then
729 setup_modules "$TARGET_VER"
730 depmod
731 else
732 info "Kernel headers not found for target kernel $TARGET_VER. \
733Please install them and execute
734 /sbin/rcvboxadd setup"
735 fi
736 fi
737 fi
738 create_vbox_user
739 create_udev_rule
740 test -n "${INSTALL_NO_MODULE_BUILDS}" || create_module_rebuild_script
741 shared_folder_setup
742 # Create user group which will have permissive access to DRP IPC server socket.
743 groupadd -r -f vboxdrmipc >/dev/null 2>&1
744
745 if running_vboxguest || running_vboxadd; then
746 info "Running kernel modules will not be replaced until the system is restarted"
747 fi
748
749 # Put the X.Org driver in place. This is harmless if it is not needed.
750 # Also set up the OpenGL library.
751 myerr=`"${INSTALL_DIR}/init/vboxadd-x11" setup 2>&1`
752 test -z "${myerr}" || log "${myerr}"
753
754 return 0
755}
756
757# cleanup_script
758cleanup()
759{
760 if test -z "${INSTALL_NO_MODULE_BUILDS}"; then
761 # Delete old versions of VBox modules.
762 cleanup_modules
763 depmod
764
765 # Remove old module sources
766 for i in $OLDMODULES; do
767 rm -rf /usr/src/$i-*
768 done
769 fi
770
771 # Clean-up X11-related bits
772 "${INSTALL_DIR}/init/vboxadd-x11" cleanup
773
774 # Remove other files
775 if test -z "${INSTALL_NO_MODULE_BUILDS}"; then
776 rm -f /etc/kernel/postinst.d/vboxadd /etc/kernel/prerm.d/vboxadd
777 rmdir -p /etc/kernel/postinst.d /etc/kernel/prerm.d 2>/dev/null || true
778 fi
779 rm -f /sbin/mount.vboxsf 2>/dev/null
780 rm -f /etc/udev/rules.d/60-vboxadd.rules 2>/dev/null
781 udevadm control --reload >/dev/null 2>&1 || true
782 udevcontrol reload_rules >/dev/null 2>&1 || true
783}
784
785start()
786{
787 begin "Starting."
788 if test -z "${INSTALL_NO_MODULE_BUILDS}"; then
789 # We want to build modules for newly installed kernels on shutdown, so
790 # mark the ones already present. These will be ignored on shutdown.
791 rm -f "$SKIPFILE_BASE"-*
792 for setupi in /lib/modules/*; do
793 KERN_VER="${setupi##*/}"
794 # For a full setup, mark kernels we do not want to build.
795 touch "$SKIPFILE_BASE"-"$KERN_VER"
796 done
797 fi
798 setup
799
800 # Warn if Secure Boot setup not yet complete.
801 if test -n "$HAVE_SEC_BOOT" && test -z "$DEB_KEY_ENROLLED"; then
802 if test -n "$HAVE_DEB_KEY"; then
803 info "You must re-start your system to finish secure boot set-up."
804 else
805 info "You must sign vboxguest, vboxsf and
806vboxvideo (if present) kernel modules before using
807VirtualBox Guest Additions. See the documentation
808for your Linux distribution."
809 fi
810 fi
811
812 if test -z "${INSTALL_NO_MODULE_BUILDS}"; then
813 test -d /sys &&
814 ps -A -o comm | grep -q '/*udevd$' 2>/dev/null ||
815 no_udev=1
816 running_vboxguest || {
817 rm -f $dev || {
818 fail "Cannot remove $dev"
819 }
820 rm -f $userdev || {
821 fail "Cannot remove $userdev"
822 }
823 $MODPROBE vboxguest >/dev/null 2>&1 ||
824 fail "modprobe vboxguest failed"
825 case "$no_udev" in 1)
826 sleep .5;;
827 esac
828 $MODPROBE vboxsf > /dev/null 2>&1 ||
829 info "modprobe vboxsf failed"
830 }
831 case "$no_udev" in 1)
832 do_vboxguest_non_udev;;
833 esac
834 fi # INSTALL_NO_MODULE_BUILDS
835
836 return 0
837}
838
839stop()
840{
841 begin "Stopping."
842 if test -z "${INSTALL_NO_MODULE_BUILDS}"; then
843 # We want to build modules for newly installed kernels on shutdown, so
844 # check which we marked at start-up.
845 for setupi in /lib/modules/*; do
846 KERN_VER="${setupi##*/}"
847 # For a full setup, mark kernels we do not want to build.
848 test -f "$SKIPFILE_BASE"-"$KERN_VER" || setup_modules "$KERN_VER"
849 done
850 fi
851 if test -r /etc/ld.so.conf.d/00vboxvideo.conf; then
852 rm /etc/ld.so.conf.d/00vboxvideo.conf
853 ldconfig
854 fi
855 if ! umount -a -t vboxsf 2>/dev/null; then
856 # Make sure we only fail, if there are truly no more vboxsf
857 # mounts in the system.
858 [ -n "$(findmnt -t vboxsf)" ] && fail "Cannot unmount vboxsf folders"
859 fi
860 test -n "${INSTALL_NO_MODULE_BUILDS}" ||
861 info "You may need to restart your guest system to finish removing guest drivers."
862 return 0
863}
864
865dmnstatus()
866{
867 if running_vboxguest; then
868 echo "The VirtualBox Additions are currently running."
869 else
870 echo "The VirtualBox Additions are not currently running."
871 fi
872}
873
874for i; do
875 case "$i" in quiet) QUIET=yes;; esac
876done
877case "$1" in
878# Does setup without clean-up first and marks all kernels currently found on the
879# system so that we can see later if any were added.
880start)
881 start
882 ;;
883# Tries to build kernel modules for kernels added since start. Tries to unmount
884# shared folders. Uninstalls our Chromium 3D libraries since we can't always do
885# this fast enough at start time if we discover we do not want to use them.
886stop)
887 stop
888 ;;
889restart)
890 restart
891 ;;
892# Setup does a clean-up (see below) and re-does all Additions-specific
893# configuration of the guest system, including building kernel modules for the
894# current kernel.
895setup)
896 cleanup && start
897 ;;
898# Builds kernel modules for the specified kernels if they are not already built.
899quicksetup)
900 if test x"$2" = xall; then
901 for topi in /lib/modules/*; do
902 KERN_VER="${topi%/misc}"
903 KERN_VER="${KERN_VER#/lib/modules/}"
904 setup_modules "$KERN_VER"
905 done
906 elif test -n "$2"; then
907 setup_modules "$2"
908 else
909 setup_modules "$TARGET_VER"
910 fi
911 ;;
912# Clean-up removes all Additions-specific configuration of the guest system,
913# including all kernel modules.
914cleanup)
915 cleanup
916 ;;
917status)
918 dmnstatus
919 ;;
920*)
921 echo "Usage: $0 {start|stop|restart|status|setup|quicksetup|cleanup} [quiet]"
922 exit 1
923esac
924
925exit
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