diff --git a/Buildroot/board/FOG/FOS/rootfs_overlay/usr/share/fog/lib/funcs.sh b/Buildroot/board/FOG/FOS/rootfs_overlay/usr/share/fog/lib/funcs.sh index 609a9e2..5ec5636 100644 --- a/Buildroot/board/FOG/FOS/rootfs_overlay/usr/share/fog/lib/funcs.sh +++ b/Buildroot/board/FOG/FOS/rootfs_overlay/usr/share/fog/lib/funcs.sh @@ -2532,7 +2532,7 @@ wipeDisk() { echo " *** WARNING: $disk is a solid-state device (class: $class) ***" echo " Overwriting an SSD is NOT a guaranteed erase: wear levelling and" echo " over-provisioning keep copies of your data in blocks that no" - echo " overwrite can address. Data may remain recoverable afterwards." + echo " overwrite can address. Data may remain recoverable afterward." echo " Use the drive's own secure erase (ATA sanitize/secure erase) for a" echo " guaranteed wipe of this device." echo "" diff --git a/docs/adr/0009-secure-boot-enrolment-paths.md b/docs/adr/0009-secure-boot-enrolment-paths.md index 3a4b6dc..276fb8c 100644 --- a/docs/adr/0009-secure-boot-enrolment-paths.md +++ b/docs/adr/0009-secure-boot-enrolment-paths.md @@ -99,7 +99,7 @@ Could not boot: Error 0x7f04819a ``` **iPXE verifies the kernel *and* the initrd through shim.** The signed chain -loads fine right up to the point where FOG's own artefacts are checked against a +loads fine right up to the point where FOG's own artifacts are checked against a MokList that does not yet contain FOG's certificate, and both are refused. So FOS can never be the thing that establishes trust in FOG's key on a machine @@ -215,7 +215,7 @@ one. Its honest scope is: **machines that currently have Secure Boot off and are going to have it turned on.** That is a real and common case — plenty of sites disable Secure Boot precisely so -they can use FOG, and want it back on afterwards. There, the task stages the key +they can use FOG, and want it back on afterward. There, the task stages the key with no USB media, no live image and no fingerprint transcription, and the tech confirms once at MokManager. That is a genuine improvement on the USB kit for that case, and nothing more. @@ -344,7 +344,7 @@ it current. **Path 1 validated end to end on 2026-08-03** (VirtualBox 7.2 EFI, platform keys cleared to enter Setup Mode). The task enrolled with nobody at the keyboard, and -the firmware afterwards held exactly what it should: +the firmware afterward held exactly what it should: - `db` — Microsoft's five db CAs plus FOG's signing certificate - `KEK` — Microsoft's two KEK CAs plus this server's KEK diff --git a/tests/README.md b/tests/README.md index 0973b7f..f521e01 100644 --- a/tests/README.md +++ b/tests/README.md @@ -192,6 +192,14 @@ tests/checks/package-mirrors.sh # drops the superseded lines, a failed download # restores the .mk rather than leaving a half-bump, # and --dry-run writes nothing +tests/checks/us-spelling.sh # FOS's own source carries US spellings. A + # whole-tree scan rather than a diff, because a + # diff-scoped check needs a base ref a shallow + # clone does not have -- and would then pass for a + # reason unrelated to spelling, silently. Two + # patterns: word/camelCase, and ALL CAPS with a + # tighter right edge, so the five-letter UK form + # does not fire inside ENROLL_SECUREBOOT ``` Like the golden harness, the library harnesses source a sandbox copy of the diff --git a/tests/checks/us-spelling.sh b/tests/checks/us-spelling.sh new file mode 100755 index 0000000..b91f64d --- /dev/null +++ b/tests/checks/us-spelling.sh @@ -0,0 +1,164 @@ +#!/bin/bash +# +# Gate: FOS's own source carries US spellings. +# +# tests/checks/us-spelling.sh # exit non-zero on any UK spelling in scope +# +# Tom asked for US spellings throughout. The tree was swept once (#168); this is +# what stops it drifting back, one echo line at a time, the way it drifted in. +# It matters more here than in most repos because these strings are read off a +# screen by a technician standing at a machine mid-enrollment. +# +# WHY A WHOLE-TREE SCAN RATHER THAN A DIFF +# +# The obvious shape is "check only the lines this pull request adds". It needs a +# base ref, and a shallow clone has no merge-base -- so the check would find +# nothing to look at and pass, for a reason that has nothing to do with +# spelling, silently and forever. A gate that can only report success is worse +# than no gate, because it also reports "verified". Scanning the whole tree +# needs no ref and cannot skip, and is only possible because the sweep already +# made the tree clean. +# +# Mirrors fogproject's tests/us-spelling.test.php, including the word list and +# the two-pattern boundary handling. Keep them in step. + +HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ROOT="$(cd "$HERE/../.." && pwd)" + +# FOS's own source. Buildroot's vendored tree is out -- upstream's spellings are +# not ours to correct. +SCOPE=( + Buildroot/board/FOG/FOS/rootfs_overlay + tests + docs + README.md +) + +# Read by a machine or by another repository, so the UK spelling is load +# bearing. Blanked out of the line before the words below are looked for. +ALLOWED=( + # Three files here and one in fogproject reference this ADR by name. + '0009-secure-boot-enrolment-paths' +) + +# An explicit list, not a blanket -ise -> -ize rule: advertise, exercise, +# surprise and otherwise are -ise in both dialects. `enrolled` and `enrolling` +# are absent on purpose -- both dialects double the l there. +UK=( + enrolment enrolments enrol enrols + recognise recognised recognises recognising recognisable unrecognised + normalise normalised normalises normalising normalisation normaliser + behaviour behaviours behavioural + colour colours coloured colouring + cancelled cancelling + labelled labelling relabelled relabelling unlabelled signalling + modelled travelled + catalogue licence centre centres + neighbour neighbours neighbouring + initialise initialised initialises initialisation initialiser + authorise authorised authorisation + serialise serialised serialising + organise organised organising organisation + minimise minimised maximise maximised optimise optimised + utilise utilised utilising prioritise summarise summarised + specialise specialised + favour favours favourable + defence offence fulfil whilst + grey greyed + analyse analysed analyses analyser + afterwards towards amongst + judgement judgements ageing + artefact artefacts programme programmes +) + +# Lookbehind is required for the boundary rules below, so this needs PCRE. +# Refuses rather than degrading to a weaker pattern: a check that quietly +# matches less is the failure this file exists to prevent. +if ! echo x | grep -qP 'x' 2>/dev/null; then + printf 'FAIL: grep has no -P (PCRE) support; cannot run this check.\n' >&2 + exit 1 +fi + +# git ls-files --cached --others --exclude-standard, not a find: tracked files, +# plus new ones a developer has written but not staged, minus anything ignored. +mapfile -t files < <(git -C "$ROOT" ls-files --cached --others --exclude-standard -- "${SCOPE[@]}" 2>/dev/null) + +# Per SCOPE entry, not just a total. git exits 0 quite happily on a checkout +# where a path has moved or where an ignore rule now swallows it, and the result +# would be "0 file(s) scanned, no UK spellings in scope" -- green, and +# meaningless. A total still passes when one directory of the four drops out, so +# the floor is per path. +empty=() +for want in "${SCOPE[@]}"; do + found=0 + for f in "${files[@]}"; do + if [[ $f == "$want" || $f == "$want"/* ]]; then + found=1 + break + fi + done + [[ $found -eq 0 ]] && empty+=("$want") +done +if [[ ${#empty[@]} -gt 0 ]]; then + printf 'FAIL: these scope paths matched no files -- moved, renamed or\n' >&2 + printf 'newly ignored? Fix SCOPE; do not delete the entry to go green.\n' >&2 + printf ' %s\n' "${empty[@]}" >&2 + exit 1 +fi + +# Two patterns, because one right-hand boundary cannot serve both shapes. +# +# WORD/camelCase -- lower or Title case. Left edge is "not preceded by a letter, +# OR on a camelCase hump". Right edge is "not followed by a lower-case letter", +# which keeps `enrol` from firing inside `enrolled` and `enrollment`. +# +# ALL CAPS -- for shell constants. Here the right edge must reject an upper-case +# letter too, or `ENROL` matches inside `ENROLL_SECUREBOOT` and the check fails +# on a correctly spelled name. `ENROLMENT_MODE` still matches: `_` is not a +# letter. +# +# Both are case-SENSITIVE. Adding -i would also fold the [a-z]/[A-Z] in the +# boundary assertions, collapsing the camelCase hump into "letter, letter" -- +# i.e. no boundary at all. +cased='' +upper='' +for w in "${UK[@]}"; do + cased="${cased}|${w^}|${w}" + upper="${upper}|${w^^}" +done +cased="${cased#|}" +upper="${upper#|}" +P_WORD="(?:(?/dev/null || continue + scanned=$((scanned + 1)) + while IFS= read -r hit; do + [[ -z $hit ]] && continue + printf '%s:%s\n' "$f" "$hit" + problems=$((problems + 1)) + done < <(sed "$sedscript" "$path" 2>/dev/null | grep -nP -o "$P_WORD|$P_CAPS" 2>/dev/null) +done + +if [[ $problems -gt 0 ]]; then + printf '\nFAIL: %d UK spelling(s) in scope.\n' "$problems" >&2 + printf 'Use the US form. If a machine reads the string and the UK spelling\n' >&2 + printf 'is load bearing, add it to ALLOWED above with the reason -- do not\n' >&2 + printf 'remove the word from UK.\n' >&2 + exit 1 +fi + +printf 'us-spelling: %d file(s) scanned, no UK spellings in scope\n' "$scanned" diff --git a/tests/checks/wipe.sh b/tests/checks/wipe.sh index c80aa95..03e8faa 100755 --- a/tests/checks/wipe.sh +++ b/tests/checks/wipe.sh @@ -239,7 +239,7 @@ run_case "nvme full, sanitize completes with forced dealloc -> ok" /dev/nvme0n1 # 8b. A confirmed sanitize must never be followed by a format. The drive is # already erased; the only reason to issue one would be a misread log. new_case; FAKE_SANICAP=2; FAKE_SSTAT_SEQ="2 2 1" -run_case "nvme full, sanitize completes -> no format afterwards" /dev/nvme0n1 full ok "" "format" +run_case "nvme full, sanitize completes -> no format afterward" /dev/nvme0n1 full ok "" "format" # 9. Unreadable sanitize log AFTER the sanitize started. The regression this # harness missed: the log parse failed on the first poll, the code called that