profiling requires patching systemd during initramfs build; remove runtime profiling option

This commit is contained in:
Anderson Rosenberg 2025-10-22 19:01:39 -04:00
parent 501d68bf7e
commit 4ac936df5b
No known key found for this signature in database
GPG key ID: 7ACF448C0590AB9C
6 changed files with 65 additions and 24 deletions

View file

@ -98,7 +98,6 @@ Due to potential security implications of arbitrary code execution (firewall.rul
- `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.profile` mounts the upperdir and workdir of OverlayFS in an accessible location under /run/reliant for debugging purposes
- `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

View file

@ -33,11 +33,17 @@ install() {
inst_script /usr/local/sbin/surgeon-suture
inst_script /usr/local/sbin/reliant-mount
inst_script /usr/local/sbin/reliant-hash
inst_script /usr/local/sbin/reliant-seal
inst /etc/reliant.conf
# Other binaries
inst_multiple dmesg lsblk blockdev mount dd wc sed sleep md5sum find modprobe cut grep mkdir rm tail
inst_multiple dmesg lsblk blockdev mount dd wc sed sort sleep md5sum find modprobe cut grep mkdir rm tail
# Optional profiling
if [ "$RELIANT_PROFILING" = "true" ]; then
inst /usr/lib/systemd/systemd-volatile-root.reliant-profiling /usr/lib/systemd/systemd-volatile-root
fi
return 0
}

View file

@ -12,6 +12,7 @@ if [ ! "$HOSTNAME" = "dom0" ]; then
fi
# Set up the defaults
: "${RELIANT_PROFILING=false}"
: "${RELIANT_PARANOID=false}"
: "${RELIANT_BIN_DIR:=/usr/local/bin}"
: "${RELIANT_SBIN_DIR:=/usr/local/sbin}"
@ -54,6 +55,14 @@ case "$RELIANT_PARANOID" in
exit 1 ;;
esac
# RELIANT_PROFILING must be a boolean value
case "$RELIANT_PROFILING" in
"true") ;;
"false") ;;
*) echo "[ERROR]: RELIANT_PROFILING: $RELIANT_PROFILING is not a valid boolean value"
exit 1 ;;
esac
# RELIANT_SPARSE_SAMPLES must be an integer
if ! [ "$RELIANT_SPARSE_SAMPLES" -eq "$RELIANT_SPARSE_SAMPLES" ] 2>/dev/null; then
echo "[ERROR]: RELIANT_SPARSE_SAMPLES: $RELIANT_SPARSE_SAMPLES is not a valid integer"
@ -114,6 +123,7 @@ reliant_install_sbin tools/surgeon-dissect surgeon-dissect 0744 root root
reliant_install_sbin tools/reliant-security reliant-security 0744 root root
reliant_install_sbin tools/reliant-snapshot-rw reliant-snapshot-rw 0744 root root
reliant_install_bin tools/reliant-print-config reliant-print-config 0755 root root
reliant_install_sbin tools/reliant-profiling-patch-systemd reliant-profiling-patch-systemd 0744 root root
# reliant-system/dracut
reliant_install_dracut dracut/99reliant/module-setup.sh module-setup.sh 0744 root root
@ -162,12 +172,18 @@ 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"
# 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"
fi
# Report successful installation
echo "[INFO]: Installation complete. Reboot to enter Protected Mode."

View file

@ -34,7 +34,7 @@ while true; do
done
# Check for the displayed volume limit in commandline arguments
# This is only useful when booting in public to hide deniable qubes
# This is useful when booting in public to hide deniable qubes from the menu
dvl_required=$RELIANT_FALSE
for argument in $(cat /proc/cmdline); do
if [[ "$argument" == reliant.dvl=* ]]; then
@ -44,7 +44,7 @@ for argument in $(cat /proc/cmdline); do
done
# Set the displayed volume limit
if [ -n "$dvl_id" ]; then
if [ $dvl_required -eq $RELIANT_TRUE ]; then
dvl_device="/dev/mapper/sflc_0_$dvl_id"
# Notify the user so they know the limit has been detected
@ -58,7 +58,7 @@ if [ -n "$dvl_id" ]; then
dvl_device="/dev/mapper/sflc_0_$dvl_id"
# Validate user input
if [ -b $dvl_device ]; then
if [ -b "$dvl_device" ]; then
plymouth display-message --text="Limit adjusted successfully"
sleep 1
plymouth hide-message --text="Limit adjusted successfully"
@ -75,10 +75,10 @@ mkdir -m 750 /run/shufflecake
reliant_e2fsck=$(grep -q reliant.e2fsck /proc/cmdline)
# Mount each volume
find /dev/mapper -maxdepth 1 -name 'sflc_0_*' | while read -r device; do
find /dev/mapper -maxdepth 1 -name 'sflc_0_*' | sort | while read -r device; do
# IMPORTANT: Seal it
blockdev --setro "$device" || exit 1
# Determine the name and mountpoint
name="${device##*/}"
mountpoint="/run/shufflecake/$name"
@ -93,7 +93,7 @@ find /dev/mapper -maxdepth 1 -name 'sflc_0_*' | while read -r device; do
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
# Apply the displayed volume limit if required
if [ $dvl_required = $RELIANT_TRUE ] && [ "$device" = "$dvl_device" ]; then
if [ $dvl_required -eq $RELIANT_TRUE ] && [ "$device" = "$dvl_device" ]; then
break
fi
done
@ -105,17 +105,3 @@ for path in '/sysroot/var/lib/qubes/appvms/'*; do
name="${path##*/}"
mkdir -m 750 "/run/volatile/appvms/$name"
done
# Check if we need to set up profiling
if grep -q reliant.profile /proc/cmdline; then
mkdir -m 750 /run/reliant
mkdir -m 750 /run/reliant/profile
# Upperdir
mkdir -m 750 /run/reliant/profile/upper
mount --bind /run/systemd/overlay-sysroot/upper /run/reliant/profile/upper
# Workdir
mkdir -m 750 /run/reliant/profile/work
mount --bind /run/systemd/overlay-sysroot/work /run/reliant/profile/work
fi

View file

@ -0,0 +1,24 @@
#!/usr/bin/sh
# Create a new file to be patched
binary=/usr/lib/systemd/systemd-volatile-root
target=/usr/lib/systemd/systemd-volatile-root.reliant-profiling
cp $binary $target
# We must NOP calls to umount and rmdir
hex_offsets=$(objdump -d "$binary" | grep -E 'call.*(umount|rmdir)' | awk '{ print $1 }' | tr -d ':')
for hex_offset in $hex_offsets; do
dec_offset=$(perl -le "print hex(\"$hex_offset\")")
printf '\x90\x90\x90\x90\x90' | dd of="$target" bs=1 seek=$dec_offset conv=notrunc
done
# Verify the patch has succeeded
for hex_offset in $hex_offsets; do
echo -n "$hex_offset: "
opcode=$(objdump -d "$target" | grep $hex_offset | awk '{ print $3 }')
if [ $opcode -eq 90 ]; then
echo "OK"
else
echo "FAIL"
fi
done

View file

@ -34,13 +34,18 @@ echo "Done."
# Check if we were given a qube list
allowed_qubes="${*:2}"
if [ -z "$allowed_qubes" ]; then
allowed_only=0
else
allowed_only=1
fi
echo "Creating links... "
for appvm in "/run/shufflecake/$name/appvms/"*; do
qube="${appvm##*/}"
# Filter if user provided a list of qubes
if [ ! -z "$allowed_qubes" ]; then
if [ $allowed_only -eq 1 ]; then
allowed=0
for allowed_qube in $allowed_qubes; do
if [ "$qube" = "$allowed_qube" ]; then
@ -64,8 +69,13 @@ for appvm in "/run/shufflecake/$name/appvms/"*; do
# App menus
su user -c "qvm-start $qube" &>/dev/null || true
su user -c "qvm-sync-appmenus $qube" &>/dev/null || true
su user -c "qvm-shutdown $qube" &>/dev/null || true
# If we have a list of allowed qubes, the user probably wants to run them anyway
# Otherwise, shut them down
if [ $allowed_only -eq 0 ]; then
su user -c "qvm-shutdown $qube" &>/dev/null || true
fi
# Firewall rules
if [ -f "$appvm/firewall.rules" ]; then
echo "Found firewall.rules. Approve?"