diff --git a/README.md b/README.md index 7d88860..007bc55 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ Due to potential security implications of arbitrary code execution (firewall.rul ### Commandline argumentop - `systemd.volatile=overlay` controls the switch between Protected Mode (when present) and Maintenance Mode (when omitted) -- `reliant.e2fsck` runs `e2fsck -p` on every volume before mount to avoid needing an extra reboot in case of accidental data corruption +- `reliant.e2fsck` attempts to run `e2fsck -p` on volumes in case mount fails - `reliant.dvl=VOLUME_ID` limits the amount of volumes displayed in Qubes app menu, manager, and other places, useful for when you want to avoid showing your hidden qubes in public - Displayed volume limit does **NOT** provide plausible deniability or actual device inspection diff --git a/dracut/99reliant/module-setup.sh b/dracut/99reliant/module-setup.sh index 54f159a..e12a354 100755 --- a/dracut/99reliant/module-setup.sh +++ b/dracut/99reliant/module-setup.sh @@ -37,12 +37,7 @@ install() { inst /etc/reliant.conf # Other binaries - inst_multiple dmesg lsblk blockdev mount dd wc sed sort sleep md5sum find modprobe cut grep mkdir rm rmdir tail - - # Optional profiling - if [ "$RELIANT_PROFILING" = "true" ]; then - inst /usr/lib/systemd/systemd-volatile-root.reliant-profiling /usr/lib/systemd/systemd-volatile-root - fi + inst_multiple dmesg e2fsck lsblk blockdev mount dd wc sed sort sleep md5sum find findmnt modprobe cut grep mkdir rm rmdir tail return 0 } diff --git a/dracut/99reliant/scripts/reliant-initramfs.sh b/dracut/99reliant/scripts/reliant-initramfs.sh index 94bcd1e..c951538 100755 --- a/dracut/99reliant/scripts/reliant-initramfs.sh +++ b/dracut/99reliant/scripts/reliant-initramfs.sh @@ -115,7 +115,7 @@ main() { # Seal all volumes for path in '/run/shufflecake/'*; do name="${path##*/}" - reliant-seal "$name" + reliant-seal "$name" &>/dev/null done } diff --git a/install.sh b/install.sh index 0d3b438..0f62b34 100755 --- a/install.sh +++ b/install.sh @@ -172,9 +172,6 @@ systemctl enable shufflecake-close.service # reliant-system/tools surgeon-dissect -t varlibqubes reliant-snapshot-rw -if [ "$RELIANT_PROFILING" = "true" ]; then - reliant-profiling-patch-systemd -fi # reliant-system/qubes-sflc depmod -a "$RELIANT_KERNEL_VERSION" @@ -182,7 +179,23 @@ depmod -a "$RELIANT_KERNEL_VERSION" # reliant-system/dracut dracut --force --regenerate-all if [ "$RELIANT_PROFILING" = "true" ]; then - RELIANT_PROFILING=true dracut --force "/boot/initramfs-$RELIANT_KERNEL_VERSION.reliant-profiling.img" + # Perform the patch + reliant-profiling-patch-systemd + old=/usr/lib/systemd/systemd-volatile-root + new=/usr/lib/systemd/systemd-volatile-root.reliant-profiling + + # Switch + tmpname="/tmp/reliant.$(uuidgen)" + mv "$old" "$tmpname" + mv "$new" "$old" + + # Build + dracut --force "/boot/initramfs-$RELIANT_KERNEL_VERSION.reliant-profiling.img" + + # Switch back + rm "$old" + mv "$tmpname" "$old" + rm "$tmpname" fi # Report successful installation diff --git a/tools/reliant-mount b/tools/reliant-mount index 9bda940..4f5ad30 100755 --- a/tools/reliant-mount +++ b/tools/reliant-mount @@ -71,8 +71,12 @@ fi # Create the volume root directory under /run mkdir -m 750 /run/shufflecake -# Check if we need to e2fsck -reliant_e2fsck=$(grep -q reliant.e2fsck /proc/cmdline) +# Check if e2fsck has been enabled +if grep -q reliant.e2fsck /proc/cmdline; then + reliant_e2fsck=$RELIANT_TRUE +else + reliant_e2fsck=$RELIANT_FALSE +fi # Mount each volume find /dev/mapper -maxdepth 1 -name 'sflc_0_*' | sort | while read -r device; do @@ -83,14 +87,13 @@ find /dev/mapper -maxdepth 1 -name 'sflc_0_*' | sort | while read -r device; do name="${device##*/}" mountpoint="/run/shufflecake/$name" - # e2fsck if requested - if [ "$reliant_e2fsck" ]; then - e2fsck -p "$device" &> /dev/null || true # If the user has mixed filesystems, it will fail for some - fi - # Mount in /run/shufflecake mkdir -m 750 "$mountpoint" - mount -o ro,noatime,nodiratime "$device" "$mountpoint" &> /dev/null || true # Allow it to silently fail in case there's no filesystem or it is corrupted + if ! mount -o ro,noatime,nodiratime "$device" "$mountpoint" &>/dev/null && [ $reliant_e2fsck -eq $RELIANT_TRUE ]; then + # If e2fsck is enabled, we get a second chance + e2fsck -p "$device" &>/dev/null || true + mount -o ro,noatime,nodiratime "$device" "$mountpoint" &>/dev/null || true + fi # Apply the displayed volume limit if required if [ $dvl_required -eq $RELIANT_TRUE ] && [ "$device" = "$dvl_device" ]; then diff --git a/tools/reliant-seal b/tools/reliant-seal index c5b4fc8..70068ae 100755 --- a/tools/reliant-seal +++ b/tools/reliant-seal @@ -4,23 +4,24 @@ RED="\e[31;1m" GREEN="\e[32;1m" ENDCOLOR="\e[0m" +# Checks if [ "$#" -ne 1 ]; then echo "Expected 1 argument." exit 1 fi - if [ "$EUID" -ne 0 ]; then echo "Must be superuser." exit 1 fi - if [ ! -d /run/shufflecake ]; then echo "Running in unsafe/maintenance mode, reliant-seal not available." exit 1 fi +# Target volume name=$1 +# Shutdown qubes and remove links in /var/lib/qubes echo -n "Destroying links... " for appvm in "/run/shufflecake/$name/appvms/"*; do qube="${appvm##*/}" @@ -37,16 +38,16 @@ for appvm in "/run/shufflecake/$name/appvms/"*; do done echo "Done." -echo -n "Sealing mountpoint... " -mount -o remount,ro,noatime,nodiratime "/run/shufflecake/$name" -echo "Done." +# Idempotent unmount +if findmnt "/run/shufflecake/$name" &> /dev/null; then + echo -n "Sealing mountpoint... " + mount -o remount,ro,noatime,nodiratime "/run/shufflecake/$name" + umount "/run/shufflecake/$name" && rmdir "/run/shufflecake/$name" + echo "Done." +fi echo -n "Sealing device... " blockdev --setro "/dev/mapper/$name" echo "Done." -echo -n "Unmounting device... " -umount "/run/shufflecake/$name" && rmdir "/run/shufflecake/$name" -echo "Done." - echo -e "${GREEN}Sealed.${ENDCOLOR} See reliant-status for more information." diff --git a/tools/reliant-unseal b/tools/reliant-unseal index 594276f..f6d06d8 100755 --- a/tools/reliant-unseal +++ b/tools/reliant-unseal @@ -1,34 +1,54 @@ #!/usr/bin/bash -#TODO: check status, report if other volumes are already unsealed set -euo pipefail RED="\e[31;1m" GREEN="\e[32;1m" ENDCOLOR="\e[0m" +# Checks if [ "$#" -lt 1 ]; then echo "Expected at least 1 argument." exit 1 fi - if [ "$EUID" -ne 0 ]; then echo "Must be superuser." exit 1 fi - if [ ! -d /run/shufflecake ]; then echo "Running in unsafe/maintenance mode, reliant-unseal not available." exit 1 fi +# Target volume name=$1 device="/dev/mapper/$name" +# Future proposal for RELIANT_PARANOID +# Check if other volumes are unsealed +# unsealed_present=0 +# for current_device in /dev/mapper/sflc_0_*; do +# if [ "$current_device" != "$device" ] && [ "$(blockdev --getro "$current_device")" -eq 0 ]; then +# unsealed_present=1 +# fi +#done +#if [ $unsealed_present -eq 1 ]; then +# read -r -p "[WARN]: Other volumes are already unsealed. Proceed? [Y/N]: " +# if [[ ! $REPLY =~ ^[Yy] ]]; then +# echo "Aborted." +# exit 0 +# fi +#fi + echo -n "Unsealing device... " blockdev --setrw "$device" echo "Done." +# Idempotent mount +mount_options="rw,noatime,nodiratime" +if findmnt "/run/shufflecake/$name" &> /dev/null; then + mount_options="remount,$mount_options" +fi echo -n "Unsealing mountpoint... " -mount -o rw,noatime,nodiratime --mkdir=0750 "$device" "/run/shufflecake/$name" +mount -o "$mount_options" --mkdir=0750 "$device" "/run/shufflecake/$name" echo "Done." # Check if we were given a qube list @@ -39,6 +59,7 @@ else allowed_only=1 fi +# Load the app menu shortcuts, firewall rules, etc. echo "Creating links... " for appvm in "/run/shufflecake/$name/appvms/"*; do qube="${appvm##*/}"