VirtualBox

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

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

Linux: startup scripts: prevent kernel build system from compressing modules on install, bugref:10287.

Let's have installed modules uncompressed regardless kernel configuration.
So, we can deal with modules signing and signature verification if kernel
was configured with one of CONFIG_MODULE_COMPRESS_XXX set.

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