VirtualBox

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

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

Additions: Linux: rcvboxadd.sh: fixed typo: failure -> fail, bugref:10287.

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