Five bugs from the 2026-09-21 audit: diag execute bit, dead fstab branch, chroot on stdin, a lying summary line, a pin for every prompt - #1
Merged
Conversation
…nch, chroot on stdin, a summary line that lied, and a pin for every prompt 1. bin/linuxlocker-diag.sh shipped as 100644. linuxlocker.sh exec's it and every document says `sudo ./bin/linuxlocker-diag.sh`; both failed with permission denied. The bug-report tool could not be run to report a bug. 2. The fstab device-path branch (stage 6b) looked for the partition name AFTER the mountpoint. On a real line the device comes first, so `/dev/nvme0n1p3 / ext4 ...` never matched and fell through to the "neither UUID nor PARTUUID found" failure. The sed on the next line was right all along; only the gate was wrong. 3. The chroot phase was a 27 KB here-document on bash's stdin. Under the 64 KB pipe buffer, bash 5.1+ delivers it through a pipe and reads it unbuffered so children can share stdin — so any child that reads stdin (a hook that asks, a debconf prompt) swallows the rest of the script and the phase ends early with a clean exit code, skipping the UKI rebuild, signing and relabel. Reproduced: a script whose tail exits 5 returned 0 after one `cat`. The phase is now written to /tmp/.luks-chroot.sh on the target and run with stdin from /dev/null. 4. The final summary printed "GRUB_ENABLE_CRYPTODISK=y", which stage 6c deliberately never writes. It now states what was actually done. 5. The README said every prompt has a LUKS_* variable behind it; 27 prompts existed and only a handful were pinnable, and without a terminal a bare `read` died under set -e with no message. Every prompt now goes through ask(): a pinned value answers it and is logged; no pin and no terminal stops the run and names the variable. New pins: LUKS_CONFIRM (ENCRYPT|CONFIGURE|CONVERT, mismatch fatal), LUKS_STALE_MAPPER, LUKS_LIVE_OVERRIDE, LUKS_BATTERY_OVERRIDE, LUKS_UNMOUNT, LUKS_RESUME, LUKS_EXISTING, LUKS_DATA_PARTITION, LUKS_MISMATCH_OVERRIDE, LUKS_CROSS_DISK, LUKS_SUBVOL_MISMATCH, LUKS_FSCK, LUKS_FSCK_FORCE, LUKS_ALREADY_SHRUNK; LUKS_PROFILE (plus 'skip') also answers the re-costing menu after a LUKS1 conversion. The inner-UUID-changed override keeps no pin on purpose. README documents all of it, and the Audit section records this pass. All three suites pass: cmdline 71/0, uki 41/0, loopback 44/0 (as root). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…in, and the README could be read otherwise The 'skip' choice after a LUKS1 conversion was worded as "keep pbkdf2", and the new LUKS_PROFILE=skip pin repeated it. pbkdf2 is a plain for loop over a hash — no memory cost, every GPU core runs its own copy — and LinuxLocker never writes it, never offers it, and does not treat a keyslot left on it as hardened. The menu now says "defer the re-costing" with that explanation under it, a deferred re-costing ends with a warning that the volume is not hardened yet, the dry-run line for a GRUB without argon2 says the same, and the README FAQ states it in bold with the for-loop reason. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…one — with cosmic time A new subsection under the BitLocker/FileVault comparison: the loop written out in four lines, the year it was standardized against the GPU of that year, why N buys nothing against sixteen thousand cores, and what each company put in front of its loop instead of replacing it. Ends with the cosmic-era table from luks-tune.sh's own model, run over all three functions with published RTX 4090 hashcat rates for the two loops. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…SHA-256 versus argon2id's bill for DRAM BitLocker's chain and FileVault's PBKDF2 are built on SHA-256, the one hash with a zettahash per second of purpose-built silicon already running. The network's 1,000 EH/s and one Antminer S21 XP's 270 TH/s are worked through the same cosmic-time model: six diceware words fall in 2.5 years and 72 days respectively. argon2id at 4 GiB is bounded by DRAM bandwidth and capacity, which no ASIC discounts; a generous thousand-part memory-bound farm still leaves six words past the age of the universe. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this fixes
Five bugs found in a full read of v1.6.0 by Claude Fable 5.1, each reproduced before it was fixed.
bin/linuxlocker-diag.shwas mode 100644;linuxlocker.sh diagexec's it and every document sayssudo ./bin/linuxlocker-diag.sh. Both failed with permission denied.bin/linuxlocker-diag.sh/dev/nvme0n1p3 / ext4 …line never matched, so it fell through to the "neither UUID nor PARTUUID" failure. The sed after it was already right.bin/luks-deploy.sh, stage 6b/cat.bin/luks-deploy.sh, step 7/tmp/.luks-chroot.shon the target, run with</dev/null, removed after and in the trapGRUB_ENABLE_CRYPTODISK=y, which stage 6c deliberately never writes.bin/luks-deploy.sh, summaryLUKS_*variable behind it". 27 prompts, a handful pinnable; without a terminal a barereaddied underset -ewith no message.bin/luks-deploy.sh,README.mdask()helper: a pin answers and is logged; no pin and no terminal stops the run and names the variable. 14 new pins, documented in the script header and READMEThe inner-UUID-changed override keeps no pin on purpose: that state means the wrong device is open, and no fleet should answer it blind.
Verification
bash -nandshellcheck -S warningclean on every scripttests/cmdline-fixture-test.sh: 71 passed, 0 failedtests/uki-fixture-test.sh: 41 passed, 0 failed, 1 skippedtests/loopback-core-test.shas root: 44 passed, 0 failedask()checked in isolation: a pinned value is taken and logged; with no pin and no terminal the run stops naming the variable/dev/X / …and ignores/dev/X /home …Not in this PR
The audit also named three design gaps that are recorded in the README's Audit section and left open here: an end-to-end boot of the Fedora, Ubuntu and Arch GRUB paths, a console-keymap check for the initramfs, and
sgdiskin the dependency map. No version bump; that is the maintainer's call.🤖 Generated with Claude Code