diff options
| author | Craig Jennings <c@cjennings.net> | 2026-04-27 13:00:26 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-04-27 13:00:26 -0500 |
| commit | 26f3f823ac17940a1b0153619f6140f45d856e33 (patch) | |
| tree | bdb02b6fc0c110ce6e59ffd379521068a446c45a /installer | |
| parent | 8c69aaaff13da3b7d1d24ed34975e8c5b30409e6 (diff) | |
| download | archangel-26f3f823ac17940a1b0153619f6140f45d856e33.tar.gz archangel-26f3f823ac17940a1b0153619f6140f45d856e33.zip | |
refactor: verify GRUB_CMDLINE_LINUX seds via prepend_grub_cmdline_linux helper
Audited the ~10 silent sed -i sites in the installer against the verification-after pattern that landed for sshd_config last session. Triaged each by failure mode.
The two GRUB_CMDLINE_LINUX seds in lib/btrfs.sh have a real silent-failure risk. If /etc/default/grub is missing or malformed and the sed pattern doesn't match, nothing happens. The kernel boots without cryptdevice=. The system can't unlock LUKS at boot. Added prepend_grub_cmdline_linux to lib/common.sh. Same shape as enable_sshd_root_login (sed, then grep, then error if the line wasn't modified). Replaced the two inline seds with helper calls.
The HOOKS= seds in installer/archangel and lib/btrfs.sh (six total) don't need verification. A missing HOOKS= line makes mkinitcpio -P fail loudly downstream, so silent-replace failure can't reach a booted system. Added a one-line audit-rationale comment at each of the three locations so the next reader doesn't re-litigate the decision.
The FILES= sed at lib/btrfs.sh:213 already self-heals via a sed-then-grep-then-append pattern, so no behavior change there. Filed a separate follow-up to lift that pattern into a named helper for clarity.
Bats: 142 → 146. Four new tests in test_common.bats cover normal (empty cmdline, existing cmdline preserved, other lines preserved) and error (missing GRUB_CMDLINE_LINUX line). Lint clean.
Diffstat (limited to 'installer')
| -rwxr-xr-x | installer/archangel | 3 | ||||
| -rw-r--r-- | installer/lib/btrfs.sh | 11 | ||||
| -rw-r--r-- | installer/lib/common.sh | 18 |
3 files changed, 30 insertions, 2 deletions
diff --git a/installer/archangel b/installer/archangel index 12f1cd0..479b53a 100755 --- a/installer/archangel +++ b/installer/archangel @@ -896,6 +896,9 @@ EOF # This ensures NVMe, AHCI, and other storage drivers are always included # - Remove fsck: ZFS doesn't use it, avoids confusing error messages # - Add zfs: required for ZFS root boot + # No sed verification needed: a missing HOOKS= line makes mkinitcpio -P + # fail loudly downstream, so silent-replace failure can't reach a booted + # system. (Audited 2026-04-27 against silent-sed pattern.) sed -i 's/^HOOKS=.*/HOOKS=(base udev microcode modconf kms keyboard keymap consolefont block zfs filesystems)/' /mnt/etc/mkinitcpio.conf # Get the installed kernel version (not the running kernel) diff --git a/installer/lib/btrfs.sh b/installer/lib/btrfs.sh index 09127b2..f704fd7 100644 --- a/installer/lib/btrfs.sh +++ b/installer/lib/btrfs.sh @@ -204,6 +204,8 @@ configure_luks_initramfs() { # Add encrypt hook before filesystems (configure_btrfs_initramfs overwrites # this with the final hook list, using sd-encrypt for multi-disk setups) + # No sed verification needed: a missing HOOKS= line makes mkinitcpio -P + # fail loudly downstream. (Audited 2026-04-27 against silent-sed pattern.) sed -i 's/^HOOKS=.*/HOOKS=(base udev microcode modconf kms keyboard keymap consolefont block encrypt filesystems fsck)/' \ /mnt/etc/mkinitcpio.conf @@ -247,7 +249,8 @@ configure_luks_grub() { info "Testing mode: adding cryptkey parameter for automated unlock" fi - sed -i "s|^GRUB_CMDLINE_LINUX=\"|GRUB_CMDLINE_LINUX=\"cryptdevice=UUID=$uuid:$LUKS_MAPPER_NAME:allow-discards ${cryptkey_param}|" \ + prepend_grub_cmdline_linux \ + "cryptdevice=UUID=$uuid:$LUKS_MAPPER_NAME:allow-discards ${cryptkey_param}" \ /mnt/etc/default/grub info "GRUB configured with cryptdevice parameter and cryptodisk enabled." @@ -613,7 +616,8 @@ EOF cryptkey_param="cryptkey=rootfs:$LUKS_KEYFILE " info "Testing mode: adding cryptkey parameter for automated unlock" fi - sed -i "s|^GRUB_CMDLINE_LINUX=\"|GRUB_CMDLINE_LINUX=\"cryptdevice=UUID=$uuid:$LUKS_MAPPER_NAME:allow-discards ${cryptkey_param}|" \ + prepend_grub_cmdline_linux \ + "cryptdevice=UUID=$uuid:$LUKS_MAPPER_NAME:allow-discards ${cryptkey_param}" \ /mnt/etc/default/grub info "Added cryptdevice parameter for LUKS partition." fi @@ -844,6 +848,9 @@ EOF # Configure hooks for btrfs # Include encrypt hook if LUKS is enabled, btrfs hook if multi-device + # No sed verification needed on the four HOOKS= seds below: a missing + # HOOKS= line makes mkinitcpio -P fail loudly downstream. (Audited + # 2026-04-27 against silent-sed pattern.) local num_disks=${#SELECTED_DISKS[@]} local luks_enabled="no" [[ "$NO_ENCRYPT" != "yes" && -n "$LUKS_PASSPHRASE" ]] && luks_enabled="yes" diff --git a/installer/lib/common.sh b/installer/lib/common.sh index 3040799..dfeb245 100644 --- a/installer/lib/common.sh +++ b/installer/lib/common.sh @@ -302,3 +302,21 @@ enable_sshd_root_login() { grep -q '^PermitRootLogin yes$' "$config_file" \ || error "PermitRootLogin not set in $config_file (no matching line to replace)" } + +############################# +# GRUB Configuration +############################# + +# Prepend a string just inside the GRUB_CMDLINE_LINUX="..." quotes in +# /etc/default/grub. Errors if the line isn't present in the file. +# Silently doing nothing here would leave the kernel without the +# parameter — for cryptdevice= that means the system can't unlock the +# root partition at boot, so we want a loud failure during install +# rather than an unbootable system after first reboot. +prepend_grub_cmdline_linux() { + local addition="$1" + local config_file="$2" + sed -i "s|^GRUB_CMDLINE_LINUX=\"|GRUB_CMDLINE_LINUX=\"${addition}|" "$config_file" + grep -qF "GRUB_CMDLINE_LINUX=\"${addition}" "$config_file" \ + || error "GRUB_CMDLINE_LINUX not modified in $config_file (line missing or pattern unmatched)" +} |
