From 1d51b23e945bf3dd8209a962ba1b8de57083c22f Mon Sep 17 00:00:00 2001 From: sdolbec Date: Thu, 29 Oct 2026 11:10:46 -0400 Subject: [PATCH] Aurora wip5: J314S install record, working staging script, Touch ID guard-off plan wip5 boots on the J314S. Records how: the initramfs must be the working Arch mkinitcpio image retargeted with prepare-trial-initrd.py (mkinitramfs ignores cryptdevice= and died before the passphrase prompt on the first try). Adds stage-wip5.sh doing exactly that, the graphical-unlock (splash) note, and touchid-guard-off.sh: verified dd backup of the xART container and Apple NVMe namespaces, then a separate xart_guard=0 entry. TOUCH-ID-STATE.md points at it. Co-Authored-By: Claude Opus 5.5 --- mseries/aurora-sep/TOUCH-ID-STATE.md | 7 +++ mseries/aurora/unified72/wip5/README.md | 63 +++++++++++++++++++ mseries/aurora/unified72/wip5/stage-wip5.sh | 63 +++++++++++++++++++ .../unified72/wip5/touchid-guard-off.sh | 45 +++++++++++++ 4 files changed, 178 insertions(+) create mode 100644 mseries/aurora/unified72/wip5/README.md create mode 100755 mseries/aurora/unified72/wip5/stage-wip5.sh create mode 100755 mseries/aurora/unified72/wip5/touchid-guard-off.sh diff --git a/mseries/aurora-sep/TOUCH-ID-STATE.md b/mseries/aurora-sep/TOUCH-ID-STATE.md index cc755e467..9c93b132c 100644 --- a/mseries/aurora-sep/TOUCH-ID-STATE.md +++ b/mseries/aurora-sep/TOUCH-ID-STATE.md @@ -3,6 +3,13 @@ One page of where each layer stands, with the evidence. Update it when something changes; details live in [XART-GUARD.md](XART-GUARD.md) and [UPSTREAM-MAP.md](UPSTREAM-MAP.md). +## Update 2026-10-29: wip5 + +On `7.2.11-elementary-aurora72-wip5` (guard 1) the enclave matches the enrolled finger (fprintd: `#0: right-index-finger`), but +the host refuses the kind-4 rewrite after the match, so `fprintd-verify` fails every time. The owner chose to test the guard off +with a backup first: [../aurora/unified72/wip5/README.md](../aurora/unified72/wip5/README.md) (xART backup + separate +`elementary-aurora72-wip5-xartguard-off-trial` entry; then check macOS Touch ID). Results go there and here. + ## Machine MacBook Pro 14" (M1 Pro, 2021), `apple,j314s` / `apple,t6000`, `asahi,os-fw-version` 13.5, diff --git a/mseries/aurora/unified72/wip5/README.md b/mseries/aurora/unified72/wip5/README.md new file mode 100644 index 000000000..b5e41a4d3 --- /dev/null +++ b/mseries/aurora/unified72/wip5/README.md @@ -0,0 +1,63 @@ +# Aurora 7.2 wip5 on the J314S (M1 Pro 14"): install record, 2026-10-29 + +This page lets the laptop be rebuilt without this session's notes. wip5 is unified72 revision 7: omacom/linux-aurora +`2f725546` (7.2.11) with patches 0001–0005 (PR #698), built in CI run 40866985442. The package is +`linux-image-elementary-aurora72-wip5_7.2.11+elementary.aurora72.wip5-1_arm64.deb`, sha256 `658746f5…ace62` (CI `SHA256SUMS`). + +## Result + +- **Boots** (first good boot 2026-10-29 10:58 EDT). Working: internal panel, external DP monitor, GPU (asahi), Wi-Fi, the six + tas2764 speaker amps (they log "Failed to parse devicetree" on the first probe and bind on the retry), cs42l84, SEP driver. +- No new kernel errors against wip4, apart from three `apple-dcp … Failed to get dp-phy: -517` probe deferrals. +- Not yet checked by the owner: dock replug, suspend and resume. +- wip4 stays the GRUB default. wip5 is the entry `elementary-aurora72-wip5-trial`. + +## How to install it (the way that works) + +```bash +sudo bash mseries/aurora/unified72/wip5/stage-wip5.sh ~/.cache/mseries-kernel/wip5/linux-image-elementary-aurora72-wip5_7.2.11+elementary.aurora72.wip5-1_arm64.deb +sudo grub-reboot elementary-aurora72-wip5-trial && sudo reboot +``` + +`stage-wip5.sh` installs the package, copies `vmlinuz`, and builds the initramfs by **retargeting the working wip4 one** +with `mseries/aurora/prepare-trial-initrd.py`, then audits it with `audit-trial-initrd.py`. The audit checks that the early +archive and every non-module entry are unchanged and that all 91 modules match the package. Last, it copies the wip4 GRUB +entry as a TRIAL entry. + +**Why not mkinitramfs:** the J314S boots an Arch mkinitcpio initramfs. The kernel line carries `cryptdevice=`, and the image's +hooks are `base asahi udev … encrypt`, with plymouth. initramfs-tools ignores `cryptdevice=`. The first wip5 staging +used `mkinitramfs` and died before the passphrase prompt on every boot, leaving no journal. mkinitcpio itself is not +installed on this machine, so retargeting is the only path. + +## Graphical unlock screen + +The initramfs already has plymouth with the elementary theme, and the `encrypt` hook asks through `plymouth ask-for-password`. +The trial entries boot with `loglevel=7` and no `splash`, so the prompt is plain text with no cue. To get the graphical prompt +on the wip5 entry only: + +```bash +sudo cp /boot/grub/custom.cfg /boot/grub/custom.cfg.before-splash && sudo sed -i '/linux \/vmlinuz-aurora72-wip5 /s/loglevel=7/quiet splash loglevel=3/' /boot/grub/custom.cfg +``` + +## Touch ID on wip5 + +On wip5 with the default guard (`xart_guard` 1), the enclave **matches** the enrolled finger. fprintd lists +`#0: right-index-finger`. The host then fails the verify: the kernel logs `xART guard: refused to rewrite a kind-4 record this +Linux install did not create`, then `post-match identity-bag snapshot failed`. That is the documented cold-boot M1 behaviour +([../../../aurora-sep/XART-GUARD.md](../../../aurora-sep/XART-GUARD.md)). The maintainers' reference M1 Pro runs `xart_guard=0` daily. + +Owner decision, 2026-10-29: try it with a backup first. `touchid-guard-off.sh` does both steps: + +1. A byte-exact, read-only `dd` of `nvme0n1p1` (iBootSystemContainer, where xART lives), `nvme0n2` and `nvme0n3`, each + verified against the device. They go to `/var/lib/mseries-kernel-tests/xart-backup-/` (root only, with `SHA256SUMS` and + `layout.txt`). **These images are this Mac's enclave state. Never commit them.** Keep a second copy off the machine (for + example a root-only directory on the SER8). Otherwise a wiped laptop loses the only way to restore them. +2. A separate GRUB entry, `elementary-aurora72-wip5-xartguard-off-trial`, the wip5 entry plus `apple_sep.xart_guard=0`. The + normal wip5 entry keeps the guard on. Nothing is armed. Undo: copy `custom.cfg.before` back from the backup directory. + +Test order: boot the guard-off entry once, run `fprintd-verify` (enrol again only if it fails), then boot macOS and check that +macOS Touch ID still works. Write the results here and in [TOUCH-ID-STATE.md](../../../aurora-sep/TOUCH-ID-STATE.md). + +**Restoring xART is a last resort.** Writing `nvme0n1p1` back with `dd` replaces the whole Apple boot container. Do it only if +macOS Touch ID or boot breaks *and* the steps the maintainers suggest have failed. Do it from this Linux install or from +recovery, never while macOS is running, and only with the image from the same Mac. diff --git a/mseries/aurora/unified72/wip5/stage-wip5.sh b/mseries/aurora/unified72/wip5/stage-wip5.sh new file mode 100755 index 000000000..1370ae367 --- /dev/null +++ b/mseries/aurora/unified72/wip5/stage-wip5.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash +# Stage an Aurora 7.2 unified72 kernel (wip5 by default) on the J314S beside the working one, as a +# non-default TRIAL GRUB entry. The persistent default and the shared boot.bin are not touched. +# +# The J314S boots an Arch mkinitcpio initramfs (cryptdevice= and the encrypt + plymouth hooks). +# Never build the new initramfs with initramfs-tools/mkinitramfs: it ignores cryptdevice= and the +# kernel dies before the passphrase prompt (wip5 first try, 2026-10-29). Instead retarget the working +# initramfs with prepare-trial-initrd.py and audit it, which is what this script does. +# +# sudo bash stage-wip5.sh /path/to/linux-image-elementary-aurora72-wip5_*.deb +# Optional: WORKING=7.2.11-elementary-aurora72-wip4 NEW=7.2.11-elementary-aurora72-wip5 SLUG=aurora72-wip5 +set -euo pipefail +[[ $EUID -eq 0 ]] || { echo 'run with sudo' >&2; exit 1; } +deb=${1:?usage: stage-wip5.sh } +here=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd) +aurora=$(cd -- "$here/../.." && pwd) # mseries/aurora +WORKING=${WORKING:-7.2.11-elementary-aurora72-wip4} +NEW=${NEW:-7.2.11-elementary-aurora72-wip5} +SLUG=${SLUG:-aurora72-wip5} +WORKING_SLUG=${WORKING_SLUG:-${WORKING#*elementary-}} +cfg=/boot/grub/custom.cfg + +ts=$(date -u +%Y%m%dT%H%M%SZ) +backup=/var/lib/mseries-kernel-tests/staging/$ts-$SLUG +mkdir -p "$backup"; chmod 700 "$backup" +cp -a "$cfg" /boot/grub/grubenv "$backup/" + +dpkg -i "$deb" +depmod -a "$NEW" +install -m 0755 "/usr/lib/modules/$NEW/vmlinuz" "/boot/vmlinuz-$SLUG" + +# Retarget the working Arch initramfs: same early archive, hooks and unlock userspace, new modules. +work=$backup/initrd +mkdir -m 700 "$work" +python3 "$aurora/prepare-trial-initrd.py" --baseline "/boot/initrd.img-$WORKING" --module-root /usr \ + --old-version "$WORKING" --new-version "$NEW" --output "$work/initrd.img-$NEW" --report "$work/module-preparation.json" +python3 - "$aurora/audit-trial-initrd.py" "/boot/initrd.img-$WORKING" "$work/initrd.img-$NEW" "/usr/lib/modules/$NEW" <<'PY' +import importlib.util, sys +from pathlib import Path +s = importlib.util.spec_from_file_location('audit', sys.argv[1]); a = importlib.util.module_from_spec(s); s.loader.exec_module(a) +r = a.audit(Path(sys.argv[2]).read_bytes(), Path(sys.argv[3]).read_bytes(), Path(sys.argv[4])) +for k in ('early_prefix_unchanged', 'nonmodule_entries_unchanged', 'module_bytes_match_candidate_tree', 'dependency_files_present'): + assert r[k] is True, k +print('initramfs audit passed:', r['verified_module_count'], 'modules') +PY +install -m 0755 "$work/initrd.img-$NEW" "/boot/initrd.img-$NEW" + +if ! grep -q "elementary-$SLUG-trial" "$cfg"; then + python3 - "$cfg" "$WORKING_SLUG" "$SLUG" "$WORKING" "$NEW" <<'PY' +import re, sys +p, ws, ns, wv, nv = sys.argv[1:] +t = open(p).read() +m = re.search(r"menuentry '[^']*' --id elementary-" + re.escape(ws) + r"-trial \{.*?\n\}\n", t, re.S) +assert m, 'working trial entry not found' +e = re.sub(r"menuentry '[^']*'", f"menuentry 'elementary OS - TRIAL: Aurora 7.2 {ns.split('-')[-1]}'", m.group(0), count=1) +e = e.replace(f"elementary-{ws}-trial", f"elementary-{ns}-trial").replace(f"/vmlinuz-{ws}", f"/vmlinuz-{ns}").replace(f"initrd.img-{wv}", f"initrd.img-{nv}") +assert ws not in e +open(p, 'w').write(t[:m.end()] + "\n" + e + t[m.end():]) +PY +fi +grub-script-check "$cfg" +echo "Staged $NEW (backup $backup). Default unchanged. Boot it once with:" +echo " sudo grub-reboot elementary-$SLUG-trial && sudo reboot" diff --git a/mseries/aurora/unified72/wip5/touchid-guard-off.sh b/mseries/aurora/unified72/wip5/touchid-guard-off.sh new file mode 100755 index 000000000..580aa7221 --- /dev/null +++ b/mseries/aurora/unified72/wip5/touchid-guard-off.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +# 1) Byte-exact, read-only backup of the Apple boot container (xART lives there) and the two small +# Apple NVMe namespaces. 2) Add a separate wip5 boot entry with apple_sep.xart_guard=0. +# The normal wip5 entry keeps the guard on; wip4 stays the default. Nothing is armed. +# Run: sudo bash ~/.cache/mseries-kernel/wip5/touchid-guard-off.sh +set -euo pipefail +[[ $EUID -eq 0 ]] || { echo 'run with sudo' >&2; exit 1; } +cfg=/boot/grub/custom.cfg +ts=$(date -u +%Y%m%dT%H%M%SZ) +dir=/var/lib/mseries-kernel-tests/xart-backup-$ts +mkdir -p "$dir"; chmod 700 "$dir" + +# Step 1: backup. Read-only dd; abort before touching anything if any copy fails to verify. +for dev in nvme0n1p1 nvme0n2 nvme0n3; do + [[ -b /dev/$dev ]] || { echo "missing /dev/$dev" >&2; exit 1; } + dd if=/dev/$dev of="$dir/$dev.img" bs=4M iflag=direct status=none + a=$(sha256sum < "$dir/$dev.img" | cut -c1-64); b=$(sha256sum < /dev/$dev | cut -c1-64) + [[ $a == "$b" ]] || { echo "backup of $dev does not match the device" >&2; exit 1; } + echo "$a $dev.img" >> "$dir/SHA256SUMS" +done +lsblk -o NAME,SIZE,PARTLABEL,PARTUUID /dev/nvme0n1 /dev/nvme0n2 /dev/nvme0n3 > "$dir/layout.txt" +chmod 600 "$dir"/* +echo "backup verified: $dir"; cat "$dir/SHA256SUMS" + +# Step 2: guard-off boot entry, copied from the wip5 trial entry. +cp -a "$cfg" "$dir/custom.cfg.before" +if ! grep -q 'elementary-aurora72-wip5-xartguard-off-trial' "$cfg"; then + python3 - "$cfg" <<'PY' +import re, sys +p = sys.argv[1]; t = open(p).read() +m = re.search(r"menuentry '[^']*' --id elementary-aurora72-wip5-trial \{.*?\n\}\n", t, re.S) +assert m, 'wip5 trial entry not found' +e = m.group(0) +e = re.sub(r"menuentry '[^']*'", "menuentry 'elementary OS - TRIAL: Aurora 7.2 wip5, Touch ID (xART guard off)'", e, count=1) +e = e.replace("--id elementary-aurora72-wip5-trial", "--id elementary-aurora72-wip5-xartguard-off-trial") +e, n = re.subn(r"(\n\s*linux /vmlinuz-aurora72-wip5 [^\n]*)", r"\1 apple_sep.xart_guard=0", e, count=1) +assert n == 1 +open(p, 'w').write(t[:m.end()] + "\n" + e + t[m.end():]) +PY +fi +grub-script-check "$cfg" +echo +echo "Done. To boot the Touch ID entry once:" +echo " sudo grub-reboot elementary-aurora72-wip5-xartguard-off-trial && sudo reboot" +echo "To undo the entry: sudo cp $dir/custom.cfg.before $cfg"