009: Closure wave 3 deblob, handoff, and optional wave4/malloc bacons.

Ship script gates wave 4 behind AXP_DEBLOB_WAVE4, documents secrets cert path,
and adds deblob appliers plus tests; docs capture Swissquote fix and parity.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
sunfish-adminandCursor committed 2026-10-09 17:31:01 +02:00
1 parent deaaf42caa
commit 3f941e8451
64 files changed
+6270 -86

No files matched your search

+1 -1
View File
@@ -36,7 +36,7 @@ Host packaging: `vendor/sunfish-a16/{Android.mk,gms.mk,BoardConfig.mk}`.
1. Download latest **default** `com.google.android.gms-NNNNNNN.apk` (no `-hw`) +
`GsfProxy.apk` from microG GitHub releases. Match GOLDEN: `versionName`
must **not** end in `-hw` (Huawei flavor drops NLP Location services /
UI). Example: `v0.3.16.252432` → `com.google.android.gms-252432032.apk`.
UI). Newest stable staged 2026-10-06: `v0.3.17.252432` → `com.google.android.gms-252432034.apk` (versionCode 252432034, default flavor, PRESIGNED).
2. Keep **official signature** (`LOCAL_CERTIFICATE := PRESIGNED`). **Never**
re-sign / ABI-strip GmsCore for size — that breaks F-Droid updates.
3. Do **not** install microG’s `com.android.vending-*.apk` (FakeStore).
+2 -1
View File
@@ -38,7 +38,8 @@ Script (idempotent, marker `SUNFISH_A16_005_SIGSPOOF`):
Changes on the LOS tree:
1. Extend `isMicrogSigned()` to accept **project Phonesky** signer for
`com.android.vending`.
`com.android.vending`. Do **not** keep LOS `isDebuggable()` — AXP/GOLDEN
is `user` (`ro.debuggable=0`) and still spoofs via the toggle + grant.
2. Gate spoofing on `Settings.Secure.allow_signature_fake` (default **0**).
3. Require grant of `android.permission.FAKE_PACKAGE_SIGNATURE`.
4. Port EXTENDROM permission + Settings Developer Options toggle + strings.
+15 -2
View File
@@ -1,5 +1,11 @@
# 009 — Remaining path to AXP / Graphene-class ship (post clean-429)
**Stale as an execution order.** Boot, vendor SPL, lock-scope, release-keys,
and `hardened_malloc` moved on 2026-10-08. Start from
`docs/009-handoff-20261008.md`.
Non-normative roadmap after LAB **BOOT_OK** on Stage1+combo4+FORTIFY+Magisk+
**CVE clean-offset 429** (denylist `CVE-2022-49980`), kernel `#47`
(`20261001T180955Z-axp-stage1-combo4-cve-clean`). Authoritative requirements
@@ -8,6 +14,12 @@ remain `specs/009-axp-los23-port/spec.md` + constitution.
Goal (owner): **almost all** applicable AXP.OS / Graphene-class behaviour on
LOS 23.2 sunfish Magisk track — not a blind dump, not bootloader lock.
**2026-10-07 next-bacon correction:** `misc/0021` is already present in the
LOS kernel base. Stage1 must omit it and use `patch --forward`; otherwise GNU
patch auto-reverses it and shrinks `KSYM_NAME_LEN` 192→128 under Clang CFI.
The first corrected candidate retains 192 and applies only the
`CVE-2022-49980` lock-scope companion as its new kernel delta.
## Already landed (kernel / Magisk core)
| Layer | Status |
@@ -16,7 +28,7 @@ LOS 23.2 sunfish Magisk track — not a blind dump, not bootloader lock.
| Combo4 + Clang FORTIFY | Ship |
| Magisk preroot EXTENDROM-class | Ship |
| CVE clean-offset 429 | Ship (LAB OK) |
| `CVE-2022-49980` | Denylist until lock-scope port |
| `CVE-2022-49980` | Original one-liner denylisted; corrected lock-scope candidate next |
| High-offset CVE (~73) | Quarantine — triage started |
Recover/bisect baseline: `20260929T123401Z-axp-stage1-combo4` (`#32`).
@@ -27,7 +39,8 @@ Recover/bisect baseline: `20260929T123401Z-axp-stage1-combo4` (`#32`).
nf_tables leftovers still skipped. Next kernel depth: **US-S5-1** defconfig
(Yama + `SLAB_FREELIST_RANDOM`), not more bulk CVE.
2. **`CVE-2022-49980` proper port** — keep UAF fix without recursive
`udc_lock` (mainline lock-scope series). Optional; denylist is safe.
`udc_lock` using the reviewed lock-scope companion. Boot and USB gadget
smoke are still required; the original one-liner remains denylisted.
3. Failed Stage1 probes (allocsize/ro/slab) — low priority vs high-offset.
4. Graphene modern techniques / `hardened_malloc` — backlog (`docs/hardening-backlog.md`);
evaluate after CVE depth is stable.
+99
View File
@@ -0,0 +1,99 @@
# Closure parity — AXP (GOLDEN) vs AXPR (LAB) — 2026-10-09
Status after **wave 3** boot on LAB slot `_a`. Swissquote 9.11.0 in Island
**PASS** (owner confirmed). Root cause for the prior `-69` / `onPrivilegedAccess`
was **Lineage tools on system** (`bash`, `htop`, `nano`, `unrar`,
`system/addon.d/50-lineage.sh`), removed in wave 3 — not Magisk PIF/cmdline.
GOLDEN was not on USB for this pass; oracle uses
`/srv/rom/references/axp/golden/2026-09-13/` plus prior live diffs.
## Ship candidate (closure baseline)
| Item | Value |
|------|--------|
| Dir | `20261009T145241Z-axp-stage1-combo4-cve-hi-releasekeys` |
| Zip | `AXP-Resurection-Pro-23.2-20261009-sunfish.zip` |
| SHA256 | `7cd20e4d218bc04f0b4a31838a5bb9040db36148a2b38d90342b3bc9f224a5fd` |
| `boot.img` | Same dir (Magisk preroot, AVB flags 0) |
| deblob | wave1 euicc + wave2 carrier/rcs + wave3 lineage tools |
| Do not re-sideload | Owner booted this zip once |
## Identity / Gate G (LAB measured)
| Check | LAB | GOLDEN ref | Notes |
|-------|-----|------------|-------|
| `ro.build.type` | `user` | `user` | OK |
| `ro.build.tags` | `release-keys` | `release-keys` | OK |
| `ro.debuggable` | `0` | `0` | OK |
| SPL system | `2026-09-01` | `2026-03-03` | LOS23 newer |
| SPL vendor | `2023-09-05` | `2023-08-05` | deliberate AXPR guard |
| SELinux | Enforcing | Enforcing | OK |
| Boot state | orange / unlocked | same | OK |
| Phonesky | `/system/priv-app/Phonesky` | AXP path variant | function OK |
| microG | `/system_ext/app/GmsCore` | often `/data` update on GOLDEN | version may differ |
## System surface (commands)
**Removed in wave 3 (was LAB-only, absent on GOLDEN):** `bash`, `htop`,
`nano`, `unrar`, `addon.d/50-lineage.sh`.
**Still LAB-only vs GOLDEN (deferred wave 4):** Qualcomm `diag_*`, `test_diag`,
`imsrcsd`, `disable_configstore`, AOSP debug bins (`bpftool`, `alloctop`,
`pbtombstone`, `apexd-lsof.sh`). Not required for Swissquote PASS.
**Kept like GOLDEN:** `curl` (`/system/bin`), `vim` (`/system_ext`).
## Recovery / boot
Sunfish: **recovery-as-boot** only (`boot_a` / `boot_b`). No `fastboot flash
recovery`. Scratch install: flash `boot.img` to both slots → recovery → factory
reset → sideload full zip → reboot system.
## Repo vs next bacon
- `apply_009_drop_lab_only_commands.py` exists but is **commented out** in the
ship script (wave 4 deferred).
- Optional later: `scripts/009-bacon-hardened-malloc.sh` (012) — separate bacon;
not in the booted wave 3 image.
- Host keys: `/srv/rom/secrets/android-certs` (2026-10-09); `~/.android-certs`
symlinks there. Backup `~/backups/android-certs-secrets-20261009T1517Z.tar.gz`.
## Physical-SIM call gate
Before any wave beyond carrier/rcs deblob: owner places a **mobile-network**
voice call on LAB (SIM in slot, not Wi‑Fi calling only). Note result and time
in `docs/009-handoff-20261008.md`.
## GOLDEN parity capture
When GOLDEN `11071JEC203839` is on USB (read-only oracle):
```bash
adb -s 11071JEC203839 shell pm list packages -f | sort > /tmp/golden-packages.txt
adb -s 11231JEC207477 shell pm list packages -f | sort > /tmp/lab-packages.txt
diff -u /tmp/golden-packages.txt /tmp/lab-packages.txt
adb -s 11071JEC203839 shell cat /proc/cmdline > /tmp/golden-cmdline.txt
adb -s 11231JEC207477 shell cat /proc/cmdline > /tmp/lab-cmdline.txt
```
Offline fallback: `/srv/rom/references/axp/golden/2026-09-13/` (not a live
cmdline). Refresh this doc when a live GOLDEN dump exists.
## Follow-on bacons (not the booted closure zip)
| Script | Purpose |
|--------|---------|
| `scripts/009-bacon-wave4-deblob.sh` | wave 4 lab-only command drops |
| `scripts/009-bacon-hardened-malloc.sh` | 012 hardened_malloc (2 GiB regions) |
Launch on `rom-dev01` via `rom-detach`; never two ninjas on one `out/`.
## Scratch reinstall
Owner-driven virgin `/data` with the **same** closure zip: flash `boot.img` to
both slots → recovery factory reset → sideload → reboot system from menu.
## Open (non-blocking)
- LOS 23 nightly rebase; regen plan/tasks.
+13
View File
@@ -6,6 +6,19 @@ AVB/signing gaps (or “impossible on this stack”). This file is that list for
**kernel** half. Userspace AVB is tracked separately below as still open.
**LAB device:** `11231JEC207477` only.
> **2026-10-07 correction / next bacon:** LAB currently runs the
> `20261007T133154Z` PRO/user/release-keys artifact. Audit found that Stage1
> treated `misc/0021` as reversed and silently changed the LOS base's
> `KSYM_NAME_LEN` from 192 to 128 while `CONFIG_CFI_CLANG=y`. The next recipe
> removes that already-present patch, invokes Stage1 with `patch --forward`,
> and gates `KSYM_NAME_LEN=192`. Artifact `20261007T161115Z` is quarantined
> and must not be flashed. Its corrected replacement,
> `20261007T171530Z`, completed all artifact gates and keeps the original CVE
> one-liner denylisted while testing only the lock-scope companion as the new
> kernel delta. It remains **unflashed** pending LAB USB-gadget acceptance.
> The historical acceptance record below remains unchanged.
**Accepted kernel ship pack (LAB 2026-10-01):** Stage1 Graphene/AH + combo4 +
Clang FORTIFY + Magisk preroot + **CVE clean-offset 429** + **hi-batch1+2 (15)**
with `CVE-2022-49980` denylisted. Clean-only `#47` / hi-batch1 `#48` remain bisect GOODs.
+24
View File
@@ -0,0 +1,24 @@
# GOLDEN reference vs LAB packages — 2026-10-09
GOLDEN was **not** on USB. Comparison uses the frozen oracle dump
`/srv/rom/references/axp/golden/2026-09-13/packages.txt` (owner-installed /
spot-check format, not `pm list packages -f` of the full system image).
A live LAB `pm list packages -f` was **not** captured in this pass: scratch
started immediately after `adb reboot bootloader` (broken pipe during reboot).
## Reference excerpt (GOLDEN dump)
Curated hits from the oracle file include Island, Swissquote, microG/Phonesky,
F-Droid/Aurora, Lineage recorder, Yuh, etc. See the full file on `rom-dev01`.
## When GOLDEN is on USB
```bash
adb -s 11071JEC203839 shell pm list packages -f | sort > /tmp/golden-live.txt
adb -s 11231JEC207477 shell pm list packages -f | sort > /tmp/lab-live.txt
diff -u /tmp/golden-live.txt /tmp/lab-live.txt
```
Merge results into `docs/009-closure-parity-20261009.md` (system surface table
stays authoritative for deblob; package list diff is for user-installed drift).
+644
View File
@@ -0,0 +1,644 @@
# 009 handoff — 2026-10-08 evening
Start here. Older remaining-work docs still describe the tree from before
LAB booted the 2026-10-08 zip. This file is the execution map for the
final ROM. Do not commit unless the owner asks. Do not flash GOLDEN.
## Hard rules already paid for
- LAB only: `11231JEC207477`. GOLDEN `11071JEC203839` is the live oracle.
It may be plugged in at the same time. Never flash, wipe, or change Magisk
on it. Always `adb -s 11231JEC207477`.
- Do not factory-reset LAB except an **owner-driven scratch** (recovery wipe +
sideload closure zip). The recovery screen "Can't load Android system /
data may be corrupt / reason=init_user0_failed" is **not** corrupt data.
- Never lower `VENDOR_SECURITY_PATCH` below `2023-09-05`.
- KernelSU stays out of Magisk ship boots.
- Do not run AXP `Deblob.sh` defaults.
- Do not start a second ninja on the same `out/`.
- Sideload the full zip. A boot-only flash does not carry userspace.
- User builds reject an undeclared downgrade (error 28).
- `fastboot flash vendor` of a sparse image: `fastboot reboot fastboot`
(`is-userspace=yes`) and `fastboot -S 128M`. A 256 MB chunk drops USB.
Do not `fastboot -w`. Do not flash another build's vbmeta in the same test.
- Host: `ssh -F docs/ssh/config a16-build`. Long builds via
`/srv/rom/artifacts/bin/rom-detach` (tmux). Do not leave `mka` on a laptop SSH.
- Keep the last booting zip plus two test builds. Laptop disk was tight.
Host artifacts are canonical.
## Running now
**Closure baseline (booted, Swissquote Island PASS):** wave 3 zip
`20261009T145241Z-axp-stage1-combo4-cve-hi-releasekeys`
SHA256 `7cd20e4d218bc04f0b4a31838a5bb9040db36148a2b38d90342b3bc9f224a5fd`.
LAB slot `_a`, `boot_completed=1`. Owner confirmed Swissquote no longer
exits `-69` in Island after wave 3 (Lineage tools removal). Parity notes:
`docs/009-closure-parity-20261009.md`. Do not sideload this zip again.
**Closure checklist (2026-10-09 evening):**
| Item | Status |
|------|--------|
| Keys → `/srv/rom/secrets/android-certs` | done |
| Scratch reinstall (virgin `/data`, same closure zip) | `boot_a`/`boot_b` flashed 2026-10-09; recovery **unauthorized** — owner: USB auth → Factory reset → sideload zip in `/tmp/axp-closure-scratch/` (laptop) or host artifact dir |
| `~/.android-certs.pre-secrets-20261009` removed on host | done |
| GOLDEN package/cmdline parity | needs GOLDEN USB or reference dump |
| `bacon009wave4` (diag drop) | **running** `2026-10-09T15:29:17Z` — log `detach-bacon009wave4-20261009T152917Z.log` |
| `bacon012malloc` (hardened_malloc) | **queue after wave4** (one `out/`): `rom-detach bacon012malloc -- /srv/rom/artifacts/bin/009-bacon-hardened-malloc.sh` |
| Physical-SIM call gate | owner — before more radio deblob |
| Git commit of repo closure deltas | owner asked 2026-10-09 |
Check detach logs under `/srv/rom/artifacts/detach-bacon009*.log`. Do not run
two ninjas on the same `out/`.
Last closure build `bacon009tools` finished `exit=0` `2026-10-09T14:54:03Z`.
`bacon009deblob4` finished `exit=0` at `2026-10-09T12:01:31Z`. Zip
`/srv/rom/artifacts/009-axp-los23-port/20261009T120025Z-axp-stage1-combo4-cve-hi-releasekeys/AXP-Resurection-Pro-23.2-20261009-sunfish.zip`
SHA256 `bd1ce97896b5da31d4c22d4ffc3f2050ad204eea45768bbf86f7527f44b70c51`.
Sideloaded to LAB at 14:58 local (`Total xfer: 2.00x`). Owner
confirmed boot. Slot `_b`. `ro.build.date` `Fri Oct 9 11:04:11 UTC 2026`.
The nine wave-2 paths are absent from the image. `/data` leftovers
`com.google.android.ims` and `com.google.android.apps.carrier.carrierwifi`
were uninstalled for user 0 and user 10. `ims` and `qcrilmsgtunnel` remain.
Previous slot `_a` is the wave-1 zip. If this slot dies later,
`fastboot -s 11231JEC207477 --set-active=a`. Do not wipe. Do not sideload
this zip again.
Wave 2 drops
CarrierServices, CarrierSettings, CarrierWifi, CarrierSetup, RilConfigService,
grilservice, ImsServiceEntitlement, PresencePolling, and RcsService.
Qualcomm radio packages stay. AVB flags 0. Boot of this zip confirmed on LAB slot `_b`.
Log `/srv/rom/artifacts/detach-bacon009deblob4-20261009T110253Z.log`.
`bacon009deblob3` finished `exit=0` at `2026-10-09T10:18:22Z`,
was sideloaded to LAB at 12:33 local (`Total xfer: 2.00x`), and the owner
confirmed boot. Slot `_a`. `ro.build.date` is `Fri Oct 9 09:18:53 UTC 2026`.
`/product/priv-app/EuiccGoogle` and
`/system_ext/priv-app/EuiccGoogleOverlay` are absent. The `/data` leftover
`com.google.android.euicc` was uninstalled for user 0 and Island user 10
(`pm uninstall` Success, `pm path` empty). EuiccSupportPixel,
EuiccSupportPixelPermissions, and OpenEUICC remain.
`im.angry.openeuicc/.ui.PrivilegedMainActivity` stayed up and opened
`DownloadWizardActivity` (empty card). That is the wave-1 pass. Do not
sideload this zip again. Next gate is a physical-SIM call, then VoLTE and
VoWiFi, before any wave-2 bacon. If this slot dies later,
`fastboot -s 11231JEC207477 --set-active=b` (flags-0 zip). Do not wipe.
`bacon009deblob2` finished `exit=0` at `2026-10-09T09:09:32Z`. Do not
sideload it. Zip
`/srv/rom/artifacts/009-axp-los23-port/20261009T090831Z-axp-stage1-combo4-cve-hi-releasekeys/AXP-Resurection-Pro-23.2-20261009-sunfish.zip`
SHA256 `722e6d2e5cd639c3dfcea8af1585d5a741ea3ffd13ff5e0fad62d2c76722b70e`.
Flags 0. `EuiccGoogle.apk` and `EuiccGoogleOverlay` are still in the image.
`bacon009deblob` finished `exit=0` at `2026-10-09T07:38:53Z`. Do not
sideload it: flags are 0, but both Google LPA packages are still in the
images. Zip
`/srv/rom/artifacts/009-axp-los23-port/20261009T073753Z-axp-stage1-combo4-cve-hi-releasekeys/AXP-Resurection-Pro-23.2-20261009-sunfish.zip`
SHA256 `63851d964a259aefa8247883401481296dd7c6bb51dbcc13ee901361c7d8ab50`.
`bacon009timeouts` finished `exit=0` at `2026-10-08T22:02:51Z`. Zip, not
flashed:
`/srv/rom/artifacts/009-axp-los23-port/20261008T220151Z-axp-stage1-combo4-cve-hi-releasekeys/AXP-Resurection-Pro-23.2-20261008-sunfish.zip`
SHA256 `1717d23db2024f524dfe48364b13ee66c998364adfc10c3f9bde676a3d926a58`.
Same hash on the `lineage-23.2-20261008-PRO-sunfish.zip` twin. vbmeta flags
still 3. It carries the timeout settings and Droidify 0.7.8.
`bacon009avb0` finished `exit=0` at `2026-10-09T00:26:40Z`. Log line
`avb_infra=... flags=0`. Sideloaded to LAB `11231JEC207477` on 2026-10-09
morning. `Total xfer: 2.00x`. Before the sideload the running slot was
`_a` (cmdline zip). Recovery adb came back unauthorized, so the owner
reboots from the recovery menu. If it sticks on the Google logo,
`fastboot -s 11231JEC207477 --set-active=a`. Do not wipe.
Zip:
`/srv/rom/artifacts/009-axp-los23-port/20261009T002537Z-axp-stage1-combo4-cve-hi-releasekeys/AXP-Resurection-Pro-23.2-20261008-sunfish.zip`
SHA256 `1aabda75c672e1e7d7a7df046a3428ef50fa47aaa3501808ff3d12bbb075e96b`.
Local copy `/tmp/axp-flash/AXP-Resurection-Pro-23.2-20261009-avb0-sunfish.zip`.
No ninja is running. The deblob Soong files are still only on the laptop.
## What is on LAB right now
**Closure baseline (wave 3)** unless a scratch reinstall is in progress.
| | |
|---|---|
| Artifact dir | `20261009T145241Z-axp-stage1-combo4-cve-hi-releasekeys` |
| Zip | `AXP-Resurection-Pro-23.2-20261009-sunfish.zip` |
| SHA256 | `7cd20e4d218bc04f0b4a31838a5bb9040db36148a2b38d90342b3bc9f224a5fd` |
| Host path | `/srv/rom/artifacts/009-axp-los23-port/20261009T145241Z-axp-stage1-combo4-cve-hi-releasekeys/` |
| Slot (last known) | `_a` after wave 3 sideload |
| deblob | wave1 euicc + wave2 carrier/rcs + wave3 lineage tools |
| AVB | flags `0` on shipped `boot.img` |
| Swissquote Island | **PASS** after wave 3 (owner confirmed); prior `-69` was Lineage tools on system |
Wave 3 removes `bash`, `htop`, `nano`, `unrar`, `system/addon.d/50-lineage.sh`.
`curl` and `vim` stay. Wave 4 diag/`bpftool`/… are **still present** on this
image; use `scripts/009-bacon-wave4-deblob.sh` for a candidate without them.
**Rollback slots (do not wipe casually):** other slot may hold an older zip
(wave 2 on `_b`, wave 1, or flags-only builds). `fastboot -s 11231JEC207477
--set-active=a|b` only if the active slot boot-loops.
**Scratch reinstall (owner 2026-10-09):** bootloader → `fastboot flash boot_a`
and `boot_b` with closure `boot.img` → recovery → **Factory reset** → sideload
the closure zip above → **Reboot system** from recovery (not `adb reboot` if adb
is unauthorized). Re-verify Magisk, Island, Swissquote after setup.
**Physical-SIM call gate:** place a normal mobile call (not only Wi‑Fi) before
any further Qualcomm radio deblob. Record pass/fail in this file.
Parity matrix: `docs/009-closure-parity-20261009.md`.
## 1. hardened_malloc — 2 GiB rebacon finished, not flashed
`bacon012malloc3` finished `exit=0` at `2026-10-08T18:43:47Z` (58 min, ccache).
Zip: `/srv/rom/artifacts/009-axp-los23-port/20261008T184238Z-axp-stage1-combo4-cve-hi-releasekeys/AXP-Resurection-Pro-23.2-20261008-sunfish.zip`
SHA256 `f85a0233be1ca83d6a866c081e7cf314e9b5e547a4d6324addb7139ed90030e9`.
Vendor SPL `2023-09-05`. Not sideloaded. The phone is still on the morning
zip in slot `a`.
The first malloc zip boot-looped. `bacon012malloc2`
(`20261008T170027Z`, SHA256
`28c7f0bfa11c60f24e86d35c080cd1e52c244c3640168e34673e4ef0252d690c`)
was sideloaded to LAB slot `b` at 19:17 local and rebooted at the Google logo.
Recovered without a wipe: `fastboot --set-active=a`, morning zip booted
(`boot_completed=1`, vendor SPL `2023-09-05`). Slot `b` still holds the bad
build and is not marked successful. Do not set it active.
Cause: sunfish msm-4.14 is `CONFIG_ARM64_VA_BITS=39` (3-level page tables),
on LAB and on GOLDEN. Upstream `Android.bp` uses
`CONFIG_CLASS_REGION_SIZE=34359738368` (32 GiB), which needs 48-bit VA;
the README says the defaults do not work on 39-bit. DivestOS Patch.sh
(LineageOS-17.1/20.0/21.0) does
`sed -i 's/34359738368/2147483648/' Android.bp` ("revert 48-bit address
space requirement"). GOLDEN ships hardened_malloc on the same 39-bit kernel
and its `system_server` holds about 210 GiB of `---p` reservations, which
matches 2 GiB regions. `config/light.mk` is still 32 GiB; it is not a fix.
Fixed in `apply_012_hardened_malloc.py` and applied on the host tree:
- region size `2147483648`; the script exits if it is not 2 GiB;
- The `// 32GiB` comment next to `2147483648` was replaced after
`bacon012malloc3` exited. The line now says
`// 2GiB, 39-bit VA (DivestOS/AXP)`.
- the exclusion helper had been inserted between `__attribute__((noinline))`
and `__libc_preinit_impl`, which moved `noinline` off the function bionic
needs it on. The applier now places the helper before the attribute,
repairs the misplaced form, and exits if `noinline` is lost.
Next: sideload the `20261008T184238Z` zip to LAB only (it lands on slot `b`),
then smoke boot, USB, Magisk, camera, and that surfaceflinger stays on Scudo.
If it loops at the Google logo again, `fastboot --set-active=a`. Do not
factory-reset.
Original notes for the first attempt follow.
Session `bacon012malloc2`, started `2026-10-08T10:25:49Z`.
- Status: `/srv/rom/artifacts/detach-bacon012malloc2.status`
- Log: `/srv/rom/artifacts/detach-bacon012malloc2-20261008T102549Z.log`
- At 13:55 local: still `running`, ninja ~10 % (6453/63504), no error.
`libc` had already linked at `2026-10-08T10:30:05Z`.
- A 30-minute watcher lived in the 2026-10-08 chat. If that chat is gone,
read the status file. Do not start another ninja.
Wrapper: `scripts/009-bacon-hardened-malloc.sh`. It applies
`vendor/sunfish-a16/patches/012-hardened-malloc/apply_012_hardened_malloc.py`,
builds `libc`, then execs the main Stage1 bacon. The host tree is already
patched, so a plain re-run of the main bacon script also ships malloc.
Do not revert `bionic` unless this experiment is abandoned.
Pin: GrapheneOS `hardened_malloc` `1d7fc7ffe0f8068a32ab2ba33df7515e7bad3f5f`
(branch 14 tip, "support GCC15"). 64-bit libc uses it; 32-bit stays Scudo.
`frameworks/av` `RLIMIT_AS` hunk does not exist on this LOS 23 tree and was
not ported. Sunfish has no MTE; the `device_has_arm_mte` product variable was
stripped from `Android.bp`.
Exclusions, required: `/system/bin/surfaceflinger` exact path, and any exe
whose path contains `camera`. Real LAB paths:
`/vendor/bin/hw/android.hardware.camera.provider@2.7-service-google` and
`/system/bin/cameraserver`. Env `DISABLE_HARDENED_MALLOC` also disables it.
`init.rc` sets `vm.max_map_count` to `1048576`.
Previous failure, already fixed: `h_malloc_info` was undeclared
(`h_malloc.h` omits it on Android). Declaration is in `malloc_common.h`.
The dead log is `detach-bacon012malloc-20261008T101328Z.log`. Do not treat
that log as the current job.
This bacon does **not** contain the Swissquote cmdline fix, the Settings
timeout patches, deblob, or AVB flags 0.
When it finishes with `exit=0`: verify the zip hash, sideload only LAB,
then smoke boot, USB, Magisk, camera, and that surfaceflinger is still on
Scudo. Keep the 20261008 zip until that smoke passes. If the bacon fails,
diagnose before relaunching. Do not factory-reset.
## 2. Swissquote — next bacon only after malloc boots
Measured 2026-10-08 with both phones online. Same app on both:
`com.swissquote.android` 9.10.0 (`versionCode=91000000`). Both have Island
user 10, Zygisk, DenyList on, and the same module set except GOLDEN also
has `flag-secure-disabler`. DenyList on both already has
- `com.swissquote.android|com.swissquote.android`
- `com.swissquote.android|com.swissquote.android_zygote`
DenyList has no user id. It covers Island. Vector's scope is `user_id=0`
on both, and GOLDEN does not even have Swissquote installed on user 0
(only user 10) and it still passes. The module screen that cannot pick
work-profile apps is a red herring. Do not chase it.
### Proven ROM difference
GOLDEN `/system/bin/init` contains `chmod("/proc/cmdline", 0440)`.
LAB's init does not. Magisk's binary on neither phone contains that string.
No module script was found chmod'ing it.
| | LAB | GOLDEN |
|---|---|---|
| `/proc/cmdline` mode | `0444` root:radio | `0440` root:radio |
| shell can read it | yes, sees `verifiedbootstate=orange` | no (`Permission denied`) |
| `init.rc` | `chown root radio` only | same `chown`, no chmod line |
Both `init.rc` files only chown. The mode change is a C call inside GOLDEN's
init. Clone that call. Do not implement it as a Magisk module. The owner
asked for that specifically.
Where it lives: `apply_009_cmdline_mode.py`, called by the ship bacon.
It inserts AOSP's `CHECKCALL(chmod("/proc/cmdline", 0440))` in
`first_stage_init.cpp` immediately after the proc mount. That CHECKCALL
is what logs `chmod("/proc/cmdline", 0440) failed`, the string found in
GOLDEN's init. LOS 23.2 already chmod's `/proc/bootconfig` and did not
chmod cmdline. `bacon009cmdline` is the build for this and keeps the
2 GiB hardened_malloc already in the tree. Do not flash it until it
finishes and the owner asks.
The compiling malloc tree does not have this call (`init.cpp` has no
`cmdline` match; `init.rc` only has the chown at line 1282).
### 2026-10-08 22:30 — writer found, do not bake the spoof into the ROM
Play Integrity Fix `service.sh` (same file on both phones) runs after
`sys.boot_completed=1` and calls `resetprop_if_diff`. That helper does
nothing when the property is empty:
```
[ -z "$CURRENT" ] || [ "$CURRENT" = "$EXPECTED" ] || resetprop -n "$NAME" "$EXPECTED"
```
`spoofProps=false` does not gate this block. Both phones now use the same
PIF print: `oriole` Pixel 6 CANARY, `ZP11.260618.005`. The earlier
`tegu` / `stallion` note is stale.
GOLDEN's bootloader cmdline creates the properties, so the module rewrites
them. LAB's cmdline never creates `vbmeta.device_state` or `veritymode`, so
the same script skips them.
| `getprop` | LAB | GOLDEN |
|---|---|---|
| `ro.boot.verifiedbootstate` | `green` (was `orange`) | `green` (was `orange`) |
| `ro.boot.flash.locked` | `1` | `1` |
| `ro.boot.vbmeta.device_state` | empty | `locked` (cmdline said `unlocked`) |
| `ro.boot.veritymode` | empty | `enforcing` (real cmdline value, not a spoof) |
| `sys.oem_unlock_allowed` | empty on the 22:32 read | `0` (cmdline-era value was `1`) |
Vector's `/data/adb/lspd/log/props.txt` on GOLDEN still records the real
values (`orange`, `unlocked`, `enforcing`, `oem_unlock_allowed=1`). They
are not in `/data/property/persistent_properties`. Island sees the rewritten
`getprop` because the property area is global. It cannot open
`/proc/cmdline` (`0440`), so it never sees the raw `unlocked` / `orange`.
The owner said Swissquote on GOLDEN also worked with no Magisk modules.
The PIF rewrite is therefore not the first fix. Hope is that the init
chmod alone is enough. Do not set `sys.oem_unlock_allowed=0` in the ROM;
it conflicts with the OEM-unlock escape hatch. Do not add the missing
cmdline tokens in this bacon. If Island still fails after the chmod,
those tokens belong to the separate AVB flags experiment.
TEESimulator 71 on LAB (`71-17be1f0`) did not change the outcome. Its
target list is still only `com.google.android.gms`, `com.android.vending`,
and `io.github.vvb2060.keyattestation`. GOLDEN is still TEE 67 with the
same three targets. The app is not in that list.
Test only inside Island. GOLDEN does not have the app on user 0, and the
owner said it has never worked in the main profile there. LAB currently
has it on user 0 and user 10. `ps` shows `magiskd`, `su`, `zygiskd64`,
`teesim`, and `vectord` on both phones, so a visible process list does not
explain why Island passes on GOLDEN.
### 2026-10-08 22:53 — chmod booted, Island still closes
Slot `_a`, zip SHA256 `40ed3213…ccfa`. `/proc/cmdline` is `0440`; shell
gets permission denied; root still reads `orange`. The app still exits in
Island and in the main profile. The 22:52 log is the same sequence as
before the chmod: DenyList hit, Play services `261200000` vs microG
`252432034`, `libsigner.so`, SELinux and `/cache` denied, `ps`, suppressed
toast, process dies. GOLDEN's microG is older (`252432033`) and Island
works there, so the version warning is not the gap.
What Island can still see: `ro.boot.vbmeta.device_state` and
`ro.boot.veritymode` are empty on LAB. GOLDEN's bootloader cmdline creates
both (`unlocked` and `enforcing`) even with no modules. Do not chase that
inside the timeouts bacon. It stays with the AVB flags 0 experiment.
### If the app still fails after the chmod
These are owner-installed modules, not ROM payload
(`docs/009-magisk-preinstall-runbook.md`):
1. TEESimulator version is already ruled out. LAB is `71-17be1f0`, GOLDEN
is `67-4f42350`, same three targets, and 71 changed nothing. Config
holds a keybox; do not copy it into git or into a doc.
2. PIF print is already the same on both (`oriole` Pixel 6 CANARY). Do not
chase `stallion`. A wrong CANARY print on sunfish already broke this
surface once (`comet`); that is not the current gap.
Banking flow if the app is reinstalled (constitution): Aurora, do not open,
DenyList including processes before the first process, clone into Island
(`com.oasisfeng.island.fdroid`, not Insular), first launch inside Island,
Play update from the work profile. Spec 009 still marks banking deferred.
The owner asked to make Swissquote work on LAB anyway. Yuh on GOLDEN needed
Vector's bootloader spoofer on top of DenyList; Swissquote on GOLDEN did not.
## 3. After that, one bacon each
Do not stack these into the malloc zip or into each other.
1. **Settings timeouts and sensitive QS tiles.** Already inside
`bacon009timeouts` (see "Running tonight"). Defaults stay off except
the sensitive QS tiles, which ask for the PIN on the lock screen.
After boot, confirm the three settings exist and Droidify is 0.7.8.
2. **Selective deblob.** Own bacon, after the timeouts zip exists. Study
and the wave-1 Soong override are in the section below. Do not run
`Deblob.sh`. Do not put wave 2 in the same bacon.
3. **AVB flags 0.** Script is ready, not launched.
`scripts/009-bacon-avb-flags0.sh` exports `AXP_AVB_FLAGS=0` and
`WITH_AVB=true`. That is the only Lineage switch: `BoardConfigLineage.mk`
skips `--flags 3`. Same `avb.pem`, same `SHA256_RSA4096`. Pubkey sha1
`ee85ac5a2dcec0846e95dd575f874a659026d790`. The default ship script still
expects flags 3 unless that env is set. Do not rsync the ship script over
`/srv/rom/artifacts/bin/` while `bacon009timeouts` is running. Launch only
after that status file shows `exit=0`, and do not flash until the owner
asks. On LAB check Magisk, a full sideload, dm-verity, and whether the
raw cmdline gained `veritymode` and `vbmeta.device_state`. Relock stays
**wont**. If it boot-loops, set the active slot back to the previous zip.
Measured on the current LAB image, before that experiment:
`getprop ro.boot.vbmeta.device_state` and `getprop ro.boot.veritymode`
are empty. `ro.boot.verifiedbootstate=green` is the PIF spoof; the raw
cmdline is still `verifiedbootstate=orange`. These two missing tokens
are bootloader cmdline properties. Flags 3 is
`HASHTREE_DISABLED|VERIFICATION_DISABLED`. GOLDEN's raw cmdline, read
earlier the same night, contains `androidboot.vbmeta.device_state=unlocked`
and `androidboot.veritymode=enforcing`. Do not write `locked` or
`enforcing` into the ROM, and do not set `sys.oem_unlock_allowed=0`.
4. **Lock-scope concurrency review.**
`vendor/sunfish-a16/patches/009-kernel-hardening/ports/cve-2022-49980-lock-scope.patch`.
Boot and USB already passed on LAB. Review the companion. Do not revert
it unless a new failure shows up. The one-liner stays denylisted.
5. **Leftover high-offset kernel CVEs.** Small reviewed batches (≤10),
strict applicator, boot each batch. nf_tables leftovers stay skipped.
Failed Stage1 probes (allocsize/0007, ro/0007+0034, slab) are low
priority. Do not reflash `20260918*-axp-kh-cve` or `kh-full`.
6. **Droidify.** `bacon009timeouts` ships `0.7.8` (`versionCode=780`,
targetSdk 37). Host file
`/srv/rom/prebuilts/axp-apps/Droidify.apk`, SHA256
`3e7934ff9b811c2f77794793381241095a02bac2d163bf922cb5a5a0ed25ca82`.
The previous `0.7.7` apk is kept beside it as `Droidify-0.7.7.apk`.
Aurora and Fossify stay.
7. **GPG SHA256 sums** of published zips, the way AXP does. Owner on
2026-10-09: not needed now. Do not start it. AXP's current publish
path is a SHA512 file plus `gpg --verify` on that file
(`docs/knowledge/signatures`).
8. **Release-key custody.** Signing works (the booted zip is `release-keys`).
Keys are still `$HOME/.android-certs/` on rom-dev01 plus a gitignored
copy under `vendor/lineage-priv/keys` and `vendor/sunfish-a16/certs`.
Move the private material to `/srv/rom/secrets/` and confirm the
encrypted offline copy. Never commit `.pk8`. Cert tar already at
`/home/android-build/backups/android-certs-20260929T1637Z.tar.gz`.
9. **SetupWizard language bounce** after Wi-Fi connect. Wi-Fi stays up.
Non-blocking. Looked at on 2026-10-08: `lineage_wizard_script.xml` goes
locale, then SIM, then network, and every network result advances to
datetime. There is no result edge that returns to language. Do not invent
a patch. `LocaleActivity` can still call `updateLocale` from the SIM MCC
while that page is open; that is a different moment from the Wi-Fi step.
10. **LOS 23 nightly rebase**, then re-apply this pack. Do it after the
malloc and cmdline bacons, not during them.
11. **Regenerate** `plan.md` / `tasks.md` after any `spec.md` edit.
Spec Kit order stands. Do not use upstream `taskstoissues`.
## Selective deblob — studied 2026-10-08
Do not run AXP `Deblob.sh`. It is not in the public AXP-OS repos or in
`/srv/rom/references/axp/archive/codeberg/git`, and its usual defaults drop
CNE, IZat/XTRA, and sometimes Widevine. Shipped GOLDEN still has
`com.qualcomm.qti.cne`. Spec FR-018 and the constitution forbid deleting
the IZat/XTRA/xtwifi blobs. The positive list is the owner's finish list.
The `[ -e $f ]` loop that printed ABSENT for every vendor binary was a
quoting bug. `ls` of the literal path is the check: "Permission denied"
means the file exists and shell cannot stat it; "No such file" means gone.
### Positive list — do not override, do not delete
Present on the booted LAB image (`11231JEC207477`). GPS daemons and
`imsrcsd` were also checked on GOLDEN before it was unplugged.
| Keep | LAB evidence | GOLDEN |
|---|---|---|
| `xtra-daemon`, `lowi-server`, `loc_launcher` | `/vendor/bin/…` exists (permission denied) | those three paths are "No such file" on GOLDEN. Keep them. Default is the precise Lineage stack. The two Settings switches below, both default off, are how the owner turns that assistance off and matches the AXP posture without deleting the binaries. |
| `xtwifi.conf` | copied by `sunfish-vendor.mk` to `/vendor/etc/xtwifi.conf` | absent on GOLDEN (`No such file`). Keep the copy rule. The location switches are what turn the assistance off. |
| Widevine | `/vendor/bin/hw/android.hardware.drm-service.widevine` exists. Soong module `android.hardware.drm-service.widevine` | same path exists |
| IMS | `/system_ext/priv-app/ims/ims.apk` (`org.codeaurora.ims`); `/vendor/bin/ims_rtp_daemon`, `imsdatadaemon`, `imsqmidaemon`, `imsrcsd` all exist | `imsrcsd` is absent on GOLDEN. Keep it. It is the Qualcomm RCS daemon, and the positive list says IMS. |
| IPA | `/vendor/bin/ipacm` exists | directory listing earlier the same night also showed it on GOLDEN |
| IWlan | `/vendor/app/IWlanService/IWlanService.apk` (`vendor.qti.iwlan`); `vendor.qti.hardware.data.iwlan@1.0.so` exists on both | keep |
| CNE | `/vendor/app/CneApp/CneApp.apk` (`com.qualcomm.qti.cne`). Soong `CneApp`, `libcne*` | package was on GOLDEN too |
| eUICC hardware | `/system_ext/priv-app/EuiccSupportPixel/EuiccSupportPixel.apk` and `EuiccSupportPixelPermissions` (`com.google.euiccpixel`, `.permissions`) | both phones |
| OpenEUICC | `/system_ext/priv-app/OpenEUICC/OpenEUICC.apk` (`im.angry.openeuicc`) | both phones |
| Radio packages already on both | `com.qualcomm.qti.telephonyservice`, `com.qualcomm.timeservice`, `com.qualcomm.uimremoteclient`, `com.qualcomm.uimremoteserver`, `com.android.carrierconfig`, `com.android.carrierdefaultapp`, `com.android.providers.telephony` | keep |
GPS precision stays the default. `apply_009_supl_privacy.py` is already in
the ship bacon. Both switches live in Location settings and start off, so
SUPL, LPP, XTRA and IZat keep running:
- "Force disable Secure User Plane Location (SUPL)" (`force_disable_supl`).
On sets `SUPL_MODE=0`. IMSI and the phone number are never sent to a SUPL
server, whether this switch is on or off.
- "Stop extra location assistance" (`force_disable_location_assist`). On
sets `LPP_PROFILE=0` (LPPE goes with that session), skips the framework
XTRA download, and stops `loc_launcher` (`xtra-daemon`, lowi, IZat).
Satellite fixes keep working. Turning it off starts `loc_launcher` again.
That second switch is the AXP location posture. Do not delete the blobs
and do not change either default to on.
`/vendor/lib64/libimsmedia_jni.so` is missing on both phones. The JNI
libs ship inside the ims app (`system_ext_priv-app_ims_lib_arm64_libimsmedia_jni_so`).
That is not a deletion.
### Wave 1 — booted 2026-10-09, pass
`bacon009deblob3` (`20261009T101715Z`, SHA256
`efbec33ac2bafc75ee2f90970a9286f51fe8073b61fc3ed11c01689c9e8a28cf`) is
the running LAB slot `_a`. `EuiccGoogle` and `EuiccGoogleOverlay` are
absent from the image. The `/data` update survived the sideload and was
removed for user 0 and user 10. EuiccSupportPixel and OpenEUICC stayed.
OpenEUICC opened onto `DownloadWizardActivity`. Empty card is the pass.
The notes below are the failed attempts; do not rebuild them.
Why the old override did nothing: `EuiccGoogle` is a Soong
`android_app_import` in `vendor/google/sunfish/Android.bp` (`product_specific:
true`). `NoEuiccGoogle` was a Make `BUILD_PHONY_PACKAGE`. Make's
`LOCAL_OVERRIDES_PACKAGES` only filters Make modules (`build/make/core/main.mk`
`module-overrides`). `out/soong/soong.lineage_sunfish.variables` contains
both `NoEuiccGoogle` and `EuiccGoogle` in the product package list, and
`PackageNameOverrides` is empty.
Laptop tree now, not rsynced:
- `vendor/sunfish-a16/deblob/Android.bp` — `NoEuiccGoogle` (`product_specific`)
overrides `EuiccGoogle`; `NoEuiccGoogleOverlay` (`system_ext_specific`)
overrides `EuiccGoogleOverlay`. It does not name `EuiccSupportPixel`.
- `vendor/sunfish-a16/apps.mk` installs both phonies.
- The Make phony was removed from `vendor/sunfish-a16/Android.mk`. Do not
put an `Android.bp` beside that `Android.mk`; Soong would skip the
prebuilt APKs in the same directory.
After the timeouts bacon exits, rsync those three files, then a deblob
bacon. Do not flash until asked. On the installed-files list, confirm
`EuiccGoogle.apk` and `EuiccGoogleOverlay.apk` are gone and
`EuiccSupportPixel.apk` and `OpenEUICC.apk` remain. The `/data` update
can survive a sideload. If `pm path com.google.android.euicc` still points
at `/data/app`, `adb -s 11231JEC207477 shell pm uninstall --user 0
com.google.android.euicc` after boot. The owner has no eSIM profile, so
do not block on downloading one. Open OpenEUICC: it must start and not
crash. An empty card or "no profiles" is a pass. `pm path` must still
show EuiccSupportPixel and OpenEUICC.
### Wave 2 — not in the wave-1 bacon
Rechecked read-only on GOLDEN `11071JEC203839` at 2026-10-08 23:24 local,
with LAB unplugged. `pm path` printed no path for every row below, and
`ls` returned `No such file` for `xtra-daemon`, `lowi-server`,
`loc_launcher`, `imsrcsd`, and `/vendor/etc/xtwifi.conf`. Present on
GOLDEN, same as LAB: EuiccSupportPixel, EuiccSupportPixelPermissions,
OpenEUICC (`/system_ext/priv-app/OpenEUICC_AXP-OS/OpenEUICC_AXP-OS.apk`),
CneApp, `org.codeaurora.ims`, IWlanService, QtiTelephonyService,
TimeService, both uimremote packages, CarrierConfig, CarrierDefaultApp,
TelephonyProvider, `ims_rtp_daemon`, `imsdatadaemon`, `imsqmidaemon`,
`ipacm`, and the Widevine HAL. One bacon, after wave 1 has booted and a
physical-SIM call, VoLTE, and VoWiFi have passed. No eSIM profile is
required. Same Soong-phony pattern, matching partition flag.
Google, not the Qualcomm IMS stack:
| Module | Partition flag | LAB path | Package |
|---|---|---|---|
| `CarrierServices` | `product_specific` | `/product/priv-app/CarrierServices` (active path is `/data/app/…/com.google.android.ims…`) | `com.google.android.ims` |
| `CarrierSettings` | `product_specific` | `/product/priv-app/CarrierSettings/CarrierSettings.apk` | `com.google.android.carrier` |
| `CarrierWifi` | `product_specific` | active path `/data/app/…/com.google.android.apps.carrier.carrierwifi…` | `com.google.android.apps.carrier.carrierwifi` |
| `CarrierSetup` | `system_ext_specific` | `/system_ext/priv-app/CarrierSetup/CarrierSetup.apk` | `com.google.android.carriersetup` |
| `RilConfigService` | `system_ext_specific` | `/system_ext/priv-app/RilConfigService/RilConfigService.apk` | `com.google.RilConfigService` |
| `grilservice` | `system_ext_specific` | `/system_ext/priv-app/grilservice/grilservice.apk` | `com.google.android.grilservice` |
AOSP, not vendor blobs. Override only after the same call test:
- `ImsServiceEntitlement` in `packages/apps/ImsServiceEntitlement/Android.bp`,
installed at `/product/priv-app/ImsServiceEntitlement/ImsServiceEntitlement.apk`
(`com.android.imsserviceentitlement`).
- `com.android.service.ims` is `/system_ext/app/RcsService/RcsService.apk`.
- `com.android.service.ims.presence` is
`/system_ext/app/PresencePolling/PresencePolling.apk`.
Grep `name: "RcsService"` and `name: "PresencePolling"` before writing
the phony. The names were not in `packages/services/Telephony/Android.bp`.
Leave these alone until a zip that removed only the Google rows above
has made a call. They were absent on GOLDEN, and they sit next to radio:
- `atfwd` → `/system_ext/app/atfwd/atfwd.apk` (`com.qualcomm.atfwd`)
- `qcrilmsgtunnel` → `/system_ext/priv-app/qcrilmsgtunnel/qcrilmsgtunnel.apk`
- `uceShimService` → `/system_ext/app/uceShimService/uceShimService.apk`
- `com.qualcomm.qti.services.secureui` → same directory name under
`/system_ext/app/`
- `CACertService` → `/vendor/app/CACertService/CACertService.apk`
(`vendor.qti.hardware.cacert.server`, `soc_specific: true`)
Do not remove `ims`, `QtiTelephonyService`, `CneApp`, `xtra-daemon`,
`lowi-server`, `loc_launcher`, `imsrcsd`, Widevine, or `EuiccSupportPixel`
in either wave.
## Already on the booted zip — do not redo
- Magisk 30.7 preroot (`/system_ext/bin/magisk`). GOLDEN oracle is still
Magisk 29.0. Ship stays 30.7 unless 30.7 itself breaks a bank after the
cmdline fix. Dormant until Additional Setup.
- microG GmsCore `0.3.17.252432` (`252432034`), not `-hw`.
- Phonesky from `/srv/rom/prebuilts/phonesky/`. Never git.
- OpenEUICC privileged, platform cert, deps SDK forced to 36
(`prebuilts/openeuicc-deps` `5402167` was generated for SDK 37).
- Sigspoof (`apply_005_sigspoof.py`) and call recording / FLAG_SECURE
(`apply_008_call_rec_flag_secure.py`) are in the ship script.
FLAG_SECURE override is a project extra, default off.
- Private DNS, connectivity check, the two location switches (both default
off, so SUPL / XTRA / IZat stay on for precision), Yama
`persist.native_debug`, disable-app.
- Jelly stays. Gallery is Fossify. Gallery2 APK stays absent. WebView stays
LOS 23. No NeoLauncher. No `axp.os` OTA endpoints.
- Vendor SPL guard: `apply_009_axp_identity.py` rewrites a `2023-08-05`
rollback back to `2023-09-05` and exits otherwise. AXP GOLDEN really is
`2023-08-05`. This divergence is deliberate.
- `LINEAGE_BUILDTYPE=PRO`, `user`, project AVB key, flags 3.
- Stage1 + combo4 + FORTIFY + CVE-clean + hi-batch1–3 + US-S5-1 Yama/slab
+ lock-scope. `KSYM_NAME_LEN` stays 192. Stage1 must use `patch --forward`
and must omit `misc/0021` (already in the LOS base; GNU patch would
reverse it and shrink KSYM 192→128).
## init_user0 — do not rediscover
The 17:15 zip (`SHA256 2c16d2385094197181c07dde4e9604137883eefedc2b346cc1071e38abb57a0b`)
lowered vendor SPL from `2023-09-05` to `2023-08-05`. Keymaster blobs on the
existing install refuse that rollback. `vdc cryptfs init_user0` fails and
recovery writes
`boot-recovery --prompt_and_wipe_data --reason=init_user0_failed`.
Proof, same userdata: nols boot failed, full 13:31 boot on the 17:15
userspace failed, flashing only the 13:31 vendor (`2023-09-05`) made Android
boot. Data was fine. The 13:31 zip
(`SHA256 2c4eb9cb831e96a57c2c068e5c044ae5d29ef140f53817e9246cac3c61dbe008`)
is the older known-good, without lock-scope. Quarantine
`20261007T161115Z` (`SHA256 df2ad13f6afeb2d25f5e8f7a32ee2caa0b926550000e5cb3078c8a56d8efffd7`)
stays unflashed.
Emulator and an on-screen boot debugger do not explain this. The emulator
cannot boot the sunfish 4.14 / keymaster / userdata stack. The debug console
is UART `ttyMSM0`. pstore on this LAB was encrypted and unreadable.
`docs/007-debug-boot-panic-screen.md`.
## Uncommitted work the next session must keep
Not committed. Do not revert while picking up a later item.
- `apply_009_axp_identity.py` — vendor SPL stays `2023-09-05`.
- `scripts/009-bacon-axp-stage1-combo4-cve-hi-releasekeys.sh` — lock-scope
applied, vendor SPL grep, Jelly/Fossify gates, the userspace applies listed
above.
- `scripts/009-bacon-hardened-malloc.sh` and
`vendor/sunfish-a16/patches/012-hardened-malloc/`.
- `tests/test_009_next_bacon_guards.py`, `tests/test_012_hardened_malloc.py`,
`tests/test_009_a15_reboot_fixups.py`, `tests/test_009_a15_small_ports.py`.
- Host tree under `/srv/rom/src/lineage` is dirty with the malloc apply and
the identity/kernel applies. Laptop scripts were rsynced to
`/srv/rom/artifacts/bin/`.
## Docs that will lie to you
- `docs/009-axp-graphene-remaining.md` — pre-boot order. Pointer added.
- `docs/009-hardening-signing-checklist.md` — still says test-keys,
`userdebug`, and "hardened_malloc later". The booted zip is `user` +
`release-keys`, and malloc is the bacon in flight.
- `docs/009-user-zip-audit-20261007.md` — an older unflashed zip. Jelly is
**kept** now; that audit's "Jelly absent" line is obsolete.
- `docs/009-version-pins.md` — still right for microG, Magisk 30.7, Phonesky,
OpenEUICC. Add the malloc pin when that bacon is accepted.
+16 -3
View File
@@ -211,14 +211,27 @@ attribution. One stage per bacon when risk is unclear.
- [x] **US-S5-1** LAB OK (`162840Z`): `CONFIG_SECURITY_YAMA=y` +
`CONFIG_SLAB_FREELIST_RANDOM=y` — see
`docs/009-lab-acceptance-20261002-uss5.md`
- [ ] Optional later: `CVE-2022-49980` lock-scope port; Stage1 slab FAIL
retries; `hardened_malloc`
- [ ] **Next cycle after the user image is accepted** (owner 2026-10-06):
close kernel CVE + Graphene/AXP hardening + deblob on that baseline.
Boot-check each batch (full `cve-strict` ~503 and `CVE-2022-49980`
alone hang at the Google logo). Inventory: remaining high-offset KEEP,
`49980` lock-scope port, Stage1 probes that failed
(allocsize/0007, ro/0007+0034, slab/0010+0018), `hardened_malloc`,
AXP deblob that still leaves radio, GPS and Widevine working.
Still out: location lockdown, bootloader relock, KernelSU, IPA removal.
- [x] **Next-bacon recipe guard (2026-10-07):** Stage1 uses
`patch --forward`, omits already-present `misc/0021`, and fails unless
`KSYM_NAME_LEN=192`; full feature-008 call-recording apply is restored.
Quarantine the earlier `bacon00949980` build and do not flash it.
Map updates: `docs/009-kernel-hardening-map.md` + Gate G attribution.
### US-S6 — Optional later
- [ ] Switch default lunch to `lineage_sunfish-user` for ship
- [ ] Confirm `lineage_sunfish-user` after flash
(bacon started 2026-10-06, tmux `009-user-bacon`, log
`/srv/rom/artifacts/detach-009-user-bacon-20261006T203157Z.log`.
PRO stays branding. Check `ro.build.type=user` and `release-keys` on LAB)
- [ ] GPG-sign published SHA sums (AXP does; nice-to-have)
- [ ] LOS23 nightly rebase (vanilla + re-apply Magisk/stage1/keys)
- [ ] Bootloader lock — **wont**
@@ -0,0 +1,180 @@
# Swissquote differential investigation — 2026-10-09
Status: **failure classified, underlying root-detection signal not yet isolated**.
Live observations approximately 15:18–15:26 Europe/Berlin. This supersedes
the Swissquote runtime inventory in `009-handoff-20261008.md`, not its
build/recovery instructions. No firmware was flashed and GOLDEN was read-only.
## Confirmed new finding
Swissquote 9.11.0 stores this nonfatal exception on LAB, Island user 10:
```text
com.swissquote.android.FreeRaspException
freeRASP: onPrivilegedAccess
com.swissquote.android.ThreatDetectedListenerKt$getThreatDetectedListener$1.onPrivilegedAccess
ThreatDetectedListener.kt:24
app.talsec.rasp.security.api.ThreatListener.onReceive
```
This was read from the app's existing local Crashlytics event JSON. Only
the exception classification and stack symbols were retained; no raw
Crashlytics report, account data, keys, or session identifiers enter Git.
`scripts/009-read-swissquote-rasp.py --device LAB` reproduces that limited,
read-only inspection. Retained events may be uploaded/removed by the app;
an empty result does not prove compatibility or that no callback occurred.
Static inspection of the installed APK established that **-69 is an
application-defined `RASP_FAILING_EXIT_CODE`**, shared by four handlers:
`onPrivilegedAccess`, `onDebug`, `onAppIntegrity`, and `onHooks`. Each records
a distinct FreeRaspException, requests the same warning, then calls
`System.exit(-69)`. Consequently the exit code alone was not enough to
attribute the failure to root. The retained exception now identifies the
privileged-access branch for the observed LAB failure. It does not identify
which underlying native check fired or exclude additional failures later.
The APK contains Talsec `v19_2_0_fullRelease` markers and loads `libts.so`.
`libsigner.so` belongs to the separately present Adjust signer integration;
loading it is not evidence that it caused this exit.
The previously suppressed toast was recovered by temporarily granting
POST_NOTIFICATIONS to LAB user 10, then revoking it in a finally block.
Its text lists generic device-safety requirements (root, debugging,
emulation, modification, malware, official store); it does **not** disclose
the failing check. A later observation showed the permission granted with
USER_SET, apparently from concurrent user activity; it was not overwritten.
## Current comparison, not the earlier handoff inventory
- Both devices have Swissquote **9.11.0 / 91100003**, target SDK 37,
arm64, with Play Store as installer and initiating package.
- All three installed APKs match byte for byte:
- base: `734293c7b6a7ecf48117e23ffc72ad0a1e3279336025551faf23c1c3c239c8f2`
- arm64 split: `6ce67d98a2a4dc4b1ac38a9b3c864e11167b17ba9ed62e8a9d69cf48cb3e090d`
- density split: `4e0ab62d8eb7c2faa959014552204c8378977459109b3ba2a0b400a87bb9c3a2`
- Both now have Swissquote installed for user 0 **and** user 10. The earlier
statement that GOLDEN has it only for user 10 is obsolete.
- Island matches: `6.4.2-d46911c9`, versionCode 51801.
- GOLDEN: Android 15 / SDK 35, Magisk 29.0. LAB: Android 16 / SDK 36,
SDK_FULL 36.1, Magisk 30.7, deblob4 slot b.
- Both are user/release-keys with `ro.debuggable=0`, SELinux Enforcing,
Zygisk enabled and DenyList **enforced**. Both list the main Swissquote
process and its `_zygote` entry. LAB logs the DenyList hit for user 10.
- Both expose `verifiedbootstate=orange`, `vbmeta.device_state=unlocked`,
`flash.locked=0`, and `veritymode=enforcing` at this measurement.
Both protect `/proc/cmdline` with mode 0440.
- GOLDEN has only hosts and flag-secure-disabler modules installed.
LAB has hosts plus PIF and TEESimulator directories; both latter modules
have **disable markers**. Directory presence is not active-module proof.
- Owner confirmed GOLDEN Swissquote still opens in Island in this state.
Its existing user-10 process was alive during read-only inspection.
- Shell developer/ADB settings are enabled on both. No enabled
accessibility service was returned for user 10 on either device.
This is strong evidence against treating spoofed green/locked properties,
PIF, or TEESimulator as prerequisites for the observed GOLDEN success.
It does not prove that every path through either banking app is independent
of attestation.
## Process-level observations and controlled experiment
Read `/proc/<Swissquote PID>/mountinfo` and selected maps using root, without
attaching a debugger or modifying the banking process. Both mount tables
lacked obvious Magisk/module mounts; neither selected maps output contained
Magisk/Zygisk/LSPosed libraries. The injected `/system_ext/bin/magisk` was
absent beneath each inspected process's `/proc/<PID>/root` view even though
it exists in the root shell's view. This supports actual unmounting, beyond
merely checking DenyList configuration. It **does not** prove absence of
all detectable root signals, sockets, policy changes, or runtime effects.
Important real ROM difference: GOLDEN has no Yama ptrace_scope node; LAB
has Yama enabled and scope 2. The local `apply_009_yama_ptrace.py` already
documents that the AXP init rule was inert on GOLDEN's kernel.
At 15:22, changed **only** LAB's transient ptrace_scope from 2 to 0, cold
started Swissquote in user 10, and observed `System.exit(-69)` again.
Restored scope **2**, with readback. No persistent property was changed.
Thus relaxing ptrace_scope alone does not fix the observed failure; this
is not a blanket clearance of every kernel-hardening difference.
## Why GOLDEN passes: what is known and what remains open
GOLDEN's actual process environment satisfies Swissquote's startup checks
despite unlocked/orange state, Magisk, and USB debugging. LAB triggers the
privileged-access callback despite working basic DenyList unmounting.
The APK and Island version are controlled; the operating system, kernel,
SELinux policy and Magisk implementation are **not** controlled yet.
Leading branches for investigation, not established causes:
1. A Magisk 29 → 30.7 difference leaves a root-detection surface after
unmounting. Upstream changed file injection, mounting and sepolicy-related
handling; simply seeing the same DenyList checkboxes cannot exclude this.
2. A ROM/kernel/SELinux difference is interpreted as privileged access by
Talsec on Android 16. Yama scope alone has been tested unsuccessfully.
3. App-visible package/file/policy differences or retained per-install state.
Package listings from shell are not automatically app-visible listings.
Do not claim “Magisk 30.7 is broken” from upstream issue 9866: that report
had **Enforce DenyList OFF**, unlike this LAB, and was closed not planned.
Do not infer a specific Talsec false positive from unrelated hardware-
attestation reports. Do not mask callbacks, patch Swissquote, or transfer
GOLDEN banking data as a diagnostic shortcut.
## Prepared next discriminator — same build, without Magisk
The current artifact directory is:
`/srv/rom/artifacts/009-axp-los23-port/20261009T120025Z-axp-stage1-combo4-cve-hi-releasekeys/`
Unpacked both boot images with the host's magiskboot. Verified:
- `boot.img`: SHA256 `e5822d8e8cbb39fe74ca638cdfcd52cd66fc741d130bdf962f433ae4f16299d2`;
ramdisk `cpio test` = **1**, Magisk patched.
- `boot-make-out.img`: SHA256
`6caceaca1e911d327e7ad86217cc6bedb8cd32fe690cadd11c9cedeed0440d1b`;
ramdisk `cpio test` = **0**, stock/unpatched.
- The extracted kernel SHA256 is identical in both:
`e093a3c7edfb2560f109c0b3df68d2722a1e05f06357316d1278b8c0348e8f89`.
This prepares a **temporary LAB-only boot experiment**, subject to owner
agreement and confirming the phone is still on this same build. No image
has been booted or flashed in this investigation. Preserve data, vendor SPL,
the active slot and the installed APK; do not reinstall/reset the app.
Prefer booting the image temporarily if the bootloader supports that path.
The stock image has not yet been boot-tested; a verified hash is not boot
acceptance. Confirm actual absence of running Magisk after boot before
interpreting the Swissquote result; the manager APK and historical `/data`
files can remain, so this is not a clean factory/rootless baseline.
- If it starts, focus on active Magisk integration; consider a compatible,
isolated comparison against GOLDEN's version, not a blind ship downgrade.
- If it still exits, reclassify the failure before investigating ROM-visible
surfaces. Rootless boot failure alone would not prove a Talsec bug.
- Return to the installed boot and repeat the original failure for an A/B/A
comparison. A process surviving briefly is not a usable-session PASS.
LAB became unavailable in ADB during investigation. On the next turn the
owner confirmed it had been reconnected and authorized the remaining tests.
USB enumeration then confirmed LAB was physically present at 3-5.3 as
18d1:4ee1 (MTP only), while GOLDEN was 18d1:4ee2 (MTP + debug). The earlier
user-facing assertion that LAB was disconnected was too broad: USB was
present, but the ADB interface was unavailable. Requested that the owner
enable USB debugging on LAB; do not mistake GOLDEN's ADB presence for LAB.
## Sources and audit trail
- Project: `009-handoff-20261008.md`, constitution, feature 009 spec,
Magisk runbook, current tracked diff and new patch scripts. Relevant recent
changes include user/release signing, AXP identity and vendor-SPL guard,
user-build signature spoofing, cmdline permissions, AVB flags 0, malloc
2-GiB regions, kernel ports/forward-only patching, Yama, USERFAULTFD off,
Settings/privacy ports and two deblob waves. No existing work was reverted.
- [Talsec callback API](https://docs.talsec.app/freerasp/freerasp/integration/flutter/api)
- [Magisk 30.7 DenyList source](https://github.com/topjohnwu/Magisk/blob/v30.7/native/src/core/deny/utils.cpp)
- [Magisk changelog](https://github.com/topjohnwu/Magisk/blob/v30.7/docs/changes.md)
- [Magisk issue 9866, different enforcement configuration](https://github.com/topjohnwu/Magisk/issues/9866)
- [Adjust upstream libsigner reference](https://github.com/adjust/android_sdk/issues/655)
- Local scratch: `/tmp/axp-swissquote-20261009/`. Proprietary APKs and
decompiled files remain outside the repository and must not be committed.
Partial full-APK decompilation was replaced by targeted inspection.
+35
View File
@@ -0,0 +1,35 @@
# User zip audit — 20261007T022805Z (not flashed)
Build finished `exit=0` at 2026-10-07T02:29:08Z. Session `009-user-bacon`.
Log: `/srv/rom/artifacts/detach-009-user-bacon-20261006T203157Z.log`.
No LAB flash, no wipe.
Artifact: `/srv/rom/artifacts/009-axp-los23-port/20261007T022805Z-axp-stage1-combo4-cve-hi-releasekeys/`
Ship zip (same bytes as the lineage twin):
`AXP-Resurection-Pro-23.2-20261006-sunfish.zip`
SHA256 `7c70944614a1002e83bba7c38e1ef3ab8baeb56bfb3f60a474f59230575ea5a9`
## Checked on the host images
| Check | Result |
|-------|--------|
| Lunch | `ro.build.flavor=lineage_sunfish-user`, `ro.build.type=user`, `ro.debuggable=0` |
| Version | `23.2-20261006-UNOFFICIAL-AXP-Resurection-Pro-sunfish`, track `pro` |
| OTA cert | `O=AXP-Resurection, OU=sunfish-a16, CN=release` (not AOSP testkey) |
| `ro.build.tags` | `dev-keys` (Lineage unofficial). GOLDEN official PRO is `release-keys` |
| `ro.lineage.releasetype` | `UNOFFICIAL` |
| AVB | project key SHA256_RSA4096, flags `3`, boot/dtbo/vendor/system chain verified |
| Magisk | `magiskboot_cpio_test=1` on the shipped boot |
| KernelSU | no KernelSU strings in `boot.img`; ship script refused `CONFIG_KSU=y` |
| microG | `system_ext/app/GmsCore`, versionCode `252432034`, versionName `0.3.17.252432` |
| Jelly / Gallery2 | **absent** on product. FossifyGallery present |
| Kernel pack | Stage1 + combo4 + FORTIFY + CVE-clean 429 + hi-batch1–3 + Yama |
## Notes for the morning
- `dev-keys` is the unofficial Lineage tag. The zip itself is signed with the project release key.
- Jelly and Gallery2 were already removed in the tree, and the ship script still fails the build if those APKs are present. This zip does not contain them.
- Flash stays a separate decision. Sideload the AXP zip; a boot-only flash is not enough.
+2 -1
View File
@@ -8,7 +8,7 @@ Never ship from stale laptop caches.
| component | version_name | version_code | upstream_ref | policy | verified_on | notes |
|-----------|--------------|--------------|--------------|--------|-------------|-------|
| VanillaBaseline | lineage-23.2 sunfish | | `/srv/rom/artifacts/003-vanilla/20260914-lineage-23.2-sunfish` | los_default | 2026-09-14 | Known-good vanilla artifact on host |
| microG GmsCore | v0.3.16.252432 | | microG official (matches GitHub latest 2026-09-17) | newest_stable | 2026-09-16 staged | `/srv/rom/prebuilts/microg/` |
| microG GmsCore | v0.3.17.252432 | 252432034 | https://github.com/microg/GmsCore/releases/tag/v0.3.17.252432 | newest_stable | 2026-10-06 staged | default flavor, not `-hw`. PRESIGNED on `system_ext`. GOLDEN live overlay was 0.3.16.1 |
| GSF Proxy | v0.1.0 | | microG official | newest_stable | 2026-09-16 staged | |
| Phonesky | 52.9.22-24 | | project patched host artifact | project_phonesky | 2026-09-14 | `/srv/rom/prebuilts/phonesky/`; never Git |
| Magisk | v30.7 | | https://github.com/topjohnwu/Magisk/releases/tag/v30.7 | newest_stable | 2026-09-17 | Staged APK; GOLDEN oracle **29.0** layout only |
@@ -17,6 +17,7 @@ Never ship from stale laptop caches.
| F-Droid | present on GOLDEN | | `org.fdroid.fdroid` | newest_stable | 2026-09-17 seen | |
| Fossify Gallery | present on GOLDEN | | `org.fossify.gallery` | newest_stable | 2026-09-17 seen | |
| Seedvault | present on GOLDEN | | `com.stevesoltys.seedvault` | los_default / newest | 2026-09-17 seen | Often LOS-provides |
| OpenEUICC | upstream 2026-09-28 | | `im.angry.openeuicc` `89d677e07d0e` | newest_upstream | 2026-10-07 wired | Privileged system_ext LPA, platform cert. Latest PeterCxy master, not the AXP fork (1.6.2 / GOLDEN 1.6.1). Datastore from LOS androidx. Deps `prebuilts/openeuicc-deps` @ `5402167` for zxing |
| Island | deferred | | `com.oasisfeng.island.fdroid` | | | US3 deferred |
## Host artifact hashes (copy from host VERSIONS when refreshed)