From fb13bbeada47bf35794a8781785372c439820361 Mon Sep 17 00:00:00 2001 From: 3hhh Date: Sat, 26 Nov 2022 11:12:20 +0100 Subject: [PATCH] qubes-pciback: add optional support for a PCI device policy This feature can be used by advanced users to assign devices to pciback in a policy-like manner based on various PCI device attributes. References QubesOS/qubes-issues#7886 QubesOS/qubes-issues#7792 --- .../modules.d/90qubes-pciback/module-setup.sh | 1 + .../90qubes-pciback/qubes-pciback.sh | 37 +++++++++++++++++-- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/dracut/modules.d/90qubes-pciback/module-setup.sh b/dracut/modules.d/90qubes-pciback/module-setup.sh index 2e32edf9..d319a4b2 100755 --- a/dracut/modules.d/90qubes-pciback/module-setup.sh +++ b/dracut/modules.d/90qubes-pciback/module-setup.sh @@ -10,6 +10,7 @@ install () { inst_multiple /etc/nsswitch.conf inst_multiple /etc/usbguard/{qubes-usbguard.conf,rules.d,IPCAccessControl.d} inst_multiple /etc/usbguard/rules.d/* + inst_multiple -o /etc/qubes-pci-policy.conf inst -l /usr/bin/usbguard inst -l /usr/sbin/usbguard-daemon inst /usr/lib/systemd/system/usbguard.service.d/30_qubes.conf diff --git a/dracut/modules.d/90qubes-pciback/qubes-pciback.sh b/dracut/modules.d/90qubes-pciback/qubes-pciback.sh index bf1b08c0..97a931bc 100755 --- a/dracut/modules.d/90qubes-pciback/qubes-pciback.sh +++ b/dracut/modules.d/90qubes-pciback/qubes-pciback.sh @@ -1,10 +1,19 @@ #!/bin/bash -- type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh -unset re HIDE_PCI usb_in_dom0 dev skip exposed +unset re HIDE_PCI usb_in_dom0 dev skip exposed PCI_POLICY_FILE PCI_POLICY_RE ignore_re devs invert usb_in_dom0=false +# PCI_POLICY_FILE syntax: +# - one POSIX regex on `lspci -mm -n` per line (matching device = allowed) +# - empty lines & lines starting with # are ignored +# - lines starting with ! will cause a block +# - processing stops as soon as a match is found +# - WARNING: If you block devices required by dom0, Qubes may not boot anymore. +# You'll have to chroot and re-create the initramfs. +PCI_POLICY_FILE="/etc/qubes-pci-policy.conf" + if getargbool 0 rd.qubes.hide_all_usb; then # Select all networking and USB devices re='0(2|c03)' @@ -17,8 +26,30 @@ else warn 'USB in dom0 is not restricted. Consider rd.qubes.hide_all_usb or usbcore.authorized_default=0.' fi -HIDE_PCI=$(set -o pipefail; { lspci -mm -n | awk "/^[^ ]* \"$re/ {print \$1}";}) || - die 'Cannot obtain list of PCI devices to unbind.' +if getargbool 0 rd.qubes.pci_policy; then + PCI_POLICY_RE="$(cat "$PCI_POLICY_FILE")" || die "Failed to read ${PCI_POLICY_FILE}." + info "Manual PCI policy mode based on ${PCI_POLICY_FILE} in initramfs." + getargbool 0 "rd.qubes.hide_all_usb" && warn "rd.qubes.hide_all_usb has no effect with rd.qubes.pci_policy." + ignore_re='^[[:blank:]]*(#.*)?$' + devs="$(lspci -mm -n)" || die "Cannot obtain the list of PCI devices." + + while IFS= read -r dev ; do + skip=1 + while IFS= read -r re ; do + invert=1 + [[ "$re" =~ $ignore_re ]] && continue + [[ "$re" == '!'* ]] && invert=0 && re="${re:1}" + if [[ "$dev" =~ $re ]] ; then + [ $invert -eq 0 ] && skip=1 || skip=0 + break + fi + done <<< "$PCI_POLICY_RE" + [ $skip -eq 0 ] && info "Allowed PCI device: $dev" || HIDE_PCI="$HIDE_PCI ${dev%% *}" + done <<< "$devs" +else + HIDE_PCI=$(set -o pipefail; { lspci -mm -n | awk "/^[^ ]* \"$re/ {print \$1}";}) || + die 'Cannot obtain the list of PCI devices to unbind.' +fi manual_pcidevs=$(getarg rd.qubes.hide_pci) case $manual_pcidevs in