009: Magisk ship pack through US-S5-1 + US-S4 OpenSSH/Jelly/Gallery2.

Release-keys/AVB, CVE clean+hi batches, Yama/slabrand, Pro branding,
bundled apps, and AXP-class product surface docs/scripts.
This commit is contained in:
sunfish-admin committed 2026-10-05 10:42:00 +02:00
1 parent fd793b9471
commit deaaf42caa
129 files changed
+11769 -141

No files matched your search

+14 -8
View File
@@ -66,8 +66,13 @@ Checked packages (package-level; process expand not fully visible in shots):
Visible unchecked (partial): Aegis, Amarok, Amaze, Aosmium.
Owner notes: most DenyList banking apps still pass; **Yuh fails** for ~weeks.
Extra Magia DenyList/host checks + Island uninstall/reclone did **not** fix Yuh.
Owner notes (2026-09-13): most DenyList banking apps still pass; **Yuh failed**
for ~weeks. Extra Magia DenyList/host checks + Island uninstall/reclone did
**not** fix Yuh at that time.
**Owner update 2026-10-02:** Yuh works again on GOLDEN after enabling Vector’s
**bootloader spoofer** module (`zygisk_vector` / Vector manager). DenyList alone
was never enough for that HA path.
## Compatibility / attestation (observational)
@@ -75,14 +80,15 @@ Extra Magia DenyList/host checks + Island uninstall/reclone did **not** fix Yuh.
|-------|--------|----------|
| Swissquote | **PASS** (owner report) | Still used; on DenyList |
| Other DenyList banks (N26, DKB, …) | **PASS** (owner: “casi todos”) | UI DenyList |
| Yuh | **FAIL** — hardware attestation / “certificate is invalid” | Owner UI + logcat ~21:51–21:52 |
| Yuh | **PASS again** (owner 2026-10-02) via Vector bootloader spoofer | Was **FAIL** 2026-09-13 (HA / “certificate is invalid”) |
| Play Integrity token path | Client path still runs | `Finsky requestIntegrityToken() finished for com.yuh`; DroidGuard `pia_attest_e1` for `com.yuh` |
| KeyMint / TEE | Errors concurrent with Yuh attempt | `keystore2`: `HARDWARE_TYPE_UNAVAILABLE` (IRPC / `TRUSTED_ENVIRONMENT`); `addRngEntropy` → `DEAD_OBJECT` / KeyMint `-1000` |
| KeyMint / TEE | Errors concurrent with 2026-09-13 Yuh FAIL | `keystore2`: `HARDWARE_TYPE_UNAVAILABLE` (IRPC / `TRUSTED_ENVIRONMENT`); `addRngEntropy` → `DEAD_OBJECT` / KeyMint `-1000` |
Interpretation for later `006`/`007` (not a GOLDEN fix): DenyList alone is
insufficient for Yuh’s hardware-attestation path; KeyMint/TEE remote-provisioning
errors correlate with the failure window. Project production root path remains
**KernelSU-Next (+ SusFS) or ReSukiSU evaluation** — Magisk/Magia is oracle-only.
Interpretation for Gate E / LAB: GOLDEN banking stack = Magisk DenyList +
`playintegrityfix` + `teesim` + **Vector bootloader spoofer** (owner-proven for
Yuh). Ship ROM still does **not** bake those modules (`009-magisk-preinstall-runbook`);
owner installs post-flash. Wrong PIF prints (e.g. `comet` CANARY on sunfish LAB)
break the same surface. Magisk/Magia remains the AXP oracle path for `009`.
Call recording: GOLDEN Secure dump shows native EXTENDROM
`extendrom_call_recording=1` (see `008` — port `er.sh` F_CALLREC, not Magisk
+66
View File
@@ -0,0 +1,66 @@
# 009 — Remaining path to AXP / Graphene-class ship (post clean-429)
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
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.
## Already landed (kernel / Magisk core)
| Layer | Status |
|-------|--------|
| Stage1 Graphene/AH | Ship |
| Combo4 + Clang FORTIFY | Ship |
| Magisk preroot EXTENDROM-class | Ship |
| CVE clean-offset 429 | Ship (LAB OK) |
| `CVE-2022-49980` | Denylist until lock-scope port |
| High-offset CVE (~73) | Quarantine — triage started |
Recover/bisect baseline: `20260929T123401Z-axp-stage1-combo4` (`#32`).
## Kernel remaining (toward “AXP CVE / Graphene depth”)
1. **High-offset quarantine** — KEEP batches 1–3 **shipped** (`151944Z`).
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.
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.
## Userspace / product remaining (AXP surface)
From `docs/009-capability-matrix.md` / Gate G (still open or partial):
| Item | Notes |
|------|--------|
| Release keys + AVB (unlocked) | US-S2/S3 — leave test-keys |
| Private DNS / connectivity check | Patches exist; keep AXP-class, no axp.os endpoints |
| Call-rec / FLAG_SECURE | `008` — selectable unlock |
| Bundled apps (Aurora, Droidify, gallery, …) | Packaging |
| Disable-app UX on A16 | Restore classic Disable |
| Hosts / DNS privacy helpers | Magisk module vs ROM-native TBD |
| WebView | LOS default (Aosmium exception) |
| Banking / Island | Deferred |
| Bootloader lock | Wont |
| KernelSU swap | Optional later; do not mix Magisk ship boots |
## Suggested execution order (default if owner has no preference)
1. Finish high-offset **relevance filter** → small apply batches (≤10) with
strict applicator + LAB boot each batch.
2. Wire **release keys** bacon of current ship pack; keep Magisk/preroot OK.
3. Land remaining **Settings/UX** AXP clones (DNS, connectivity, disable-app)
if not already on LAB zip.
4. Optional: 49980 lock-scope port; Graphene userspace / hardened_malloc spikes.
## Do-not
- Reflash full-503 / old kh-cve zips.
- Bulk-apply high-offset without manual review.
- Mix KernelSU into Magisk ship boots.
- Treat “almost AXP/Graphene” as requiring locked bootloader.
+54
View File
@@ -0,0 +1,54 @@
# AXP.OS PRO sunfish product/app surface — 20260324 zip
Oracle: `AXP.OS-22.2-20260324-PRO-sunfish.zip` (`payload.bin` → partitions).
Extracted 2026-10-02 (local `payload-dumper-go`). Authoritative for **debloat**
vs Lineage product defaults — not the disroot `upstream_*` lineage mirror.
## `product/app` (present)
Aperture, ApertureLensLauncher, Backgrounds, Camelot, DeskClock,
ExactCalculator, LatinIME, LocalContactsBackup, ModuleMetadata, PhotoTable,
Recorder, ThemesStub, Twelve, messaging, uimremoteclient, uimremoteserver
## `product/app` (absent vs typical LOS product)
| LOS / our prior ship | AXP PRO |
|----------------------|---------|
| Jelly | **absent** (browser stub on system_ext) |
| Gallery2 | **absent** (Fossify only) |
| Etar | **absent** (uses `Etar_ER` on system_ext) |
| AuroraStore / Droidify / Fossify | not on product — on **system_ext** |
| VZWAPNLib / PixelCameraServices* | absent here (device packs may differ) |
## `product/priv-app`
Contacts, Dialer, SettingsIntelligence
## `product/bin`
**No** `/bin` tree (no sshd/ssh/rsync). `etc/init/init.openssh.rc` **present**.
## `system_ext/app` (bundled AXP extras)
AuroraStore, Etar_ER, F-Droid, FossifyGallery_FD, GsfProxy_GH,
MicrogGmsCore_GH_presigned, Profiles, AccessibilityMenu,
QtiTelephonyService, SimpleSettingsConfig,
`noDefaultBrowserWebView`, `noeSpeakNG`
## `system_ext/priv-app` (selected)
AOSLauncher (NeoLauncher — **wont** for 009), AOSmium_webview64
(**exception** — we ship LOS WebView), OpenEUICC_AXP-OS, Seedvault,
TrebuchetQuickStep, Updater, Lineage*, Settings, SystemUI, ims, …
## 009 mapping
| AXP | Our ship policy |
|-----|-----------------|
| AuroraStore | product `AuroraStore` (already) |
| F-Droid | **Droidify** substitute (owner) |
| FossifyGallery_FD | product `FossifyGallery` + override Gallery2 |
| noDefaultBrowserWebView | **US-S4-2**: drop Jelly |
| Gallery2 absent | **US-S4-2**: ensure Gallery2 gone (override alone left dir) |
| NeoLauncher / Aosmium | wont / exception — keep Launcher3 + LOS WebView |
| OpenSSH bins | US-S4-1 done |
+58
View File
@@ -0,0 +1,58 @@
# 009 AXP capability matrix (resurrection track)
Maps GOLDEN/`002` + `docs/axp-pro-parity.md` → ship status for **Magisk AXP
clone on LOS23**. Authoritative requirements remain `specs/009-axp-los23-port/spec.md`.
Status: `required` | `exception` | `deferred` | `impossible`
| category | golden_ref | status | notes |
|----------|------------|--------|-------|
| Base LOS 23.2 sunfish | `003` | required | Vanilla baseline before AXP integrate |
| microG + GSF | `002` / `004` | required | Newest stable |
| Phonesky (project patched) | `002` / `004` | required | Host artifact; FakeStore forbidden |
| Selectable signature spoofing | `005` / GOLDEN `allow_signature_fake` | required | Restricted; DO toggle |
| Selectable call-recording unlock | `008` / GOLDEN `extendrom_call_recording` | required | EXTENDROM key |
| Magisk preroot + DenyList-class | GOLDEN Magisk 29.0 / Magia | required | Newest Magisk; EXTENDROM-class boot patch |
| Bundled usability apps (Aurora, Droidify, gallery, …) | `002` / parity | required | Newest workable; **Droidify** (light + many default repos); **no NeoLauncher** |
| Private DNS presets (AXP-class provider list) | AXP Settings | required | Clone AXP private-DNS entries; no AXP OTA/repos |
| Internet connectivity / INTERNET special permission UX | AXP/Graphene-class | required | Keep behaviour; **do not** integrate `axp.os` endpoints/branding |
| Disable app (classic) vs Archive | AOSP/LOS A16 Archive | required | Restore usable **Disable** on A16; Archive alone disliked by owner |
| DNS/hosts privacy helpers | parity / GOLDEN modules `hosts` | required | If in AXP surface; Magisk module vs ROM-native TBD |
| Userspace hardening / AVB (unlocked) | parity `011`–`012` pulled into `009` | required | Staged; gaps documented; no bootloader lock |
| Release / definitive signing keys | GOLDEN / plan `/srv/rom/secrets` | required | Ship off test-keys; Phonesky same identity |
| Bootloader lock / relock | IOdes-class | wont | AXP/LOS unlocked norm; Magisk preroot assumes unlocked |
| Kernel update + hardening | parity / FR-017 | required | LOS23 sunfish kernel + attributable patches |
| WebView | GOLDEN Aosmium | exception | LOS23 WebView default; chooser unlocked; no Aosmium |
| Banking / Island / Swissquote / Yuh | `002` Gate E | deferred | Owner future (2026-09-17); not MVP |
| Localization / location hardening AXP vs LOS | owner complaint | deferred | FR-018 — **do not extra-cap** vs LOS for ship (2026-09-18); no MVP toggle; compare doc later only |
| NeoLauncher | AXP default | wont | Owner: do not integrate; LOS Launcher3 |
| F-Droid client (`org.fdroid.fdroid`) | GOLDEN | substitute | Prefer **Droidify** |
| AXP external market repos / AXP OTA servers | AXP EOL infra | wont | Servers down / EOL — do not wire |
| Sideloadable system package refresh (microG, Magisk, Phonesky, …) | owner cadence ~2–3 mo | required | FR-019 — same-signer / PRESIGNED / Magisk update path; no OTA |
| KernelSU / SusFS | `007` | deferred | Out of ship; optional recycle FR-016 |
| AXP backup ROM feature | parity | impossible / wont | External NeoBackup only |
| FLAG_SECURE global override | project `008` | deferred | Nice-to-have; not AXP hard gate |
## Bundled packages observed on GOLDEN (2026-09-17 `pm list packages -s`)
| package | role | matrix |
|---------|------|--------|
| `com.aurora.store` | Aurora | required (pin newest) |
| `com.looker.droidify` | Droidify (F-Droid client) | required — preferred over `org.fdroid.fdroid` |
| `org.fdroid.fdroid` | F-Droid | substitute / skip unless packaging forces it |
| `org.fossify.gallery` | Fossify Gallery | required |
| `com.stevesoltys.seedvault` | Seedvault | often los-provides |
| `com.android.launcher3` | Launcher | los-provides — **no NeoLauncher** |
| `org.axpos.aosmium` / `_wv` | Aosmium | exception — do not ship; LOS WebView |
| `com.google.android.gsf` | GSF | required |
| `com.android.vending` | Phonesky | required (project artifact) |
User-installed (not system): Island, banks, Magisk manager (hidden pkg), etc.
## Build oracle note
Prefer AXP **build tree + docs** on `rom-dev01` (see axpos.org developer
building / EXTENDROM preroot) to learn Magisk/product packaging. GOLDEN `adb`
is for runtime behaviour, not the first compile reference. Host currently has
rendered docs under `/srv/rom/references/axp/archive/…`; full AXP `build`
checkout still to stage.
+171
View File
@@ -0,0 +1,171 @@
# 009 CVE bisect plan (after full CVE Google-logo hang)
**Baseline GOOD:** Stage1 + combo4 + Clang FORTIFY
Artifact: `20260929T123401Z-axp-stage1-combo4` (LAB recovered 2026-09-29 via
`fastboot flash boot` of that pack’s Magisk `boot.img`).
**BAD:** Stage1+combo4+FORTIFY + full `cve-strict.list` (503)
Artifact: `20260929T181525Z-axp-stage1-combo4-cve` — compiles, wlan CRC OK,
**hangs at Google logo**. **Do not** re-flash the full 503 set.
## Audit before more flashes (2026-09-29 evening)
Owner review correctly flagged the applicator and asked for reject/partial
review **before** bisect flashes.
| Check | Result |
|-------|--------|
| Patch `FAIL` count on BAD build | **0** (`OK=503`) — no `.rej` from that run |
| Continue-on-fail + delete `.rej` | **Procedural defect** (fixed in `apply_cve_strict.sh`) — would hide incomplete applies on future drift |
| GNU patch “Succeeded with fuzz≥2” | **0** |
| Hunks with **\|offset\| ≥ 200 lines** | **168** of 503 — strong mis-apply risk even when `patch` exits 0 |
| \|offset\| ≥ 200 list | `cve-high-offset-ge200.txt` (**73 unique** paths in report extract; full 168 in host fuzz report) |
| Host report | `/srv/rom/artifacts/009-axp-los23-port/cve-stage/apply-cve-strict-20260929T173037Z-fuzz-report.txt` |
Logo hang alone does **not** identify a CVE id; “Additional Setup” is unrelated.
USB loss after sideload does **not** mean the zip was not installed.
### Applicator fix (`apply_cve_strict.sh`)
- Default: **abort** on first FAIL (no partial tree).
- Keep `*.rej` / `*.orig` under `CVE_REJECT_DIR` (no silent delete).
- **QUALITY_FAIL** if fuzz ≥ `CVE_MAX_FUZZ` (default 1) or
\|offset\| ≥ `CVE_MAX_ABS_OFFSET` (default **200**).
- Forensic only: `CVE_STRICT_CONTINUE=1`.
H1 bacon (`009-bacon-cve-h1`) **stopped** — do not flash that half until a
strict re-apply (offsets gated) produces a clean tree.
## Next method (revised)
1. Build allowlist = `cve-strict.list` **minus** high-offset (≥200) suspects
(and existing denylist).
2. Re-apply with new applicator (must finish with QUALITY_FAIL=0 / abort).
3. Bacon that “clean-offset” set → LAB boot test (**fastboot flash boot** only;
recover with Stage1 boot if needed).
4. If still BAD → classic binary bisect on the **clean** list only.
5. Separately, quarantine high-offset patches for manual review / port
(do not bulk-apply with huge offsets).
## Flash rules (LAB)
1. sunfish recovery is in `boot` — bad kernel ⇒ Recovery looks like logo loop.
2. Unbrick: `fastboot -s 11231JEC207477 flash boot <GOOD boot.img>` → reboot.
**Always** pin LAB serial. Never flash “any” fastboot device (GOLDEN risk).
3. No reboot-loop automation. No unscoped recover watchers.
4. One reboot after a deliberate flash.
## Diagnostic limits (owner review 2026-09-30)
- A BAD half **reproduces** the hang; it does **not** prove a single CVE is the
root cause (interactions / order / mis-apply semantics still possible).
- Applicator had **0 FAIL** on the original full set; abort/offset gates were
still required, but they did **not** clear this logo hang.
- Bisect flashes are **`boot.img` only** on `boot_a` (serial-pinned). No slot /
download / flash miss seen on H1a2: hang tracks what H1a2 changes vs Stage1
base. **No** demonstrated need to re-sideload full zip or wipe data for this
bisect.
- “CRC wlan OK” so far = host-side `kmalloc_caches` only (kernel
`Module.symvers` vs pack `wlan.ko`). Does **not** check all symbols nor the
on-device installed module (adb pull denied without root). Narrows one
suspicion; does **not** rule out module ABI skew.
- Next interpretation: if H1a2a boots, still test H1a2b. If **both** boot alone
but H1a2 fails → interaction/dependency, not a single-patch proof.
- **Applicability (owner 2026-10-01):** AXP A15 success ≠ correct port to
LOS23/A16 sunfish. Per [kernel CVE process](https://cdn.kernel.org/doc/html/latest/process/cve.html),
each CVE must be judged for *this* tree/config/modules — not bulk-trusted.
H1a2b includes useful fixes (USB gadget UAF, QC audio DSP bounds, F2FS
state, QRTR) but also arch/drivers off in our defconfig (x86/AMD, s390,
CAN/ATA/SAS/kprobes/brcmfmac, …). These are mostly **bugfixes**, not
transversal hardening like FORTIFY/allocator. Concrete hypothesis (unproven):
`CVE-2022-49980` (`udc_lock` on gadget events) — check whether this tree
already holds that lock on the same paths (possible deadlock). Also re-audit
F2FS patches vs exact sunfish F2FS version/deps. **In H1a2b1b list**
(not H1a2b1a).
### Code review: CVE-2022-49980 vs msm-4.14 (2026-10-01)
Patch only wraps `udc->driver` read in `usb_udc_uevent()` with
`mutex_lock(&udc_lock)`. On **our** `msm-4.14` `udc/core.c` (base
`28f9290ae067`, pre-CVE apply), `kobject_uevent()` is still invoked **while
holding `udc_lock`**:
- `usb_gadget_remove_driver()` → `KOBJ_CHANGE` (called from
`usb_del_gadget_udc` / `usb_gadget_unregister_driver` under lock)
- `udc_bind_to_driver()` → `KOBJ_CHANGE` (called from
`usb_gadget_probe_driver` under lock)
`dev_uevent` / `class->dev_uevent` run **synchronously** inside
`kobject_uevent`. `udc_lock` is a non-recursive `mutex`. Applying 49980 alone
⇒ same thread: lock → uevent → `usb_udc_uevent` → lock again ⇒ **deadlock**.
This matches community reports that backporting CVE-2022-49980 to older trees
(e.g. 5.10.y) introduces deadlock; mainline later needed **lock-scope**
changes (unbind/bind outside `udc_lock`), not the one-liner alone.
sunfish_defconfig: `CONFIG_USB_GADGET=y`, rich `CONFIG_USB_CONFIGFS_*` (ADB /
MTP / etc.) — gadget bind/unbind at boot is plausible. Still **hypothesis**
until H1a2b1b (or a 49980-only build) is LAB-tested; do **not** ship 49980
without the companion lock-order fix (or omit it from the allowlist).
**2026-10-01 evening:** 49980-only LAB = BAD (logo). Deadlock paths on this
tree include both (a) `device_add` / uevent under `udc_lock` at UDC register
and (b) `kobject_uevent` from remove/bind while lock held. Serial console /
pstore stack not captured yet — would confirm hang site; denylist stands.
## GPS
FR-018: no location lockdown.
## Status
- [x] Full CVE = BAD (logo); documented do-not-reflash
- [x] Audit apply log (0 FAIL, many huge offsets)
- [x] Fix applicator abort + keep rejects + offset/fuzz gate
- [x] Stop premature H1 bacon (full-503 halves archived `*.full503.bak`)
- [x] Clean-offset allowlist bacon + LAB boot
Artifact `20260929T203844Z-axp-stage1-combo4-cve-clean` (430 patches,
QUALITY_FAIL=0) — **BAD** 2026-09-29T20:42Z: `fastboot flash boot`
OK on `boot_a`, then Google-logo hang / USB dark (~4+ min). Recover =
Stage1 `20260929T123401Z-axp-stage1-combo4` boot only.
- [x] Clean H1 (215) bacon + LAB boot — artifact
`20260929T213532Z-axp-stage1-combo4-cve-h1` — **BAD** 2026-09-30
(logo). H1 **reproduces**; H2 untested; not a single-CVE ID yet.
- [x] H1a (108) — `20260930T075006Z-…-cve-h1a` **BAD** (logo). H1a
**reproduces**; interaction possible; module coherence not yet checked
for CVE boots.
- [x] H1a1 (54) — `20260930T084048Z-…-cve-h1a1` **BOOT_OK** 2026-09-30T19:21Z
(kernel `#38`, slot `_a`). Build-tree `wlan`/`kmalloc_caches` CRC
`0xe7ccd971` matches Stage1 Gate G (device pull of `wlan.ko` denied
without root; intra-pack CRC OK). H1a1 set alone does **not** reproduce
the hang.
- [x] H1a2 (54) — `20260930T200752Z-…-cve-h1a2` **BAD** (owner: Google logo
after flash; reproduces). H1a1 GOOD + H1a2 BAD ⇒ hang associated with
H1a2 set (still not a single id; module CRC intra-pack was Stage1-class
on prior boots).
- [x] H1a2a (27) — `20260930T213106Z-…-cve-h1a2a` **BOOT_OK** 2026-09-30T21:36Z
(kernel `#40`). Host `kmalloc_caches` match. Alone does **not** reproduce.
- [x] H1a2b (27) — `20260930T222148Z-…-cve-h1a2b` **BAD** (logo alone).
H1a2a GOOD + H1a2b BAD ⇒ hang associated with H1a2b set (not proven
single patch). Note: owner phrasing “combi” = this half failed on LAB;
interaction check already satisfied by testing halves separately.
- [x] H1a2b1 (14) — `20260930T231324Z-…-cve-h1a2b1` **BAD** (logo). Includes
`CVE-2022-49980` (udc_lock hypothesis). Set of 14 reproduces.
- [x] H1a2b1a (7) — `20261001T001808Z-…-cve-h1a2b1a` **BOOT_OK** 2026-10-01
(kernel `#43`). No `CVE-2022-49980` in this half.
- [x] H1a2b1b (7, includes `CVE-2022-49980`) —
`20261001T010705Z-…-cve-h1a2b1b` **BAD** 2026-10-01 (logo). H1a2b1a
GOOD + H1a2b1b BAD ⇒ hang associated with this 7-set (49980 still
unproven alone).
- [x] **49980-only** — `20261001T160836Z-…-cve-49980-only` **BAD** 2026-10-01
(logo). Single-patch reproduce on LAB. Added to `cve-denylist.txt`.
Do not re-apply without lock-scope companion fix.
- [x] H1a2b1b **without** 49980 (6) —
`20261001T170442Z-…-cve-h1a2b1b-no49980` **BOOT_OK** 2026-10-01
(kernel `#46`, LAB `11231JEC207477`). Confirms 49980 was the **sole**
hang trigger in the H1a2b→…→H1a2b1b BAD lineage (other six alone OK).
- [x] Clean-offset **minus 49980** (429) —
`20261001T180955Z-axp-stage1-combo4-cve-clean` **BOOT_OK** 2026-10-01
(kernel `#47`). List md5 `e05056f6…`; apply OK=429. Prior BAD 430 pack
`20260929T203844Z-…` kept. **49980 was the only logo hang** found in the
clean-offset set so far. 15m poll loop stopped after flash.
@@ -0,0 +1,83 @@
# high-offset triage 2026-10-01T18:18:58+00:00
# list=/srv/rom/src/lineage/vendor/sunfish-a16/patches/009-kernel-hardening/cve-high-offset-ge200.txt count=73
mmfs, CVE-2020-29372/^5.7/0001.patch mm: check that mm is still valid in madvise() mm/madvise.c,
other, CVE-2021-47209/^5.15/0001.patch sched/fair: Prevent dead task groups from regaining cfs_rq's kernel/sched/autogroup.c,kernel/sched/core.c,kernel/sched/fair.c,kernel/sched/rt.c,kernel/sched/sched.h,
net, CVE-2021-47299/^5.13/0001.patch xdp, net: Fix use-after-free in bpf_xdp_link_release net/core/dev.c,
offarch, CVE-2022-48825/^5.17/0001.patch scsi: qedf: Add stag_work to all the vports drivers/scsi/qedf/qedf_main.c,
net, CVE-2022-48969/^6.1/0001.patch xen-netfront: Fix NULL sring after live migration drivers/net/xen-netfront.c,
net, CVE-2022-49086/ANY/0001.patch net: openvswitch: fix leak of nested actions net/openvswitch/flow_netlink.c,
net, CVE-2022-49341/ANY/0001.patch bpf, arm64: Clear prog->jited_len along prog->jited arch/arm64/net/bpf_jit_comp.c,
mmfs, CVE-2022-49412/ANY/0001.patch bfq: Avoid merging queues with different parents block/bfq-iosched.c,
other, CVE-2022-49641/ANY/0001.patch sysctl: Fix data races in proc_douintvec(). kernel/sysctl.c,
net, CVE-2022-49687/ANY/0001.patch virtio_net: fix xdp_rxq_info bug after suspend/resume drivers/net/virtio_net.c,
net, CVE-2022-49695/ANY/0001.patch igb: fix a use-after-free issue in igb_clean_tx_ring drivers/net/ethernet/intel/igb/igb_main.c,
other, CVE-2022-49715/ANY/0001.patch irqchip/gic-v3: Fix refcount leak in gic_populate_ppi_partitions drivers/irqchip/irq-gic-v3.c,
usb, CVE-2022-50246/ANY/0001.patch usb: typec: tcpci: fix of node refcount leak in tcpci_register_port() drivers/usb/typec/tcpm/tcpci.c,
other, CVE-2022-50304/ANY/0001.patch mtd: core: fix possible resource leak in init_mtd() drivers/mtd/mtdcore.c,
net, CVE-2023-3777/^6.5/0001.patch netfilter: nf_tables: skip bound chain on rule flush net/netfilter/nf_tables_api.c,
other, CVE-2023-52486/^6.7/0001.patch drm: Don't unref the same fb many times by mistake due to deadlock drivers/gpu/drm/drm_plane.c,
other, CVE-2023-52676/^6.7/0001.patch bpf: Guard stack limits against 32bit overflow kernel/bpf/verifier.c,
other, CVE-2023-52707/^6.2/0001.patch sched/psi: Fix use-after-free in ep_remove_wait_queue() kernel/sched/psi.c,
other, CVE-2023-52847/^6.6/0001.patch media: bttv: fix use after free error due to btv->timeout timer drivers/media/pci/bt8xx/bttv-driver.c,
other, CVE-2023-53594/ANY/0001.patch driver core: fix resource leak in device_add() drivers/base/core.c,
net, CVE-2023-53669/ANY/0001.patch tcp: fix skb_copy_ubufs() vs BIG TCP net/core/skbuff.c,
other, CVE-2023-53709/ANY/0001.patch ring-buffer: Handle race between rb_move_tail and rb_check_pages kernel/trace/ring_buffer.c,
offarch, CVE-2024-2201/^6.9/0001.patch x86/bugs: Change commas to semicolons in 'spectre_v2' sysfs file arch/x86/kernel/cpu/bugs.c,
offarch, CVE-2024-24855/^6.4/0001.patch scsi: lpfc: Fix a possible data race in lpfc_unregister_fcf_rescan() drivers/scsi/lpfc/lpfc_hbadisc.c,
net, CVE-2024-26643/^6.8/0001.patch netfilter: nf_tables: mark set as dead when unbinding anonymous set net/netfilter/nf_tables_api.c,
other, CVE-2024-26900/^6.8/0001.patch md: fix kmemleak of rdev->serial drivers/md/md.c,
net, CVE-2024-39296/^6.9/0001.patch bonding: fix oops during rmmod drivers/net/bonding/bond_main.c,
mmfs, CVE-2024-40917/^6.10/0001.patch memblock: make memblock_set_node() also warn about use of mm/memblock.c,
net, CVE-2024-40923/^6.10/0001.patch vmxnet3: disable rx data ring on dma allocation failure drivers/net/vmxnet3/vmxnet3_drv.c,
net, CVE-2024-40954/^6.10/0001.patch net: do not leave a dangling sk pointer, when socket creation fails net/core/sock.c,
mmfs, CVE-2024-41014/^6.10/0001.patch xfs: add bounds checking to xlog_recover_process_data fs/xfs/xfs_log_recover.c,
net, CVE-2024-43879/^6.10/0001.patch wifi: cfg80211: handle 2x996 RU allocation in net/wireless/util.c,
net, CVE-2024-46754/^6.10/0001.patch bpf: Remove tst_run from lwt_seg6local_prog_ops. net/core/filter.c,
offarch, CVE-2024-46830/^6.11/0001.patch KVM: x86: Acquire kvm->srcu when handling KVM_SET_VCPU_EVENTS arch/x86/kvm/x86.c,
net, CVE-2024-50186/^6.12/0001.patch net: explicitly clear the sk pointer, when pf->create fails net/socket.c,
mmfs, CVE-2024-50273/^6.11/0001.patch btrfs: reinitialize delayed ref list after deleting it from the list fs/btrfs/delayed-ref.c,
mmfs, CVE-2024-53066/^6.12/0001.patch nfs: Fix KMSAN warning in decode_getfattr_attrs() fs/nfs/inode.c,
mmfs, CVE-2024-53173/ANY/0002.patch NFSv4.0: Fix a use-after-free problem in the asynchronous open() fs/nfs/nfs4proc.c,
mmfs, CVE-2024-53217/ANY/0002.patch NFSD: Prevent NULL dereference in nfsd4_process_cb_update() fs/nfsd/nfs4callback.c,
net, CVE-2024-53240/ANY/0001.patch xen/netfront: fix crash when removing device drivers/net/xen-netfront.c,
mmfs, CVE-2024-56558/ANY/0001.patch nfsd: make sure exp active before svc_export_show fs/nfsd/export.c,
other, CVE-2024-56569/ANY/0001.patch ftrace: Fix regression with module command in stack_trace_filter kernel/trace/ftrace.c,
mmfs, CVE-2024-56596/ANY/0002.patch jfs: fix array-index-out-of-bounds in jfs_readdir fs/jfs/jfs_dtree.c,
mmfs, CVE-2024-56598/ANY/0002.patch jfs: array-index-out-of-bounds fix in dtReadFirst fs/jfs/jfs_dtree.c,
net, CVE-2024-56605/ANY/0002.patch Bluetooth: L2CAP: do not leave dangling sk pointer on error in net/bluetooth/l2cap_sock.c,
mmfs, CVE-2024-56779/ANY/0002.patch nfsd: fix nfs4_openowner leak when concurrent nfsd4_open occur fs/nfsd/nfs4state.c,
offarch, CVE-2024-57849/ANY/0002.patch s390/cpum_sf: Handle CPU hotplug remove during sampling arch/s390/kernel/perf_cpum_sf.c,
net, CVE-2024-58009/ANY/0001.patch Bluetooth: L2CAP: handle NULL sock pointer in l2cap_sock_alloc net/bluetooth/l2cap_sock.c,
other, CVE-2024-58083/ANY/0001.patch KVM: Explicitly verify target vCPU is online in kvm_get_vcpu() include/linux/kvm_host.h,
mmfs, CVE-2025-21671/ANY/0001.patch zram: fix potential UAF of zram table drivers/block/zram/zram_drv.c,
net, CVE-2025-21909/ANY/0001.patch wifi: nl80211: reject cooked mode if it is set along with other flags net/wireless/nl80211.c,
net, CVE-2025-37789/ANY/0001.patch net: openvswitch: fix nested key length validation in the set() net/openvswitch/flow_netlink.c,
net, CVE-2025-37795/ANY/0001.patch wifi: mac80211: Update skb's control block key in net/mac80211/tx.c,
mmfs, CVE-2025-37839/ANY/0001.patch jbd2: remove wrong sb->s_sequence check fs/jbd2/journal.c,
other, CVE-2025-37923/ANY/0001.patch tracing: Fix oob write in trace_seq_to_buffer() kernel/trace/trace.c,
net, CVE-2025-37932/ANY/0001.patch sch_htb: make htb_qlen_notify() idempotent net/sched/sch_htb.c,
other, CVE-2025-38034/ANY/0001.patch btrfs: correct the order of prelim_ref arguments in btrfs__prelim_ref include/trace/events/btrfs.h,
other, CVE-2025-38044/ANY/0001.patch media: cx231xx: set device_caps for 417 drivers/media/usb/cx231xx/cx231xx-417.c,
net, CVE-2025-38200/ANY/0001.patch i40e: fix MMIO write access to an invalid page in i40e_clear_hw drivers/net/ethernet/intel/i40e/i40e_common.c,
mmfs, CVE-2025-38204/ANY/0001.patch jfs: fix array-index-out-of-bounds read in add_missing_indices fs/jfs/jfs_dtree.c,
mmfs, CVE-2025-38218/ANY/0001.patch f2fs: fix to do sanity check on sit_bitmap_size fs/f2fs/super.c,
other, CVE-2025-38285/ANY/0001.patch bpf: Fix WARN() in get_bpf_raw_tp_regs kernel/trace/bpf_trace.c,
net, CVE-2025-38473/ANY/0001.patch Bluetooth: Fix null-ptr-deref in l2cap_sock_resume_cb() net/bluetooth/l2cap_sock.c,
other, CVE-2025-38495/ANY/0001.patch HID: core: ensure the allocated report buffer can contain the drivers/hid/hid-core.c,
mmfs, CVE-2025-38498/ANY/0002.patch do_change_type(): refuse to operate on unmounted/not ours mounts fs/namespace.c,
other, CVE-2025-39742/ANY/0001.patch RDMA: hfi1: fix possible divide-by-zero in find_hw_thread_mask() drivers/infiniband/hw/hfi1/affinity.c,
audio, CVE-2025-39751/ANY/0001.patch ALSA: hda/ca0132: Fix buffer overflow in add_tuning_control sound/pci/hda/patch_ca0132.c,
other, CVE-2025-39824/ANY/0001.patch HID: asus: fix UAF via HID_CLAIMED_INPUT validation drivers/hid/hid-asus.c,
net, CVE-2025-39847/ANY/0001.patch ppp: fix memory leak in pad_compress_skb drivers/net/ppp/ppp_generic.c,
net, CVE-2025-39874/ANY/0001.patch macsec: sync features on RTM_NEWLINK drivers/net/macsec.c,
other, CVE-2025-39998/ANY/0001.patch scsi: target: target_core_configfs: Add length check to avoid buffer drivers/target/target_core_configfs.c,
net, CVE-2025-40078/ANY/0001.patch bpf: Explicitly check accesses to bpf_sock_addr net/core/filter.c,
mmfs, CVE-2025-40080/ANY/0001.patch nbd: restrict sockets to TCP and UDP drivers/block/nbd.c,
--- counts ---
27 net,
21 other,
18 mmfs,
5 offarch,
1 usb,
1 audio,
1 --- counts ---
+123
View File
@@ -0,0 +1,123 @@
# FORTIFY: auditoría del build 20260926T183144Z
Revisión de solo lectura en rom-dev01. Sin compilaciones ni flasheos nuevos.
El dueño confirma arranque de ksync-slab y fallo del último FORTIFY.
## Artefactos y empaquetado
Raíz remota: `/srv/rom/artifacts/009-axp-los23-port/`.
- Referencia: `20260926T171215Z-bisect-ksync-slab-only`.
- Fallido: `20260926T183144Z-bisect-ksync-fortify-only/boot-make.img`.
- SHA-256 registrado del fallido:
`89734e6a34f99bfdc2d334e06e1ff49da46dac311139b7dc54f25ae7af0f0641`.
- Ambos ramdisks desempaquetados tienen SHA-256
`c9ebabdcec875c896530214c5f2988e30a6bc37754855e4cba4863692d7db519`.
- Ambos DTB tienen SHA-256
`2fca15709ff6d9f48fea938952439e8d00c2b998c73e7a216172ae3965b07566`.
- El header del FORTIFY conserva Android 16 y parche `2026-09`.
- El script usa breakfast y exige TARGET_RELEASE=bp4a.
El problema anterior de cambiar la release/ramdisk no aparece en esta comparación.
La config embebida del fallido tiene FORTIFY=y, SLAB_FREELIST_HARDENED=n;
la referencia slab tiene las dos opciones al revés. Ambos conservan LTO y CFI.
## Hallazgo principal: la exclusión de Clang es ineficaz
En `/srv/rom/src/lineage/kernel/google/msm-4.14/security/Kconfig:190-195`:
```text
config FORTIFY_SOURCE
bool "Harden common str/mem functions against buffer overflows"
depends on ARCH_HAS_FORTIFY_SOURCE
# https://bugs.llvm.org/show_bug.cgi?id=50322
# https://bugs.llvm.org/show_bug.cgi?id=41459
depends on !CC_IS_CLANG
```
`git grep` no encuentra una definición de `CC_IS_CLANG` en ese árbol.
La config generada tampoco contiene CONFIG_CC_IS_CLANG. La restricción usa
un símbolo no definido y por ello no detecta el compilador real.
`obj/KERNEL_OBJ/include/generated/compile.h` identifica **Clang 21.0.0,
r563880c, LLD 21**, no GCC. El commit que introdujo la restricción es
`eb4c4383950d`, «fortify: Explicitly disable Clang support».
Esto demuestra un defecto de integración/configuración. No demuestra por sí
solo la instrucción concreta que provoca el fallo de arranque. Un Clang más
nuevo no sustituye automáticamente las adaptaciones del código FORTIFY.
Referencia primaria de las adaptaciones upstream: Kees Cook,
[fortify: Add Clang support, v7 8/8](https://lists.openwall.net/linux-kernel/2022/02/08/1547).
La serie adapta wrappers y atributos de tamaño de objeto; no consiste en
añadir cuerpos BUG a símbolos sin resolver. El parche AXP
`0008-Graphene-Kernel_Hardening-fortify/4.14/0004.patch`, inspeccionado, añade
comprobaciones intra-object; no aporta por sí solo ese soporte Clang.
## Segundo defecto: el error de enlace se convirtió en código ejecutable
Primer intento, log remoto
`/srv/rom/artifacts/detach-009-bisect-ksync-fortify-20260926T172516Z.log`:
```text
ERROR: "__read_overflow2" [techpack/audio/dsp/q6_dlkm.lto.ko] undefined!
ERROR: "__read_overflow" [drivers/staging/qcacld-3.0/wlan.lto.ko] undefined!
```
El script `scripts/009-bisect-ksync-one.sh` añade después a `lib/string.c`
cuatro funciones exportadas (`__read_overflow`, `__read_overflow2`,
`__read_overflow3`, `__write_overflow`) con cuerpo `BUG()`.
Así consigue enlazar, pero no resuelve por qué el compilador emite llamadas
a esos helpers, declarados para diagnóstico en `include/linux/string.h:241`.
El objeto generado `techpack/audio/dsp/q6_dlkm.ko`, desensamblado, contiene:
```text
rtac_remove_voice + 0x1d0, offset 0x673ec:
R_AARCH64_CALL26 __read_overflow2
```
El código asociado incluye la copia de elementos en `shift_voice_devices`
(`techpack/audio/dsp/rtac.c:638-644`). Falta resolver si el diagnóstico indica
un acceso real fuera de límites o un problema de los wrappers/compilador.
No convertirlo en un no-op ni aceptar BUG como solución.
**Límite importante:** el ensayo despliega solo boot y conserva los módulos
vendor previos. Esta llamada existe en el módulo recién compilado, pero no
se ha demostrado que ese módulo se cargue en LAB. Tampoco se encontraron
llamadas directas desde funciones ordinarias de vmlinux a los cuatro stubs
en la búsqueda realizada (sí sus entradas CFI y sus bucles internos).
Por tanto, no se atribuye el fallo de arranque específicamente a ese stub.
Las llamadas normales a `fortify_panic` son parte de FORTIFY y su presencia
no prueba que ninguna se ejecute durante el arranque fallido.
## Siguiente paso justificado
1. Conservar ksync-slab como referencia que arranca. No encadenar más opciones
sobre el build FORTIFY fallido.
2. Tratar FORTIFY como un port con dependencias: estudiar la implementación
AXP y adaptar soporte Clang al kernel 4.14, incluyendo detección de compilador
y pruebas de los wrappers. Corregir la detección sola bloquearía esta
opción; no equivaldría a implementar FORTIFY.
3. Retirar los stubs BUG de la receta candidata y resolver los diagnósticos
de audio/WLAN, validando la causa de cada llamada. Mantener LTO/CFI como
referencia; desactivarlos globalmente introduce otra variable y pierde
protecciones ya funcionales.
4. Archivar .config, diff, vmlinux y Module.symvers por build. Comprobar
compatibilidad con los módulos realmente desplegados, no solo uname.
5. Obtener una traza del intento fallido que distinga FORTIFY, CFI, carga de
módulos y montaje de datos. En esta revisión ADB no detecta teléfonos,
por lo que no se han leído registros actuales de LAB.
Conclusión: hay un defecto concreto de habilitación y un arreglo de enlace
inadecuado. La causa exacta en ejecución sigue pendiente; no anunciar otro
boot como reparado únicamente porque vuelva a compilar.
Plan de port (siguiente documento): `docs/009-fortify-clang-port.md`.
## Logs LAB post-fallo (2026-09-26, Cursor)
Teléfono en fastboot tras FORTIFY. Reflasheo slab-only (`boot_a`/`boot_b`) y reboot.
`/sys/fs/pstore/` vacío (0 ficheros); sin `console-ramoops` ni `last_kmsg`.
Misma ausencia de traza que en hangs Stage1/CVE previos. No hay dmesg del intento fallido.
Artefacto local vacío: `.local-artifacts/009-fortify-crash-20260926/`.
@@ -0,0 +1,87 @@
# FORTIFY bounds: enlace correcto, arranque fallido
Artefacto remoto: `20260926T223246Z-bisect-ksync-fortify-bounds` bajo
`/srv/rom/artifacts/009-axp-los23-port/`.
El dueño informa logo Google, reinicios y finalmente fastboot. El proceso
de build terminó exit=0 a las 22:32:52 UTC del 26 de septiembre.
## Verificaciones realizadas
- Los dos parches de límites están en las fuentes actuales. Audio/WLAN
ya no tienen los símbolos sin resolver `__read_overflow*` en sus objetos
LTO. Sí usan `fortify_panic`, que el kernel define y exporta normalmente.
- `lib/string.c` no tiene modificaciones/stubs; `vmlinux` no contiene los
cuatro helpers artificiales de overflow de los intentos anteriores.
- El boot descargado tiene SHA-256
`ba5ac99eb2873dac4c3c8b108753bb89e5aa7a7d71972361e32b39f6ed9ef136`,
igual al registro remoto.
- Desempaquetado local correcto: Android 16, parche 2026-09, header v2.
El kernel extraído tiene SHA-256
`99348e4f21a46c3bf95dde3a97995cd97375a6792427c5d497b3296fa0c0a906`,
idéntico al kernel nuevo y al kernel verificado en el servidor.
- Los ramdisks en los directorios remotos work/check del fallido y combo4
tienen el mismo SHA-256. Se conserva el método ksync.
## Error ignorado por el empaquetador
El log muestra que el último `magiskboot unpack` (línea 91 del script)
terminó con `Illegal instruction (core dumped)`. El `|| true` permitió
continuar y declarar DONE. Es un defecto de verificación que debe corregirse.
No demuestra que la imagen sea inválida: la copia con el mismo hash se ha
desempaquetado correctamente en el portátil y contiene el kernel esperado.
No confundir el fallo de la herramienta host con una traza del teléfono.
## Estado de LAB durante esta revisión
ADB disponible como usuario shell, sin privilegios root. LAB ya ejecuta
combo4, kernel #16, `sys.boot_completed=1`. Pstore vacío. Propiedades de
motivo de arranque: ro.boot.bootreason=reboot, sys.boot.reason=bootloader.
No identifican el fallo previo. El tramo de logcat consultado no contiene
una traza FORTIFY/CFI del intento fallido.
Intentos de leer módulos instalados en vendor devolvieron Permission denied.
Por tanto, no se ha podido comparar su ABI/CRC con el kernel fallido.
No se ha ejecutado adb root, cambiado Magisk, reiniciado ni flasheado LAB.
## Prueba adicional de eficacia de wrappers
Se extrajo el bloque FORTIFY del string.h actual a un harness temporal,
con sus wrappers y macros, tipos auxiliares y libc host. Clang r563880c,
`-O2 -flto -fuse-ld=lld`. No se añadieron stubs overflow. El handler de
fortify del harness termina con código 77 para observar el rechazo.
Directorio remoto: `/tmp/axp-fortify-runtime-9t4hrer_`.
13 casos dieron el resultado esperado:
- strlen/strnlen sobre una cadena válida, strcpy válido;
- memcpy, memmove, memset, memcmp y strncpy: tamaño 8 sobre buffers de 8
aceptado, tamaño dinámico 9 rechazado por fortify_panic.
**Límites:** ejecución host x86_64, no kernel ARM64; no prueba CFI del kernel,
wrappers restantes, todos los call sites, módulos ni arranque. El caso memcmp
usa el mismo buffer a ambos lados; no es una prueba exhaustiva de comparación.
Estas pruebas muestran protección efectiva en los casos probados, no que el
port completo sea correcto.
## Lo que falta para atribuir el fallo
La corrección de límites resolvió el enlace, que era su alcance probado.
No se ha identificado la instrucción que detiene el arranque. Encontrar
llamadas a fortify_panic en el binario (incluso en funciones de inicio) es
normal y no demuestra que se ejecuten durante el fallo.
Prioridad: preparar una captura de fallo utilizable antes del próximo ensayo.
Comprobar en la referencia funcional el acceso y funcionamiento de pstore/
ramoops, incluido el mecanismo del dispositivo que procesa sus registros.
Un arranque de diagnóstico puede instrumentar fortify_panic para registrar
caller/backtrace conservando su comportamiento de fallo; también debe poder
distinguir una caída CFI, un watchdog y un fallo de módulos. Esa instrumentación
sin un canal persistente/serial verificado no garantiza obtener evidencia.
Conservar combo4 como referencia aceptada. No habilitar FORTIFY para ship,
ni atribuir el fallo a un controlador concreto, ni reintroducir stubs/no-ops
a partir del solo síntoma del logo. Revisar después compatibilidad de módulos
y los call sites identificados por una traza real.
Plan de captura (siguiente documento): `docs/009-fortify-diag-capture-plan.md`.
+98
View File
@@ -0,0 +1,98 @@
# FORTIFY + Clang en msm-4.14 (plan de port)
Documento de preparación. No es un parche listo. Relacionado:
`docs/009-fortify-boot-audit-20260926.md` (diagnóstico del fallo LAB).
## Hechos ya cerrados
| Hecho | Evidencia |
|-------|-----------|
| Packaging ksync OK | Ramdisk/DTB idénticos a slab; patch `2026-09` |
| FORTIFY one-CONFIG tumba arranque | LAB → reinicios → fastboot; pstore vacío |
| DMESG / SLAB / INIT_ON_ALLOC / INIT_ON_FREE solos OK | Bisect ksync 2026-09-26 |
| `depends on !CC_IS_CLANG` es inútil aquí | `CC_IS_CLANG` **no existe** en msm-4.14; el build usa Clang 21 + LTO/CFI |
| Stubs `__read_overflow*` + `BUG()` | Anti-patrón: enlazan pero dejan llamadas reales (p.ej. `q6_dlkm` → `__read_overflow2`). **No reutilizar** |
| AXP `fortify/4.14/0004.patch` | Solo intra-object (`FORTIFY_SOURCE_STRICT_STRING` / Micay). **No** aporta soporte Clang |
## Qué hace falta (upstream, no inventado)
Serie Kees Cook *fortify: Add Clang support* (v7, 2022-02), mergeada en kernels
modernos. Idea central:
1. Atributos Clang: `__pass_object_size`, `__overloadable`, `__diagnose_as`
(en `compiler_attributes.h`).
2. Wrappers FORTIFY adaptados para que `__builtin_object_size(p, 1)` funcione
desde inlines (en kernels nuevos: `include/linux/fortify-string.h`).
3. Kconfig: `depends on !CC_IS_CLANG || CLANG_VERSION >= 120001` (y exclusiones
arch específicas). Clang 21 cumple la versión; falta el código.
Referencias:
- Cover: <https://lists.openwall.net/linux-hardening/2022/02/08/7>
- Commit ilustrativo: `281d0c962752` (*fortify: Add Clang support*)
- Antecedente del disable: `a52f8a59aef4` / bugs LLVM 41459, 50322
En **4.14** el FORTIFY vive todavía dentro de `include/linux/string.h` (no hay
`fortify-string.h`). El backport no es un cherry-pick limpio: hay que adaptar
los wrappers al layout 4.14 o traer la separación de headers con cuidado.
## Detección de compilador (paso previo pequeño)
Sin `CC_IS_CLANG` / `CLANG_VERSION` en Kconfig, cualquier `depends on !CC_IS_CLANG`
es no-op. Antes o junto al port de wrappers:
1. Backport mínimo de los símbolos Kconfig que usan árboles Android/comunes
modernos (`CC_IS_CLANG`, `CLANG_VERSION`) **o** equivalencia documentada
vía `scripts/Kconfig.include` / Makefile del árbol.
2. Con eso solo + `depends on !CC_IS_CLANG`: FORTIFY queda **apagado** con
Clang — correcto, pero no da hardening. Sirve como red de seguridad para
no volver a activarlo “por accidente”.
## Camino de implementación propuesto (orden)
1. **Quitar stubs** de `009-bisect-ksync-one.sh` (o dejarlos detrás de un
flag explícito `ALLOW_FORTIFY_BUG_STUBS=1` no usado por defecto). Un
FORTIFY que no enlace sin stubs = señal de que el port está incompleto.
2. **Introducir detección Clang** en Kconfig (paso pequeño, testeable).
3. **Port wrappers Clang** al `string.h` 4.14 (o split a `fortify-string.h`
si el diff queda más limpio), tomando la serie Kees como fuente, no stubs.
4. **Build ksync** solo `CONFIG_FORTIFY_SOURCE=y` (sin STRICT_STRING al
principio). Criterio de éxito: modpost **sin** undefined
`__read_overflow*` y sin exportar cuerpos `BUG()`.
5. Si aparecen llamadas residuales en audio/WLAN: tratar cada una como bug
de tamaño/objeto o fallo del wrapper — no enmascarar.
6. Flash LAB (mismo método ksync / GOODMAKE). Solo entonces valorar
`FORTIFY_SOURCE_STRICT_STRING` (AXP 0004) encima.
7. Reintroducir FORTIFY en el combo defconfig OK (DMESG+SLAB+INIT_ON_*).
Fuera de alcance de este port: desactivar LTO/CFI globales “para que compile”
(introduce otra variable y pierde protecciones ya validadas).
## Qué no es “clonar AXP” aquí
AXP aporta el parche Graphene de **strict string** sobre un FORTIFY que ya
debe ser válido con el toolchain del producto. En LOS23/sunfish el toolchain
es Clang+LTO; el vacío es el **soporte Clang de FORTIFY**, no el 0004.
Hasta tener (3)+(4), no marcar FR-017 FORTIFY como listo.
Nota (búsqueda host): el `0008-…-fortify/5.15/0006.patch` AXP (*rewrite
fortify source for 5.15 gki*) también es strict-string sobre
`fortify-string.h` ya existente — no sustituye la serie Kees de Clang.
## Estado
- **LAB combo4 OK** (2026-09-26): `#16`, DMESG+SLAB+INIT_ON_ALLOC+INIT_ON_FREE, sin FORTIFY.
- Stubs BUG gated off en ksync (`ALLOW_FORTIFY_BUG_STUBS`).
- Port en curso: `vendor/.../fortify-clang/apply_fortify_clang.py`.
- **fortify-pos0 FAIL 2026-09-26T21:54Z:** modpost
`__read_overflow*` undefined en `q6_dlkm.lto.ko` / `wlan.lto.ko`.
**vmlinux/Image.lz4 sí generaron** (sin esos U en el núcleo). El port POS0
no basta aún para módulos LTO; no reintroducir stubs.
Siguiente: localizar call sites (p.ej. rtac) o `__NO_FORTIFY` puntual /
más del port Kees — no ACCEPT hasta harness + link limpio.
- **Ensayo 2026-09-26T22:06Z:** POS0 + bounds (`rtac`/`lim_process_fils`) en
job `009-bisect-ksync-fortify-bounds`. Log:
`detach-009-bisect-ksync-fortify-bounds-20260926T220634Z.log`.
**Build OK / LAB FAIL:** logo Google → reboot. Reflasheo a combo4.
Bounds resolvieron el link; no bastan para arrancar. FORTIFY sigue
aparcado para ship hasta traza o port más completo + harness.
+240
View File
@@ -0,0 +1,240 @@
# Plan: captura verificable del fallo FORTIFY
> Revisión posterior: [auditoría del diagnóstico del 27/09](009-fortify-diag-review-20260927.md).
> El «canal VERIFICADO» de abajo solo demuestra parte de la persistencia:
> SysRq-x puede dejar la misma marca que se observa tras SysRq-c. Además, el
> escritor no funciona antes de ramoops_probe. La ausencia de AXPDIAG1 tras
> fortify-diag **no descarta fortify_panic**, ni demuestra watchdog. Se conserva
> abajo el historial original de las pruebas.
Parte de `docs/009-fortify-bounds-boot-failure-20260927.md`.
Referencia LAB: combo4 `#16` (sin FORTIFY). No flashear diagnóstico hasta
tener canal de captura comprobado en esa referencia.
## Hallazgos en combo4 (2026-09-27, solo lectura)
| Señal | Valor |
|-------|--------|
| boot_completed | 1 |
| pstore montado | sí, vacío |
| last_kmsg / debugfs | no accesibles como shell |
| Magisk / su | no activos (virgin AXP) |
| cmdline | `console=null`, `androidboot.ramdump=disabled` |
| config | `CONFIG_PSTORE=y`, `PSTORE_RAM`, `PSTORE_CONSOLE`, `ACCESS_RAMOOPS` |
| bootreason tras recover | `reboot` / `bootloader` (no identifica el panic FORTIFY) |
Conclusión: el kernel **tiene** pstore/ramoops, pero LAB no entrega traza
útil tras el reboot a fastboot. Cambiar más CONFIGs sin canal de evidencia
repite el bucle anterior.
## Objetivo del arranque de diagnóstico
Distinguir, con registro persistente o serial:
1. `fortify_panic` (caller + backtrace)
2. fallo CFI
3. watchdog / softlockup
4. fallo de carga de módulos / ABI
Sin eso, no atribuir el logo Google a audio/WLAN ni a FORTIFY genérico.
## Pasos (orden)
1. **Canal de captura en combo4 (sin FORTIFY)**
- Confirmar cómo Pixel 4a/sunfish expone ramoops tras panic
(`ACCESS_RAMOOPS`, partición `klog`/`logfs`, `ramdump=disabled`).
- Probar un panic controlado mínimo en un boot **solo diagnóstico**
(no ship) y verificar que shell/root puede leer
`/sys/fs/pstore/console-ramoops*` tras el siguiente arranque bueno.
- Alternativa: UART/serial o `androidboot.console` no-null si el lab lo
permite. Si el canal falla, no flashear FORTIFY otra vez.
2. **Instrumentar `fortify_panic`** (solo en árbol de ensayo)
- Antes del `BUG()`: `pr_emerg` con `%pS` del return address + stack.
- Mantener el panic (no convertir en no-op).
- Misma receta ksync (GOODMAKE + kernel FORTIFY+POS0+bounds).
3. **Marcas CFI / módulos**
- Si el log muestra CFI: seguir esa vía.
- Si aparece durante `insmod`/init de vendor: comparar CRC/ABI de
módulos (requiere root o dump desde recovery).
- Si watchdog sin fortify/CFI: otra clase de hang.
4. **Empaquetador**
- Quitar el `|| true` que traga el SIGILL de `magiskboot` en VERIFY, o
verificar el header en el laptop con el mismo SHA. Defecto de script,
no causa del reboot (imagen unpack OK en laptop).
5. **Solo después** de una traza atribuible: cambio mínimo (call site,
excepción justificada, o más port). No stubs. No ship FORTIFY.
## Estado 2026-09-27 (tras Rooted debugging)
- `adb root` OK.
- `vendor.ramoops.decryption.error=1` en boot normal.
- Causa 1: `/vendor/bin/ramoops` hardcodea
`/sys/devices/soc/.../size` pero el kernel expone
`/sys/devices/platform/soc/...` (y vía `/sys/class/misc/.../size`).
Binario parcheado en `/data/local/tmp/ramoops.fix` para class paths.
- Causa 2: tras eso, kernel log `ramoops: Failed to set key, -22` (EINVAL)
al escribir AES en sysfs. pstore sigue vacío. Remount pstore denegado por SELinux.
- Claves RSA sí existen en `/data/vendor_ce/0/ramoops/{priv,pub}.pem`.
- `boot_debug/crash.txt` es basura userspace antigua, no kernel FORTIFY.
- Build `fortify-diag` (panic instrumentado) sigue en curso.
## Captura post fortify-diag (2026-09-27 ~01:36)
Tras flash diag → fallo → recover combo4 `#16` + `adb root`:
- pstore vacío; `boot_debug/kernel.txt` vacío; sin `FORTIFY_DIAG` en claro.
- Dump `/dev/access-ramoops` (4 MiB): entropía alta (cifrado); 0 strings útiles.
- Decrypt sigue fallando (`Failed to set key, -22`).
Prueba de canal con **SysRq-c** en combo4:
- Bootloader registró `androidboot.bootreason=kernel_panic` (panic real).
- **Aun así** pstore vacío y alt cifrado sin plaintext.
Conclusión: en este LAB un `kernel_panic` **no** produce traza legible vía pstore
hasta arreglar el pipeline AES/ramoops. El síntoma FORTIFY (antes del SysRq)
había dejado `bootreason=reboot`/`bootloader`, no `kernel_panic` — hipótesis
abierta: reset/wdog distinto de `fortify_panic`, o el bootloader reescribe el
motivo al pasar por fastboot.
Siguiente trabajo de captura: diag **sin cifrado** (pstore/ramoops plaintext)
o arreglo del setkey; no más flashes FORTIFY hasta tener canal verificado con
SysRq → fichero legible en pstore.
## Captura plaintext (2026-09-27 ~01:45)
Hallazgos en combo4 tras Rooted debugging + reboot sin unlock:
| Señal | Valor |
|-------|--------|
| `dumpsys user` | `RUNNING_LOCKED`, Unlock time unknown |
| `sys.user.0.ce_available` | vacío |
| `/data/vendor_ce/0/ramoops` | `Required key not available` |
| `mount \| grep pstore` | vacío tras `on boot` umount |
| Remount manual `pstore` + `use_alt=0` | monta OK, **sigue sin ficheros** |
| `/dev/pmsg0` + reboot | no aparece `pmsg-ramoops-*` |
| SysRq-c | `bootreason=kernel_panic`, alt cifrado, primary vacío |
Causa de sistema (no solo FORTIFY):
1. `init-ramoops.rc` hace `umount /sys/fs/pstore` en `on boot` y solo remonta
cuando `vendor.ramoops.decrypted=true` (tras CE unlock + `ramoops -D`).
2. Binario `/vendor/bin/ramoops` usa paths sysfs pre-`platform/` → size=-1;
con binario parcheado a class paths, CE locked → sin `priv.pem`.
3. Writes de pstore van al **primary**; el carveout que sobrevive/lee userspace
tras decrypt es el **alt** cifrado (`/dev/access-ramoops`).
4. `ramoops_init_prz` hace `persistent_ram_zap(primary)` tras `save_old` en
console/pmsg — el pipeline asume encrypt-on-shutdown a alt.
Canal de evidencia (sin CE / sin AES): patch diag
`ramoops_axp_plaintext_alt` — en DMESG oops/panic escribe magic `AXPDIAG1` +
cuerpo en claro al **alt** (ioremap). Verificación LAB:
```text
dd if=/dev/access-ramoops bs=1M count=4 | strings | grep -E 'AXPDIAG1|Kernel panic'
```
Build canal (sin FORTIFY): `scripts/009-bisect-ksync-pstore-alt-plain.sh`
(`PSTORE_ALT_PLAIN=1`). Probar SysRq → magic legible **antes** de otro flash
FORTIFY.
### Iteración 2 (ioremap en panic)
- Alt carveout **sí** persiste: write userspace `AXPUSER1` → reboot → sigue ahí.
- Build `20260927T001522Z` con mirror vía `ioremap_wc` **en** `ramoops_pstore_write`
(contexto panic/atomic): SysRq → `bootreason=kernel_panic` pero **sin** `AXPDIAG1`
(ioremap no es safe ahí; write silencioso no-op).
- Fix: pre-map en `ramoops_probe` (`axp_alt_va`) + solo `memcpy_toio`/`wmb` en panic.
Rebuild: job `009-bisect-ksync-pstore-alt-plain2`.
- plain2: map OK + SysRq `kernel_panic`, sin `AXPDIAG1` (aliasing WC vs `ioremap`).
- plain3: `AXPDIAG0-probe` legible tras boot (kernel→alt OK). Tras SysRq solo
`AXPDIAG0` — el hook DMESG pstore no corre en este panic path.
- plain4: `panic_notifier` + `AXPDIAG1-panic-notifier`, pero el boot siguiente
reescribía `AXPDIAG0` encima. Fix: no clobber si head=`AXPDIAG1`.
Rebuild: `pstore-alt-plain5`.
### Canal VERIFICADO (plain7, `20260927T024949Z`)
| Prueba | Resultado |
|--------|-----------|
| `echo x > /proc/sysrq-trigger` (sin panic) | `AXPDIAG1-sysrq-fixed` en `/dev/access-ramoops` |
| sysrq-x + `adb reboot` | `AXP alt keeps prior AXPDIAG1 capture` |
| sysrq-x + sysrq-c → `bootreason=kernel_panic` | magic `AXPDIAG1` sobrevive (cuerpo a veces truncado por reset) |
| Metadata `/dev/access-metadata` tras panic | reescrita (claves AES); no usar |
Lectura post-fallo (root, no hace falta unlock CE):
```text
adb root
dd if=/dev/access-ramoops bs=1M count=4 | strings | grep AXPDIAG
dmesg | grep AXP
```
## v4 canal (post review v3 2026-09-27)
Ver `docs/009-fortify-diag-v3-review-20260927.md`. v3 obsoleto: `ioremap`
tras `paging_init` (antes de slab/vmalloc) puede tumbar el control sin
FORTIFY; attrs early cached vs IO; milestones compartían slots con el fallo.
`apply_fortify_diag.py` **v4**:
- Early: `early_ioremap` (FIXMAP_PAGE_IO) antes de `parse_early_param`; se
mantiene hasta después de `mm_init`. Permanente: `ioremap` **solo** tras
`mm_init`. Handler nunca mapea.
- Layout página 0: fallo @0 (+ mirrors); milestones @2048 (zonas separadas).
- Adoptar fallo previo solo si registro **completo** (header + `\\n` + mirror).
- Ciego residual: pre-`early_map`; ventana breve al cambiar early→perm si el
VA se publica mal (v4 publica permanente antes de retirar early).
Validación control (sin FORTIFY) — media/tardía; no prueba pre-`early_map`:
0. Wipe zona fallo: `dd if=/dev/zero of=/dev/access-ramoops bs=4K count=1`
1. Flash `pstore-alt-plain` v4, boot, `adb root`.
2. Milestones: `strings | grep AXPDIAG0` → `...,early_map` / `perm_map` /
`mm_init` (offset distinto; pueden coexistir con un AXPDIAG1).
3. **Solo** SysRq-c (sin `x`).
4. Recover combo4 → `AXPDIAG1,C,<attempt>,0x...,sysrq-c` completo.
5. Solo entonces fortify-diag v4.
### Review resultados v4
Ver `docs/009-fortify-v4-capture-results-review-20260927.md`,
`docs/009-fortify-v4-clean-tests-verification-20260927.md`, y artefactos:
- `.local-artifacts/009-v4-clean-c-20260927T190738Z/`
- `.local-artifacts/009-v4-x-persist-20260927T191143Z/`
- `.local-artifacts/009-v4-twophase-x-then-c-20260927T191809Z/` (adb
readback then panic: pre-verified X lost by P3)
### LAB 2026-09-27 (plain-v4 `20260927T084531Z`) — hechos vs hipótesis
**Demostrado**
- Writer de first-failure en vivo: SysRq-x →
`AXPDIAG1,X,20260927T084531Z,0x...,sysrq-x` @0 (+ mirrors).
- Milestone slot @2048 recibe `AXPDIAG0,M,...,panic_reg` (último stage;
sobrescribe stages previos en el mismo offset).
- Tras SysRq-c (arranque sin `x` previo) + recover combo4: **no** hay
`AXPDIAG1` en ninguno de los 8 slots de fallo; @0 es opaco.
**No demostrado / correcciones**
- **No** hay, en el código revisado, una rutina de *cifrado del alt al
entrar en panic*. Sí hay camino de descifrado del alt. «Desactivar
encrypt en el kernel» no apunta aún a una función identificada; no usar
eso como siguiente paso.
- Que `panic_reg` aparezca @2048 tras combo4 **no** prueba zona segura ni
supervivencia al panic: combo4 no escribe `AXPDIAG*`, pero un arranque
intermedio de **v4** regenera el mismo `panic_reg` con el mismo attempt
id. Hace falta attempt id distinto por boot, o wipe + leer sin otro boot
v4, antes de atribuir persistencia.
- El latch `axp_first_latch` es **solo RAM**: un wipe del dump no lo
resetea. Si en el mismo arranque se hace SysRq-x y luego SysRq-c, `c`
no escribe. Las pruebas `c`-only válidas requieren wipe **y reboot**
(o imagen nueva) sin `x` previo en ese boot.
- Causa de @0 opaco tras `c` (sobrescritura, fallo de escritura, otro
productor): **abierta**.
+119
View File
@@ -0,0 +1,119 @@
# FORTIFY diagnostic review — 2026-09-27
## Conclusion
The boot failure remains unresolved. The latest capture does **not** exclude
`fortify_panic`, and does not establish a watchdog reset. The diagnostic channel
has an early-boot blind spot and its documented panic validation admits a stale
marker. Fix these experimental controls before interpreting another empty dump.
Review covered the Cursor transcript, local patch scripts and capture plan,
remote kernel sources/build artifacts, saved diag2 dump and installed LAB
modules. No flashing, rebooting, live source changes or new builds were performed
in this review.
## Experiment history and what it establishes
1. Original defconfig bisects also changed bp4a to bp2a (security patch and
platform version regression). Those experiments did not isolate hardening.
2. Corrected ksync packaging retained GOODMAKE's boot environment. Combo4 boots
with DMESG restriction, slab freelist hardening and allocation/free clearing.
3. FORTIFY required a Clang port. Exported overflow BUG stubs were removed;
pass_object_size was aligned to the wrappers' object-size mode 0.
4. The audio/WLAN overflow-helper link failures were localized to specific
functions. Explicit array-capacity guards resolved the targeted compilation
failures. Successful linking does not establish runtime correctness of the
port, or prove those drivers caused the subsequent boot failure.
5. Bounds FORTIFY boots still failed. Diagnostics then added caller printing,
stack dumping and a plaintext marker in the alternate ramoops region.
6. Plain-channel iterations tested mapping, probe overwriting, a panic notifier
and SysRq writes. These are useful channel experiments, but the recorded
plain7 result is insufficient to validate fresh panic-time writes.
7. Latest diag2 (`20260927T032419Z-bisect-ksync-fortify-diag`) failed to boot;
recovery used combo4. No readable failure record has been obtained.
## Confirmed diagnostic defects
### 1. Capture starts too late to exclude an early FORTIFY failure
`apply_fortify_diag.py` maps the alternate region only at the successful end of
`ramoops_probe`. Remote `fs/pstore/ram.c:1270` performs the mapping;
`ramoops_init` is a `postcore_initcall` at line 1365. The writer immediately
returns if `axp_alt_va` is null (patch script lines 105–106).
Remote `init/main.c` calls `setup_arch` at 565 and `parse_early_param` at 579,
before `rest_init` at 738 and the later `do_basic_setup` / `do_initcalls` path.
Disassembly of the current FORTIFY vmlinux contains branches to fortify_panic:
```text
parse_early_param: ffffff8012290974 -> ffffff8011ac186c
start_kernel: ffffff8012290fb8 -> ffffff8011ac186c
setup_arch: ffffff8012296750 -> ffffff8011ac186c
```
These are possible failure paths, **not evidence that any executed**. They
demonstrate that an instrumented FORTIFY failure can occur while the persistent
writer is unavailable. A SysRq test from a fully booted system cannot validate
that interval.
### 2. Plain7's positive control can accept an old marker
The capture plan records `sysrq-x + sysrq-c` followed by survival of the magic
`AXPDIAG1`, sometimes without the complete body. SysRq-x already writes that
magic. The next probe explicitly preserves it. Therefore magic survival alone
does not prove that SysRq-c or the panic notifier wrote anything new.
Require a distinct per-attempt identifier and a complete panic-specific record,
different from the pre-panic marker. Validate the exact failed-boot → fastboot
→ rescue-image → dump sequence, not just a normal reboot into plain7.
### 3. The durable record follows operations that may fail
The injected `fortify_panic` first calls `pr_emerg` and `dump_stack`, then writes
the persistent mark (patch script lines 36–39). A failure or recursion in those
operations could prevent the mark. The durable body contains only the helper
name, not the caller address printed to the unavailable console. Subsequent
panic-notifier and pstore writes also target the same slots and can overwrite
the first record.
Record the first failure before formatted output; include a raw caller address,
event type and attempt identifier. Preserve the first record. Use a minimal
writer independent of the fortified helpers under investigation. This still
requires a correctly reserved/mapped region available at the tested boot stage;
moving the call alone does not fix defect 1.
## Additional checks
- Latest local boot SHA-256 matches the remote published boot:
`a5be43617770205bb9a2d2ad5989ca566ad9713134e7210c585f02fd7bdea554`.
- Current build configuration enables FORTIFY, Clang LTO, Clang CFI and
MODVERSIONS.
- Read-only comparison of all 41 installed vendor `.ko` files against current
remote `Module.symvers`: **3,182 version entries, zero CRC mismatches, zero
missing symbols**. This checks symbol version compatibility only; it does not
prove all runtime ABI/CFI behavior is correct or identify the crashing code.
- LAB was recovered and running combo4 kernel #16 with `sys.boot_completed=1`.
- Saved diag2 `access-ramoops.bin` is 4 MiB and contains none of `AXPDIAG0`,
`AXPDIAG1`, `FORTIFY`, `DBGC` or `Oops`. Measured byte entropy is approximately
7.99996 bits/byte. This does not uniquely distinguish encryption, overwritten
contents or other high-entropy data, nor prove no panic occurred.
- `bootreason=reboot` observed after rescue is not a preserved trace of the
original failure and cannot exclude a panic in the earlier attempt.
## Next experiment requirements
1. Preserve combo4 and archive each diagnostic patch, config, vmlinux and hashes.
2. Validate fresh, distinguishable failure records with an otherwise booting
control. Test persistence across the same recovery sequence used in practice.
3. Cover the early interval explicitly: use a board-supported early output or
correctly reserved early persistent writer, with initialization milestones.
Do not insert ordinary ioremap calls into arbitrary early/panic context.
4. Validate an intentionally triggered diagnostic event at the boot stage being
tested. A late SysRq control alone is insufficient.
5. Only then repeat FORTIFY with a first-failure record containing a caller and
symbolize it using the exact vmlinux. If no reliable early channel is
achievable, use controlled localization experiments and label them as such;
do not promote them to a working or complete hardening port.
Do not add overflow stubs, suppress fortify_panic or declare watchdog/CFI the
cause solely because the current capture is empty.
@@ -0,0 +1,60 @@
# Diagnostic v2 review — 2026-09-27
Reviewed local `apply_fortify_diag.py` and generated remote
`kernel/axp_diag_capture.c` with attempt `20260927T083401Z`, while the plain-v2
control build was running. No live sources or build jobs were changed.
The direction is useful: record before printing, include event/caller/build
identifier, and validate SysRq-c without first writing SysRq-x. However, this
implementation is not yet a validated early-boot recorder.
## Required corrections
1. **Do not map from the failure handler.** `axp_diag_mark_event` calls
`axp_diag_map`, which calls ordinary `ioremap` if no mapping exists. This
reintroduces mapping in panic/early context. In this tree ARM64 ioremap uses
`get_vm_area_caller` and `ioremap_page_range`; mm_init initializes the slab
allocator and vmalloc. Mapping after successful mm_init is a reasonable
later-stage control, but the failure handler must not try to compensate for
an earlier failure with that same ordinary mapping path.
2. **The previously identified early interval is still uncovered.** Remote
`init/main.c` calls setup_arch at 565 and parse_early_param at 579; mm_init
and the new hook are at 600–604. A successful late SysRq test does not
validate a failure in either earlier function or inside mm_init itself.
3. **First-failure retention is not guaranteed.** `axp_first_done` is a plain
integer tested before recording and set only after the writes. Concurrent
CPUs or recursion can both pass the test. The event writer does not inspect
an existing persistent record, despite the stated promise to preserve one;
only the milestone writer does. Use a deliberate atomic/reentrancy protocol
and an explicit policy for records from previous boots. A build timestamp
distinguishes builds, not repeated attempts with the same image.
4. **Milestone format contains an embedded NUL.** The literal `AXPDIAG0,M,`
is 10 characters, but memcpy copies 11 and advances by 11. This copies the
string terminator before the attempt identifier. Consequently `strings |
grep AXPDIAG0` loses the attempt/stage from the same line. Use the literal's
length excluding its terminator (for example sizeof(literal)-1).
## Validation scope
A complete new `C` record surviving the actual combo4 recovery sequence would
be useful evidence for late panic capture. It would not establish early-boot
coverage. Require the exact expected identifier and complete record; define
how previous records are archived/cleared before repeating the same image.
Keep the first failure separate from milestones and subsequent notifier events.
The capture implementation still includes linux/string.h and memcpy calls;
verify the final ARM64/LTO generated writer does not depend on the FORTIFY
failure path under test. `no_sanitize("cfi")` alone does not disable FORTIFY.
Do not interpret an empty capture from this v2 as proof against fortify_panic.
## Status
Local `apply_fortify_diag.py` updated to **v3** addressing items 1–4
(no map-from-handler; early+perm maps in `setup_arch`; atomic latch + durable
head check; milestone `sizeof(lit)-1`). Residual pre-`early_map` blind spot
remains documented in the capture plan. plain-v2 build is obsolete — rebuild
control as plain-v3 before flash.
@@ -0,0 +1,68 @@
# Diagnostic v3 review — 2026-09-27
Checked the local generator and remote generated kernel/axp_diag_capture.c,
attempt 20260927T084106Z, while plain-v3 was building. No build cancellation,
source modification on the server, or device operations were performed.
## Corrected
- Failure handler no longer maps memory.
- Event claim uses atomic_cmpxchg before composing the record.
- Event path checks a previous persistent AXPDIAG1 header.
- Milestone prefix length excludes the terminating NUL.
- Explicit byte I/O replaces memcpy on the MMIO writer path.
- Early mapping now precedes parse_early_param in ARM64 setup_arch.
## Blocking issue: permanent mapping before allocators exist
The new setup.c hook at lines 398–402 calls axp_diag_map_permanent immediately
after paging_init. This is still inside setup_arch, before start_kernel calls
mm_init. It even precedes bootmem_init in setup_arch.
axp_diag_map_permanent releases the early map and calls ordinary ioremap.
In this tree, arch/arm64/mm/ioremap.c calls get_vm_area_caller, which reaches
mm/vmalloc.c:1405 __get_vm_area_node and kzalloc_node at line 1421, followed by
alloc_vmap_area. The allocator initialization (mem_init, kmem_cache_init,
vmalloc_init) occurs later in init/main.c:mm_init.
Thus paging_init is NOT the readiness gate for ordinary ioremap. This diagnostic
can introduce its own boot failure in the no-FORTIFY control. Do not use a
failure of this control to draw conclusions about FORTIFY.
The transition needs a deliberate lifetime plan: ordinary mapping only after
its allocators are ready, and safe retirement of the early mapping respecting
early_ioremap_reset. Simply relocating one call without checking that lifetime
is insufficient. If a temporary uncovered interval is chosen, document it and
ensure failure writers cannot dereference a stale early mapping.
## Mapping attributes and persistence
early_memremap uses FIXMAP_PAGE_NORMAL, whereas the permanent ioremap and
access-ramoops use PROT_DEVICE_nGnRE. This changes memory attributes. The writer
only uses wmb and a readback; it has no explicit cache maintenance for a cached
early mapping. These operations alone do not establish that early cached writes
reach reset-surviving memory. Review compatible early I/O mapping attributes
(early_ioremap uses FIXMAP_PAGE_IO in this tree) and verify on hardware.
## Remaining first-record limitations
- Milestones check the latch but do not participate in its atomic claim. A
milestone interrupted by a failure writer can resume and overwrite the same
slots. Separate milestone storage from first-failure storage, or use a
protocol that also covers milestones and reentrancy.
- A bare eight-byte header is treated as a complete prior failure. An interrupted
write that persisted only that header can suppress later captures. Validate a
complete record/commit indication and inspect mirrors.
- The identifier remains per build, not per boot; archive/clear old captures
under an explicit test procedure before repeating the same image.
The improvements are real, but v3 is not yet ready to be described as a
validated early-capture channel. These findings concern instrumentation, not an
identified cause of the original FORTIFY boot failure.
## Status
Local generator updated to **v4**: no `ioremap` until after `mm_init`; early
map uses `early_ioremap` (IO attrs) and is kept until then; failure @0 vs
milestones @2048; adopt only complete records. plain-v3 must not be flashed —
rebuild control as plain-v4.
@@ -0,0 +1,27 @@
--- a/techpack/audio/dsp/rtac.c
+++ b/techpack/audio/dsp/rtac.c
@@ -652,6 +652,12 @@
pr_debug("%s\n", __func__);
mutex_lock(&rtac_voice_mutex);
+ if (rtac_voice_data.num_of_voice_combos > ARRAY_SIZE(rtac_voice_data.voice)) {
+ pr_err("%s: invalid voice count %u\n", __func__,
+ rtac_voice_data.num_of_voice_combos);
+ mutex_unlock(&rtac_voice_mutex);
+ return;
+ }
/* look for device */
for (i = 0; i < rtac_voice_data.num_of_voice_combos; i++) {
if (rtac_voice_data.voice[i].cvs_handle == cvs_handle) {
--- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_fils.c
+++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_fils.c
@@ -1092,6 +1092,9 @@
return false;
}
+ if (dot11f_ie_rsn.pmkid_count > ARRAY_SIZE(dot11f_ie_rsn.pmkid))
+ return false;
+
for (i = 0; i < dot11f_ie_rsn.pmkid_count; i++) {
if (qdf_mem_cmp(dot11f_ie_rsn.pmkid[i],
pe_session->fils_info->fils_pmkid,
+127
View File
@@ -0,0 +1,127 @@
# FORTIFY family bisection — 2026-09-27
## Why this experiment
The two-phase X-then-C experiment establishes loss of an adb-verified record
somewhere in the panic/reboot sequence. Further recovery-channel engineering
has not identified the original FORTIFY boot failure. This experiment instead
isolates the protection families while leaving panic behavior intact.
This is diagnostic-only: a boot with one family is not a completed FORTIFY port
and must not be promoted into the shipping hardening configuration.
## Independent analysis before build
- Reconstructed symbols from the saved failed bounds kernel #19, rather than
inspecting the live output overwritten by later no-FORTIFY diagnostic builds.
- Found 372 direct branches to fortify_panic, including its CFI jump-table
entry. Their presence alone does not prove execution. Inspected early
start_kernel/setup_arch checks; no demonstrated unconditional failure found.
- Recompiled init/main.c, arch/arm64/kernel/setup.c and lib/string.c in scratch
space with the actual Clang 21 flags and the ported header; this is not a
replacement for whole-kernel LTO or a device boot.
- The selector's full, memory and strings variants compile for init/main.c and
lib/string.c with those flags. No overflow stubs are added.
## Source and build isolation
`scripts/009-fortify-select-family.py` selects complete wrapper functions from
the existing port and verifies the expected inventory of 15 wrappers. Memory
keeps memset, memcpy, memmove, memscan, memcmp, memchr, memchr_inv and kmemdup.
Strings keeps strncpy, strcat, strlen, strnlen, strlcpy, strncat and strcpy.
Disabled wrappers use the existing raw declarations, not a returning panic stub.
`scripts/009-build-fortify-family-isolated.sh` archives kernel commit
28f9290ae067d3e7857126eb6312720dbe9c7c80 to its own source directory. It applies
the existing Clang port and the already-tested audio/WLAN bounds patch, then
selects a family. It never resets Cursor's live source or writes its output.
The input .config is extracted from the saved failing bounds kernel. olddefconfig
must leave it byte-identical or the job aborts. Clang r563880c, LLVM tools and
Android host build flags are reused. Kernel release suffix is preserved for
installed modules. Full module linking is required even though only boot will
be packaged. The raw new Image is injected into GOODMAKE; ramdisk and DTB stay
from GOODMAKE. Local unpack, metadata, payload and module-version checks remain
required before device use.
## First run
Remote root: `/srv/rom/artifacts/009-fortify-family-20260927/`.
Detached session: `009-codex-fortify-memory-20260927`.
Log: `/srv/rom/artifacts/detach-009-codex-fortify-memory-20260927-20260927T193643Z.log`.
Status: `/srv/rom/artifacts/detach-009-codex-fortify-memory-20260927.status`.
The memory-only build started at 19:36:43 UTC. Configuration drift check passed
(empty memory/config.diff). Build finished exit=0 at 19:58:48 UTC
(`memory/boot-make.img`).
**LAB boot (2026-09-27 ~22:00 local):** flashed both slots → `sys.boot_completed=1`
on kernel `#1` `Sun Sep 27 19:45:25 UTC 2026`. Memory-only family **boots**.
**Strings-only build:** session `009-codex-fortify-strings-20260927`, finished
exit=0 at 20:51:38 UTC (`strings/boot-make.img`).
**LAB boot (strings):** flashed both slots → returned to **fastboot** (~100s,
no `boot_completed`). Recovered combo4. Strings-only family **fails to boot**.
**Family result:** memory boots, strings does not → narrow toward string
wrappers (`strncpy`/`strcpy`/`strlen`/…), not the memcpy family. Still
diagnostic-only; not a shippable FORTIFY subset.
**Strings split (LAB):**
- `strings-copy` → **boots**
- `strings-len` (strlen, strnlen) → **boots**
- full `strings` (copy+len together) → **fails**
Implication: neither half alone is sufficient to reproduce; failure is in the
**interaction** of fortified copy + fortified len (or LTO/CFI coupling of
both). Next: smaller cross products (e.g. strcpy+strlen only), same baseline.
**Cross products (LAB):**
- `strings-strcpy-strlen` → **boots**
- `strings-copy-strlen` (5 copy + strlen) → **fails**
- `strings-copy-strnlen` → **boots** (strlen is the critical len partner)
- `strings-strlen-restcopy` (strlen+strncpy/strlcpy/strcat/strncat) → **fails**
- `strings-strlen-ncopy` (strlen+strncpy+strlcpy) → **fails**
- `strings-strlen-cat` (strlen+strcat+strncat) → **boots**
- `strings-strlen-strncpy` → **boots**
- `strings-strlen-strlcpy` → **fails**
- **Smoking gun:** fortified `strlcpy` + fortified `strlen` together.
- **Root cause:** 4.14 `strlcpy` does `ret = strlen(q)`. With Clang
`__pass_object_size`, nested fortified `strlen` panics on known-size
sources; GCC usually saw bos==-1 and skipped. Fix in
`apply_fortify_clang.py`: `strlcpy`/`strcpy` use `__underlying_strlen`.
**Fix verification (LAB 2026-09-28):**
- Rebuilt `strings-strlen-strlcpy` + full `strings` with fixed apply → both
`exit=0` (~18:24 / 18:26 UTC).
- Flashed both slots: `strlen+strlcpy` → `boot_completed=1`; full `strings`
→ `boot_completed=1` (`CONFIG_FORTIFY_SOURCE=y`, kernels `#1` 18:06 / 18:10 UTC).
- Pre-fix pair archived as `strings-strlen-strlcpy-broken/` on the host.
**Full family (LAB 2026-09-28):** rebuilt `full` (15 wrappers) with nested-strlen
fix → `exit=0` 19:31 UTC → flashed both slots → **`boot_completed=1`**
(`CONFIG_FORTIFY_SOURCE=y`, kernel `#1` 19:18 UTC). Port wrappers alone are
no longer the brick.
**combo4+FORTIFY (LAB 2026-09-28):** ksync
`20260928T201655Z-bisect-ksync-combo4-fortify-fix` → flashed both slots →
**`boot_completed=1`** with `FORTIFY` + `INIT_ON_*` + `DMESG` +
`SLAB_FREELIST_HARDENED`. Nested-strlen fix unblocked the previous ship
candidate pack.
## Interpretation
- A memory-only boot would narrow investigation toward the string wrappers or
their interaction with memory wrappers. It would not prove a specific string
operation or driver is faulty.
- A memory-only failure would keep the memory family, common port machinery and
build/runtime interactions in scope; it would not clear the string family.
- Complementary/control builds should follow the observation, changing only the
selector. If behavior is deterministic, continue by splitting the implicated
group, then its caller set. Do not restart from an unrelated build baseline.
- Preserve vmlinux, source, effective config, command, compiler version, hashes
and the exact boot result for each variant.
+89
View File
@@ -0,0 +1,89 @@
# Revisión del port FORTIFY en curso — 2026-09-26, 21:25 UTC
Revisión de solo lectura del servidor; no se han editado scripts en ejecución.
El dueño confirma combo4 arrancado. Cursor registra kernel #16, DMESG,
SLAB_FREELIST_HARDENED, INIT_ON_ALLOC y INIT_ON_FREE activos, FORTIFY apagado.
No se ha repetido aquí la inspección de LAB.
## Estado real
Job: `009-bisect-ksync-fortify-clang`, iniciado a las 21:15:03 UTC.
Log: `/srv/rom/artifacts/detach-009-bisect-ksync-fortify-clang-20260926T211503Z.log`.
A las 21:25 UTC seguía activo, con procesos clang consumiendo CPU. El log
principal no se actualizaba desde las 21:18:39; eso no implicaba bloqueo.
No había resultado final ni nuevo artefacto FORTIFY validado.
El script recibe **solo CONFIG_FORTIFY_SOURCE**. Es un ensayo aislado, no
combo4+FORTIFY; coincide con el plan local. Preserva breakfast/bp4a y el
empaquetado sobre GOODMAKE. El diff actual no modifica lib/string.c ni añade
los stubs BUG. Mantener deshabilitado ALLOW_FORTIFY_BUG_STUBS.
## Hallazgo que revisar antes de aceptar el port
El script `apply_fortify_clang.py` adapta atributos y prototipos, pero deja
consultas de tamaño incoherentes con algunos atributos:
- POS equivale a `pass_object_size(1)`.
- `strlen` y `strnlen` reciben p con POS y consultan
`__builtin_object_size(p, 0)`.
- `strlcpy`, `strncat` y `strcpy` reciben q con POS y consultan su tamaño
con tipo 0. En otros wrappers, POS0 sí coincide con las consultas tipo 0.
Esto no es un detalle estético. La información de tamaño implícita depende
del tipo. Se compiló por stdin una prueba pequeña con el mismo Clang
r563880c, también para AArch64 freestanding, sin escribir en el servidor:
```c
typedef __SIZE_TYPE__ size_t;
__attribute__((noinline))
size_t mismatch(const char *const p __attribute__((pass_object_size(1)))) {
return __builtin_object_size(p, 0);
}
__attribute__((noinline))
size_t matched(const char *const p __attribute__((pass_object_size(0)))) {
return __builtin_object_size(p, 0);
}
```
El IR optimizado de mismatch devuelve -1 (tamaño desconocido); matched
devuelve el argumento implícito de tamaño. **Límite:** es una prueba aislada
noinline del mecanismo, no una demostración de que todas las llamadas a los
wrappers always_inline reales pierdan protección. Es necesario probar los
wrappers reales con optimización/LTO, tamaños conocidos y desconocidos.
Referencia primaria:
[Clang: pass_object_size](https://clang.llvm.org/docs/AttributeReference.html#pass-object-size-pass-dynamic-object-size).
Adaptar coherentemente los atributos y la semántica de tamaño del 4.14;
no sustituir todas las consultas por tipo 1 a ciegas, porque cambia la
política whole-object/subobject y puede alterar accesos válidos del árbol.
## Otros puntos de aceptación pendientes
- El port elimina `depends on !CC_IS_CLANG` sin implementar la detección y
los límites de versión/capacidades que propone su propio plan. Los macros
de atributos tienen fallback vacío: un compilador no compatible puede
volver a habilitar un FORTIFY sin soporte. No es prueba de fallo de Clang 21,
pero la configuración aún no tiene una protección adecuada.
- `__diagnose_as` está definido pero no utilizado en los wrappers revisados.
Documentar si se omite intencionadamente y validar diagnósticos reales;
declarar el atributo no implementa su efecto.
- El empaquetador imprime propiedades/config pero varias comprobaciones
terminan en `|| true`. Mostrar el valor no garantiza que coincida con el
esperado. Antes de entregar: comparar hashes de ramdisk/DTB, metadatos,
kernel inyectado y opciones de la config embebida, fallando si difieren.
- No editar el script activo. Congelar copia, hash, argumentos, diff y
configuración por experimento para evitar repetir el incidente combo4.
## Qué debe probarse además de compilar y arrancar
Sin stubs es necesario, pero no suficiente: quitar accidentalmente una
comprobación también puede hacer desaparecer símbolos de overflow.
Usar casos válidos y desbordamientos intencionados en un harness aislado
de los wrappers reales (no provocar corrupción en LAB), comprobando el
diagnóstico o camino de fallo esperado con Clang/LTO. Verificar también
ausencia de stubs en binarios/módulos, .config efectiva y hardware básico.
Después del ensayo aislado, validar combo4+FORTIFY como artefacto distinto.
Conclusión: el enfoque mejora y el build está activo; aún hay detalles del
port y pruebas de eficacia pendientes. No equivale a un port ya aceptado.
@@ -0,0 +1,103 @@
# FORTIFY POS0: dos errores localizados y corrección candidata
Revisión del job `009-bisect-ksync-fortify-pos0`, que terminó con exit=1
el 2026-09-26 a las 21:54:28 UTC. Se leyó el log del servidor, el fragmento
aportado y la conversación reciente de Cursor de este proyecto.
## Resultado
Se reprodujeron los dos símbolos sin resolver en compilaciones aisladas de
los archivos responsables, usando los argumentos del build fallido y su
Clang 21. Añadiendo validaciones explícitas de capacidad, desaparecen ambos
en los objetos tras LTO, **sin stubs y sin desactivar FORTIFY**.
[Parche candidato](009-fortify-driver-bounds-candidate.patch).
Es un cambio local propuesto en esta revisión, no un parche upstream.
No se ha aplicado al árbol de compilación de Cursor. `git apply --check`
contra el árbol remoto actual terminó correctamente.
## Localización en los objetos reales del build fallido
Raíz: `/srv/rom/src/lineage/out/target/product/sunfish/obj/KERNEL_OBJ`.
- `techpack/audio/dsp/q6_dlkm.lto.o`: `rtac_remove_voice+0x1d0`,
relocación `R_AARCH64_CALL26 __read_overflow2`.
- `drivers/staging/qcacld-3.0/wlan.lto.o`:
`lim_process_fils_auth_frame2+0xe48`,
relocación `R_AARCH64_CALL26 __read_overflow`.
Importante: modpost etiqueta el error con `.lto.ko`, pero los objetos
intermedios disponibles son `.lto.o`. Los `.ko` antiguos que quedan en out
no deben confundirse con módulos del intento fallido.
### Audio
`techpack/audio/dsp/rtac.c` tiene capacidad para dos entradas de voz.
`rtac_remove_voice` usa un contador global para recorrer el array y llama a
`shift_voice_devices`, que copia del elemento `idx+1`. El código de alta
ya limita el número de entradas, pero ese invariante no basta para eliminar
la rama de diagnóstico en esta compilación.
El candidato valida el contador bajo `rtac_voice_mutex`, antes del recorrido.
Si supera ARRAY_SIZE(voice), registra el error, libera el mutex y retorna.
Esto evita aceptar el estado inválido; no altera el recorrido válido ni
desactiva las comprobaciones de memoria.
### Wi-Fi
`lim_process_fils.c:1095` recorre `dot11f_ie_rsn.pmkid_count` y compara
PMKID de 16 bytes. El array declarado en `dot11f.h:6725` es `pmkid[4][16]`.
El objeto LTO conserva una rama al helper de overflow cuando el contador
alcanza cinco o más sin haberse encontrado una coincidencia.
El parser `dot11f.c:6703` ya rechaza contadores mayores de cuatro. Por tanto,
esta revisión **no demuestra que exista una entrada explotable ni una lectura
real fuera de límites**. El compilador no elimina todas las ramas inválidas
en el consumidor. El candidato comprueba ARRAY_SIZE(pmkid) justo antes del
bucle y devuelve false ante un contador inválido.
## Validación realizada
Se trabajó en directorios temporales de rom-dev01, sin cambiar las fuentes
ni los objetos de salida usados por Cursor:
- `/tmp/axp-fortify-probe-bl9zsxpt`: reproducción de ambos archivos y
prueba Wi-Fi; contiene también una variante preliminar de audio no elegida.
- `/tmp/axp-fortify-probe-kkcpn4o9`: reproducción y candidato final de audio.
Método: leer la orden original de `.rtac.o.cmd` / `.lim_process_fils.o.cmd`,
conservar sus opciones de Clang/LTO/CFI e includes; cambiar únicamente la
fuente/output a copias temporales, evitar generar dependencias en out y
añadir el directorio original para resolver includes locales. Ejecutar
`ld.lld -m aarch64linux -O2 -r` sobre cada objeto bitcode y consultar
símbolos sin resolver con llvm-nm.
Resultados:
```text
audio baseline: U __read_overflow2
audio con validación del contador: ningún símbolo overflow sin resolver
wifi baseline: U __read_overflow
wifi con validación del contador: ningún símbolo overflow sin resolver
```
**Alcance:** son dos unidades de compilación y su enlace LTO aislado. No se
ha repetido el enlace completo de q6_dlkm/wlan, modpost global, ROM o boot.
No se han probado arranque, llamadas de voz, audio ni Wi-Fi en LAB. Tampoco
se sustituye con esto el harness pendiente de eficacia de los wrappers.
## Reanudación para Cursor
1. Conservar la evidencia del intento fallido y revisar/aplicar el candidato
después del reset y del port FORTIFY en la receta reproducible. El script
ksync resetea las fuentes: una edición manual previa se perdería.
2. Validar módulos completos/modpost sin `__read_overflow*`, sin nuevos
stubs, sin `__NO_FORTIFY` en estos controladores y sin apagar LTO/CFI.
3. Validar el harness de FORTIFY, la config efectiva y el empaquetado antes
de entregar un nuevo boot. Mantener combo4 como referencia que arranca.
4. Tras aceptar FORTIFY aislado, probar combo4+FORTIFY y funciones de hardware.
La conversación de Cursor proponía mirar los call sites o una exclusión
puntual con `__NO_FORTIFY`. Ya hay evidencia para intentar primero estas
validaciones de límites. Las advertencias de versionado de símbolos WLAN
son un asunto adicional; esta corrección no afirma resolverlas.
@@ -0,0 +1,99 @@
# v4 capture results review — 2026-09-27
## Result
The capture channel still has no validated panic-survival result. Do not infer
that AES selectively overwrites offset 0 while sparing offset 2048, and do not
choose a high offset as a safe region without establishing its ownership and
observed persistence. No FORTIFY-specific failure has been captured yet.
Reviewed Cursor's recorded experiment summaries, v4 generated source, the kernel
ramoops implementation, sunfish DT and init.ramoops.sh. Read the current LAB alt
region while LAB was running combo4 #16; no device writes, flashes or reboots.
Current 4 MiB capture SHA-256:
`24bbccbf4ed1271bc0950167f4a7921e2a79c534ad735d506ebb504a0353f310`.
It contains `AXPDIAG0,M,20260927T084531Z,panic_reg` at 2048, and no AXPDIAG
marker at the eight expected failure offsets 0,128,256,384,512,640,768,896.
## Unsupported steps in the current explanation
1. Random-looking bytes are not proof that the current test caused encryption.
Without a before/after snapshot from the same attempt, they can be old data,
overwritten data or ciphertext. The stored old captures are from different
experiments and cannot establish this particular transition.
2. The milestone is written again on every v4 boot, with a build-time identifier
shared by every boot of that image. Cursor reports that the first SysRq-c
returned with kernel_panic, followed by further live v4 tests. A regenerated
milestone is therefore an alternative to survival across panic. Final
recovery to combo4 does not resolve its age across the preceding boots.
3. The v4 latch is in ordinary kernel RAM. SysRq-x sets it. Clearing the alt
region with dd does not clear the latch in the running kernel. A subsequent
SysRq-c in that same boot will skip recording, even if the region looks
empty. Cursor's summary says a clean retry occurred but does not establish
the full clear/reboot/no-X sequence; this remains a confounder, not a proven
mistake in the executed sequence.
4. Current fs/pstore/ram.c exposes ramoops_decrypt_alt: it reads cxt->size,
decrypts with crypto_aead_decrypt, and copies the whole buffer back only on
success. This is not a panic-time encrypt routine. The inspected sunfish
init script invokes ramoops -D and then ramoops -g -l -c. No kernel panic
encrypt implementation was identified by these searches. Firmware ownership
remains possible, but unproven. Disabling kernel decryption would not by
itself demonstrate that an external encryption path was disabled.
5. The DT declares a 4 MiB alt ramoops reservation, not a separately reserved
diagnostic high-offset region. No offset within it is currently shown safe.
## Next useful test: preserve attribution before another rebuild
Use the existing no-FORTIFY control to establish a documented timeline. Keep
SysRq-x and SysRq-c experiments in separate boots, and archive full dumps,
kernel identity, and boot reason at each available observation point.
- Archive and clear the diagnostic region BEFORE booting the control; then
verify the region contains no complete old failure record. Do not clear only
the persistent bytes after X and assume the in-memory latch has reset.
- Run a fresh boot with no X. Archive the pre-C contents; execute only C.
Recover directly to combo4 when possible, recording any intermediate v4
boot or forced hardware reset. A forced reset is a separate experimental
condition from the automatic panic reboot.
- Compare the full before/after bytes, including mirrors and milestone area.
Do not use the same-build milestone alone as evidence of survival.
- Independently test X persistence through the SAME recovery sequence. This
distinguishes a writer that works in a live kernel from storage that survives
the recovery path. It does not replace the fresh-C test.
If fresh C still leaves no attributable record, a control-only diagnostic can
read back/validate the exact committed C record immediately before panic and
report or expose that result while observable. This separates failure to write
from later loss. It must remain a diagnostic experiment, not a swallowed panic
or a production hardening change.
Only after identifying which transition loses a verified record should the
next patch change its storage or intercept an identified writer. A separately
reserved region needs a board/firmware-compatible design; an arbitrary high
offset is not a substitute for that evidence.
## Remaining source limitation
v4 composes up to 128 bytes but caps persistence at 120; long tokens can lose
the terminating newline required by adoption. This does not explain the short
sysrq-c/sysrq-x records, but must be fixed for general panic messages.
The original FORTIFY cause remains open. Diagnostics v2/v3 had concrete
implementation defects; v4 fixes those major defects and boots, but its test
results still do not establish a working early-panic channel.
## Follow-up LAB (same evening, documented)
Clean C-only:
`.local-artifacts/009-v4-clean-c-20260927T190738Z/` — clear → v4 boot (no X)
→ C → **intermediate auto v4 reboot** (`kernel_panic`) → combo4. No
`AXPDIAG1` at T3 or T4. Fail zone 0:1024 went from all-zero (T2) to opaque
non-`AXPDIAG1` bytes (T3=T4). Latch/X confounder ruled out for this run.
X persistence (no panic):
`.local-artifacts/009-v4-x-persist-20260927T191143Z/` — `AXPDIAG1,X,...`
survives combo4 recover; fail[0:128] identical before/after.
Next: distinguish “C never committed” vs “lost across panic” with a
control-only pre-panic readback of the committed C record (see above).
@@ -0,0 +1,50 @@
# Verification of clean C and X experiments — 2026-09-27
Independently parsed the binary dumps and recorded kernel/boot properties in:
- `.local-artifacts/009-v4-clean-c-20260927T190738Z/`
- `.local-artifacts/009-v4-x-persist-20260927T191143Z/`
The clean C test removes the earlier X/latch confounder: T2 has a zero failure
zone and a fresh v4 #29 boot; T3 reports kernel_panic on an intermediate v4 boot;
T4 is combo4 #16. No complete failure record is present after C. The intermediate
boot prevents localization of loss to the panic itself versus later boot stages.
The X test demonstrates that all eight complete 55-byte X records survive the
normal recovery to combo4 unchanged. It does not include the panic transition
of the C test, so it is a recovery control rather than the same full sequence.
Precision correction: T3 and T4 are NOT identical binary dumps. Their first 128
bytes match, but 7,213 bytes differ across 4 MiB, including six bytes in the first
1 KiB. Likewise X2 and X3 have 79 differing bytes, despite their complete X
records surviving intact. These differences do not negate X persistence, but
avoid describing entire zones or dumps as identical. Their cause is not yet
established.
Next diagnostic should check a full C record (primary and mirrors, expected
event/id/caller/terminator) immediately after its writer and before panic.
The success/failure result must be observable independently of the storage
whose survival is under test. A print to a console that cannot be retrieved, or
another flag only in the same alt region, would repeat the observability problem.
A control-only two-phase arm/readback/trigger protocol can expose the record
and status through adb before deliberately entering panic; document the changed
timing and validate the actual immediate path subsequently. Keep normal FORTIFY
failure behavior intact.
This establishes a narrower investigation: the writer plus normal recovery can
work; a clean panic experiment still loses or fails to produce the record.
Selective AES overwrite and a safe alternative offset remain unproven.
## Follow-up: two-phase arm/readback/panic (same evening)
Artifact:
`.local-artifacts/009-v4-twophase-x-then-c-20260927T191809Z/`
Using existing v4 (no rebuild): SysRq-x → **adb dump confirms** eight
complete `AXPDIAG1,X` records → SysRq-c (latch no-ops C write; panic runs)
→ intermediate v4 (`kernel_panic`) → combo4.
Result: pre-verified X is **absent at P3 and P4**. Independent channel was
adb, not alt-only flags. Timing caveat: adb RTT between arm and panic; type
X not C. Narrow reading: fail-zone content verified before panic does not
survive this panic/reboot path; soft recover without panic still preserves X.
+135
View File
@@ -0,0 +1,135 @@
# Gate G / FR-017 — kernel hardening attribution (ship candidate)
**What “Gate G doc” means:** the acceptance contract asks for a written list of
**what kernel hardening we applied, what we skipped and why**, plus userspace
AVB/signing gaps (or “impossible on this stack”). This file is that list for the
**kernel** half. Userspace AVB is tracked separately below as still open.
**LAB device:** `11231JEC207477` only.
**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.
Prior Stage1-only pack `20260929T123401Z-axp-stage1-combo4` remains the
**recover / bisect GOOD** baseline (kernel `#32`).
## Current accepted artifact
| Field | Value |
|--------|--------|
| Artifact | `/srv/rom/artifacts/009-axp-los23-port/20261001T201836Z-axp-stage1-combo4-cve-hi-batch2/` |
| Local flash copy | `.local-artifacts/009-flash-cve-hi-batch2/` |
| Prior hi-batch1 GOOD | `20261001T192418Z-…-cve-hi-batch1/` (`#48`) |
| Prior clean GOOD | `20261001T180955Z-…-cve-clean/` (`#47`) |
| Kernel base | LOS `msm-4.14` `@ 28f9290ae067` (`4.14.357-openela`) |
| Running LAB (boot flash) | slot `_a`, kernel `#49` `Thu Oct 1 19:49:54 UTC 2026` |
| CVE list | clean **429** + hi-batch1 (**7**) + hi-batch2 (**8**) |
| Apply quality | clean OK=429; hi OK=15 fuzz≤1 (elevated abs-offset) |
| Note | host detach `exit=141` after `bacon_exit=0` = tee SIGPIPE, not a real fail |
| Magisk | EXTENDROM-class preroot v30.7 (virgin until Additional Setup; `magiskd` OK) |
| KernelSU | absent (Magisk track) |
**Flash procedure that works:** recovery → (optional wipe) → sideload zip →
**Reboot system**. Bisect/CVE boots may use `fastboot -s 11231JEC207477 flash boot`
only when CRC/modules match the installed vendor. Do **not** flash Magisk
`boot.img` onto the other slot alone (new kernel + old vendor ⇒ `wlan` CRC mismatch).
**Build entrypoints:**
- Apply: `apply_stage1_combo4.sh` then `apply_cve_strict.sh` with
`CVE_STRICT_LIST=…/cve-clean-offset.list` (denylist includes 49980)
- Bacon: `scripts/009-bacon-axp-stage1-combo4-cve-clean.sh` (or
`009-bacon-cve-clean-post49980` host wrapper)
- Baseline-only: `scripts/009-bacon-axp-stage1-combo4.sh`
## Applied (attributable)
### A. Combo4 defconfig + Clang FORTIFY port
| Item | Source / notes |
|------|----------------|
| `CONFIG_FORTIFY_SOURCE=y` | Ship; Clang port required on this toolchain |
| `CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y` | Combo4 |
| `CONFIG_INIT_ON_FREE_DEFAULT_ON=y` | Combo4 |
| `CONFIG_SECURITY_DMESG_RESTRICT=y` | Combo4 |
| `CONFIG_SLAB_FREELIST_HARDENED=y` | Combo4 (not `SLAB_HARDENED` alone) |
| Clang FORTIFY / `__pass_object_size` | `fortify-clang/apply_fortify_clang.py` (Kees-class port adapted to 4.14 `string.h`) |
| Nested strlen fix | `strlcpy`/`strcpy` use `__underlying_strlen(q)` — LAB smoking gun 2026-09-28 |
| Driver bounds | `fortify-clang/0001-driver-bounds-rtac-fils.patch` (link/false-path) |
| `# CONFIG_KSU is not set` | Magisk track |
### B. Stage1 Graphene / AndroidHardening (30 patches)
Source tree: AXP `kernel_patches` (host `/srv/rom/references/axp/kernel_patches`).
List: `vendor/sunfish-a16/patches/009-kernel-hardening/stage1.list` via
`apply_stage1.sh`.
Includes (series names): Deny_USB, allocsize (partial), bugon, fortify
strict-string patch (AXP `0004` — **not** a substitute for the Clang port),
misc, random, ro, sanitize, slab, unused, etc. Full paths in `stage1.list`.
**LAB marker:** `/proc/sys/kernel/deny_new_usb` present (Graphene Deny USB).
**Build fix retained:** Stage1 `slab/0014` misfuzz into `is_root_cache` →
reverted in `apply_stage1_combo4.sh` when detected (`BUILD-FIXES.md`).
## Explicitly NOT in this ship pack
| Item | Why |
|------|-----|
| Full `cve-strict.list` (~503) | Logo hang; includes high-offset (≥200) and `CVE-2022-49980`. Do not reflash `20260929T181525Z-…-cve` / old `*-kh-cve`. |
| `CVE-2022-49980` (USB gadget UAF) | **Denylist.** Alone reproduces Google-logo hang on LAB (2026-10-01). One-liner takes `udc_lock` in `usb_udc_uevent` while this 4.14 tree still fires uevents under the same lock (`device_add` / bind / unbind). Needs lock-scope companion port, not bulk apply. See `docs/009-cve-bisect-plan.md`. |
| High-offset CVE set (`cve-high-offset-ge200.txt`, ~73) | Quarantine + sunfish filter (26 KEEP). **hi-batch1+2 (15) LAB BOOT_OK `#49`**. Remaining KEEP ~10 (skip `3777`/`26643` nf_tables-class). |
| LinuxIncrementals | Skipped (policy / scope) |
| Failed Stage1 probes | allocsize/0007, ro/0007+0034, slab/0010+0018 — port later |
| Location lockdown | FR-018 — **skip forever on this track**; keep GPS precise/fast (LOS defaults) |
| FORTIFY `BUG()` overflow stubs | Invalid ship fix; never reuse |
| KernelSU / SusFS | Out of Magisk ship track (optional later recycle) |
| Userspace Deblob (Widevine/IMS/CNE) | Deferred (mobile data / Widevine) |
| Bootloader lock | Wont (AXP/LOS unlocked norm) |
## Historical note (why this pack exists)
1. Stage1 / CVE / kh-full bacons of 2026-09-18 **compiled** but **did not boot** on LAB (logo hang).
2. Bisect found Clang FORTIFY + nested `strlen` inside `strlcpy` as a hard brick; combo4 without broken FORTIFY booted.
3. Fixed FORTIFY → combo4+FORTIFY Magisk bacon OK → Stage1 **re-tried on that baseline** → LAB OK 2026-09-29.
## Userspace Gate G (still open)
Kernel attribution above satisfies the **FR-017 / SC-010 kernel** bullet.
Userspace / signing work is **not** done by this kernel bacon.
### In scope (do)
| Item | Intent |
|------|--------|
| **Release / definitive signing keys** | Ship OTAs and images signed with project release keys (not AOSP test-keys). Phonesky and update identity stay on that key across releases. Secrets stay on `rom-dev01` under `/srv/rom/secrets/` — never in Git. |
| **AVB as applicable on unlocked sunfish** | Match GOLDEN/AXP-class AVB *build* posture where LOS 23.2 allows; document any gap that is impossible without locked bootloader or vendor glue we do not have. |
| **Userspace hardening** | Staged Graphene/AXP-class patches (and CVE mega on the boot-OK kernel pack) — attributable, bisectable. |
| **CVE mega (kernel)** | **Partial ship:** clean-offset 429 on Stage1+combo4+FORTIFY (LAB OK). Remaining: high-offset quarantine + proper 49980 port. Never flash `20260918*-kh-cve/full` or full-503 BAD packs. |
### Out of scope (explicit skip)
| Item | Why |
|------|-----|
| **Bootloader relock / locked-device ship** | Neither **AXP.OS** nor **LineageOS** ship a locked-bootloader product as the normal path. **IOdes** does; we are not cloning that model. LAB and end-user sunfish remain **unlocked** for Magisk preroot / sideload workflow. Do **not** treat “cannot lock bootloader” as a Gate G failure. |
Gap rule unchanged: anything still missing from the **in-scope** rows must be present **or** written down as impossible on this stack — no silent omit.
**Checklist + measured GOLDEN vs LAB:** `docs/009-hardening-signing-checklist.md`
(T040). LAB 2026-09-29 is still `userdebug`/`test-keys`/`orange`; GOLDEN is
`user`/`release-keys`/`orange` unlocked — same unlock class, missing project
keys.
## Prior known-good (fallback)
| Artifact | Role |
|----------|------|
| `20260929T033128Z-axp-combo4-fortify` | Magisk + combo4+FORTIFY **without** Stage1 |
| `20260918T143547Z-axp-full` | Pre-KH Magisk baseline (bisect GOODMAKE source) |
## Owner LAB smoke (2026-09-29)
Owner reported Magisk, microG, and related checks OK on Stage1 pack after
sideload to slot `_b`. Optional: second sideload to refresh leftover slot `_a`
(not required for daily use).
+248
View File
@@ -0,0 +1,248 @@
# 009 — Userspace hardening / signing / AVB checklist (Gate G)
**Task:** T040.
**Companion:** kernel half = `docs/009-gate-g-kernel-attribution.md`.
**Policy (2026-09-29):** project **release keys yes**; **bootloader relock no**
(AXP/LOS unlocked norm; IOdes-class lock = non-goal). See
`specs/009-axp-los23-port/research.md`.
Secrets never enter Git. Host material lives under `/srv/rom/secrets/` on
`rom-dev01` only.
---
## Measured baseline (2026-09-29)
| Prop / fact | GOLDEN (AXP Pro) | LAB (Stage1 pack) | Target |
|-------------|------------------|-------------------|--------|
| `ro.build.type` | `user` | `userdebug` | `user` for ship; `userdebug` OK while developing |
| `ro.build.tags` | `release-keys` | `test-keys` | `release-keys` |
| `ro.build.flavor` | `lineage_sunfish-user` | `lineage_sunfish-userdebug` | `…-user` at ship |
| `ro.debuggable` | `0` | `0` on LAB measure wait — typically `1` on userdebug | `0` on ship |
| `ro.secure` | `1` | (LOS default) | `1` |
| `ro.boot.flash.locked` | `0` | `0` | `0` (unlocked — intentional) |
| `ro.boot.verifiedbootstate` | `orange` | `orange` | `orange` while unlocked |
| `ro.boot.vbmeta.device_state` | `unlocked` | (same class) | unlocked |
| `ro.boot.veritymode` | `enforcing` | expect enforcing | keep |
| SELinux | Enforcing (expect) | **Enforcing** | keep |
| OTA zip cert | AXP releasekey | **AOSP `testkey.x509.pem`** (byte-match on stage1 zip) | project releasekey |
| AVB signing key in tree | AXP custom | `external/avb/test/data/testkey_rsa2048.pem` | project AVB key |
| `BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS --flags 3` | AXP sets real AVB when enabled | LOS sunfish adds `--flags 3` unless `WITH_AVB=true` | keep flags 3 (signing infra only; not runtime harden) |
LAB adb sample (device `11231JEC207477`, Stage1 sideload):
`test-keys` / `userdebug` / `orange` / `flash.locked=0` / `getenforce=Enforcing`.
GOLDEN source: `/srv/rom/references/axp/golden/2026-09-13/getprop.txt`.
---
## What “done” means for Gate G userspace
1. Ship images/OTAs verify as **`release-keys`** (not AOSP test-keys).
2. Phonesky / microG keep **their** project JKS identities under
`/srv/rom/secrets/{phonesky,microg}-signing/` (already exist).
3. AVB *build* uses project keys where LOS23/sunfish allows; device stays
**unlocked** (`orange`). Relock is **out of scope**.
4. Userspace hardening stages are attributable (patch dir + map) or explicitly
deferred/skipped with reason.
5. Gaps written down — no silent omit.
---
## Stages (do in order)
### US-S0 — Inventory (this doc) — **done 2026-09-29**
- [x] Compare GOLDEN vs LAB signing/AVB props.
- [x] Confirm stage1 zip OTA cert == AOSP testkey.
- [x] Confirm no `~/.android-certs` / platform release keys on host yet
(only Phonesky + microG JKS).
- [x] Record bootloader-lock = wont.
### US-S1 — Generate project Android signing keys — **done 2026-09-29 (host)**
Host-only. Never commit `.pk8` / private PEM.
| Key | Role |
|-----|------|
| `releasekey` | Default APK/OTA (`PRODUCT_DEFAULT_DEV_CERTIFICATE`) |
| `platform` | `platform`-signed priv-apps |
| `shared` / `media` / `networkstack` / `sdk_sandbox` / `bluetooth` / `nfc` | AOSP partition signing set |
Procedure: `scripts/009-generate-release-keys.sh` on `rom-dev01`
→ prefers `/srv/rom/secrets/android-certs/` if writable, else
`$HOME/.android-certs` (Lineage default; used 2026-09-29 because secrets/
is root-owned 750 without group write).
**Mandatory before first signed ship bacon:** encrypted/offline backup of that
directory (constitution). Public `*.x509.pem` may later be copied into Git for
docs; private material must not.
Acceptance:
- [x] `$HOME/.android-certs/{releasekey,platform,…}.{pk8,x509.pem}` + `avb.pem`
exist on `rom-dev01` (2026-09-29T16:37Z)
- [x] Host tar backup: `/home/android-build/backups/android-certs-20260929T1637Z.tar.gz`
(mode 600; SHA256 in `.sha256`) — **still copy offline/encrypted**
- [x] `releasekey` DN = `O=AXP-Resurection, OU=sunfish-a16, CN=release`
(not AOSP testkey)
- [ ] Root later: `install -d` `/srv/rom/secrets/android-certs` and move keys there
- [ ] Owner offline encrypted copy confirmed
### US-S2 — Wire release keys into bacon — **in progress**
Lineage convention: `PRODUCT_DEFAULT_DEV_CERTIFICATE` → path without suffix
(e.g. `…/releasekey`). On LOS 23 / soong, **env export alone is ignored** —
must be a product makefile `PRODUCT_` (see `vendor/sunfish-a16/signing.mk`,
inherited via `magisk.mk`). Verified `get_build_var` → project releasekey.
Keys **present** on rom-dev01 (`$HOME/.android-certs/releasekey.pk8`, 2026-09-29).
First artifact `20261001T221102Z-…-cve-hi-releasekeys` was **still AOSP testkey**
(env-only wire). Rebacon after `signing.mk` (2026-10-01T22:12Z).
CVE LAB bacons keep test-keys. First real signed bacon stays **`userdebug`**.
**LAB 2026-10-02:** first signed sideload booted Wi‑Fi OK but Bluetooth
crash-looped — zygote `selinux_android_setcontext` failed with
`seinfo=default` for `com.android.bluetooth`. Cause: APK signed with project
`certs/bluetooth.pk8` while `MAINLINE_BLUETOOTH_SEPOLICY_DEV_CERTIFICATES`
stayed on AOSP `build/make/target/product/security/` (non-`com.google.android.bt`
default in `config.mk`). Fix: `PRODUCT_MAINLINE_BLUETOOTH_SEPOLICY_DEV_CERTIFICATES`
in `signing.mk` (rebacon required; boot-only flash insufficient).
Acceptance:
- [ ] Zip `META-INF/com/android/otacert` ≠ AOSP testkey
- [ ] `ro.build.tags=release-keys` on LAB after **sideload** (boot-only flash insufficient)
(note: first RK sideload still showed `dev-keys` on userdebug — recheck after BT fix)
- [x] Magisk preroot + microG + Wi‑Fi **and Bluetooth** OK on Stage1+combo4+CVE-hi ship pack
(`20261002T085915Z-…-cve-hi-releasekeys`, LAB 2026-10-02: BT ON, crashed 0)
- [x] `plat_mac_permissions.xml` embeds project `bluetooth.x509.pem` (`seinfo=bluetooth`)
- [ ] Minor: LOS SetupWizard after Wi‑Fi connect can bounce to language step
(Wi‑Fi stays connected; non-blocking; note only)
- [ ] Prior test-keys image retained for bisect
(`20261001T201836Z-…-cve-hi-batch2` / `#49`, or hi-batch3 when OK)
Script: `scripts/009-bacon-axp-stage1-combo4-cve-hi-releasekeys.sh` +
`vendor/sunfish-a16/signing.mk` → `vendor/sunfish-a16/certs/releasekey`
(in-tree copy of `$HOME/.android-certs`; **gitignored** — soong rejects paths
outside `ANDROID_BUILD_TOP`).
### US-S3 — Project AVB key (unlocked device)
Today sunfish often signs with AOSP `testkey_rsa4096` (or rsa2048) and adds
`--flags 3` unless `WITH_AVB=true` (`BoardConfigLineage.mk` /
`BoardConfig-common.mk`). LAB `20261002T085915Z` vbmeta = AOSP testkey_rsa4096
+ flags 3 (not project `avb.pem`).
AXP ships custom AVB keys and documents AVB2; GOLDEN stays **unlocked/orange**.
Clone that *signing* posture, not IOdes lock.
**Bootloader / OEM unlocking (2026-10-02):** relock remains **wont** for this
Magisk track (orange + preroot). Locking with Magisk-patched boot is a brick
risk on Pixel unless the full AVB chain is enforced end-to-end — out of scope.
Keep `flash.locked=0` / `verifiedbootstate=orange`. Prefer leaving **OEM
unlocking** enabled in Developer options as a *best-effort* escape hatch for
future unlock attempts — it is **not** a guarantee of recovery, data
preservation, or rescue from every failure mode (AOSP: unlock ability is
conditional). Do **not** turn it off casually.
Wire: `vendor/sunfish-a16/BoardConfig.mk` overrides `BOARD_AVB_*` →
`vendor/sunfish-a16/certs/avb.pem` + `SHA256_RSA4096`. Leave `WITH_AVB`
unset so `--flags 3` stays (Magisk-friendly).
**What flags 3 means (libavb):** `HASHTREE_DISABLED (1) | VERIFICATION_DISABLED (2)`.
Descriptors are not enforced at boot; this is **AVB signing infrastructure**,
not “AVB-hardened verified boot”. Do not call US-S3 “AVB endurecido” while
flags stay 3. A later stage may measure `WITH_AVB=true` (flags 0) + Magisk
resign — separate acceptance.
Acceptance:
- [x] `BOARD_AVB_KEY_PATH` → project `vendor/sunfish-a16/certs/avb.pem`
- [x] Artifact gates **fail closed** on **target_files/IMAGES** (not OUT make
images): pubkey sha1 == `avb_pkmd.bin` (≠ AOSP `2597c218…`); Flags `3`;
`verify_image --key` vbmeta + `--expected_chain_partition` vbmeta_system;
Magisk boot hash matches vbmeta; `magiskboot cpio test` ≠ 0
- [x] Document clearly: runtime AVB enforce = **off** (flags 3) — not “AVB endurecido”
- [x] Device still boots unlocked; Magisk preroot intact (LAB 2026-10-02 sideload
+ boot/vbmeta reinforce; `magiskd`, `flash.locked=0`, orange)
- [x] No bootloader relock; OEM unlocking left enabled (escape hatch, not guarantee)
### Branding (no rebacon-only)
- [x] Wire `vendor/sunfish-a16/branding.mk` →
`TARGET_UNOFFICIAL_BUILD_ID=AXP-Resurection-Pro` (full Magisk track, not slim;
next bacon embeds it in `ro.lineage.version`)
- [x] Ship script publishes sibling `AXP-Resurection-Pro-*-sunfish.zip`
(hardlink/copy of Lineage bacon zip). Current artifact renamed the same way
without rebuild.
### US-S4 — Userspace hardening (first attributable pack)
See `docs/009-us-s4-userspace-hardening.md`.
- [x] Stage 0 LAB measure (Enforcing + FBE)
- [x] US-S4-1: strip Openssh/rsync/procmem packages from Lineage `common.mk`
(`apply_009_drop_openssh_packages.py`); keep `init.openssh.rc` (AXP PRO)
- [x] LAB 2026-10-02: ship `20261002T151944Z` sideloaded + reinforced;
see `docs/009-lab-acceptance-20261002-uss4.md`
- [ ] **US-S4-2** (wired, pending bacon): drop Jelly + Gallery2 (AXP PRO
product oracle — Fossify stays); `apply_009_drop_jelly_gallery2.py` +
`NoLineageJelly`; see `docs/009-axp-pro-product-apps-20260324.md`
| Candidate | Priority | Notes |
|-----------|----------|-------|
| Confirm SELinux Enforcing + encryption | **done** | LAB Enforcing + FBE |
| ptrace/Yama | **done US-S5-1** | LAB `162840Z` `CONFIG_SECURITY_YAMA=y` |
| Debug/bugreport surface trim | **done US-S4-1** | AXP PRO product oracle |
| Jelly + Gallery2 debloat | **US-S4-2 wired** | AXP PRO product; Fossify kept |
| mount flags / noexec where stock allows | early | don't break HW |
| hardened_malloc | later | Graphene/AXP; portability cost |
| Broad Graphene framework (scopes, etc.) | later / deferred | high UX cost; not Magisk-clone MVP |
Ship patches under `vendor/sunfish-a16/patches/009-axp-los23-port/hardening/` with README
attribution. One stage per bacon when risk is unclear.
### US-S5 — Kernel CVE mega / more Graphene (on boot-OK pack)
**Do not** flash old `20260918*-axp-kh-cve` / `kh-full` (logo hang).
- [x] CVE clean-offset 429 + hi-batch1–3 on Magisk ship (`151944Z` LAB OK)
- [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`
Map updates: `docs/009-kernel-hardening-map.md` + Gate G attribution.
### US-S6 — Optional later
- [ ] Switch default lunch to `lineage_sunfish-user` for ship
- [ ] GPG-sign published SHA sums (AXP does; nice-to-have)
- [ ] LOS23 nightly rebase (vanilla + re-apply Magisk/stage1/keys)
- [ ] Bootloader lock — **wont**
---
## Host paths
| What | Path |
|------|------|
| Platform / OTA / AVB secrets | `$HOME/.android-certs/` on rom-dev01 (2026-09-29); prefer `/srv/rom/secrets/android-certs/` after root relocate |
| Certs tar backup | `/home/android-build/backups/android-certs-20260929T1637Z.tar.gz` |
| Phonesky JKS | `/srv/rom/secrets/phonesky-signing/` |
| microG JKS | `/srv/rom/secrets/microg-signing/` |
| Keygen script (repo) | `scripts/009-generate-release-keys.sh` |
| Signing README (vendor) | `vendor/sunfish-a16/patches/009-axp-los23-port/signing/README.md` |
| GOLDEN props | `/srv/rom/references/axp/golden/2026-09-13/` |
| AXP docs (mirror) | `…/axpos.org/docs/knowledge/{signatures,verifiedboot}/` |
---
## Explicit non-goals
- Bootloader relock / green verified-boot for end users.
- Replacing Phonesky/microG keys with platform keys.
- Committing private keys or passphrases to Git.
- Treating missing lock as Gate G failure.
@@ -0,0 +1,64 @@
# AXP Internet connectivity check providers (from GOLDEN Settings)
Source: `Settings.apk` on GOLDEN `11071JEC203839`
(`ConnectivityCheckPreferenceController` + `connectivity_check_*` arrays),
pulled 2026-09-18.
Artifact: `.local-artifacts/002-golden/20260918-connectivity/`
Preference: **Internet connectivity check**
(`connectivity_check_settings`) — sets global
`captive_portal_{http,https,fallback,other_fallback}_url` and
`captive_portal_mode`.
## GOLDEN UI list (as shipped)
| value | UI label | HTTP check URL |
|------:|----------|----------------|
| 0 | Disabled | *(mode=0; stock Google URLs cleared/disabled)* |
| 1 | Amazon Fire OS (US) | `http://fireoscaptiveportal.com/generate_204` |
| 2 | Cloudflare (US) | `http://cp.cloudflare.com` |
| 3 | **AXP.OS (DE)** | `http://captiveportal.axpos.org/generate_204` |
| 4 | Google (US) [default] | `http://connectivitycheck.gstatic.com/generate_204` |
| 5 | Huawei (CN) | `http://connectivitycheck.platform.hicloud.com/generate_204` |
| 6 | Kuketz (DE) | `http://captiveportal.kuketz.de` |
| 7 | Microsoft Edge (US) | `http://edge-http.microsoft.com/captiveportal/generate_204` |
| 8 | openSUSE (DE) | `http://conncheck.opensuse.org` |
| 9 | Ubuntu (UK) | `http://connectivity-check.ubuntu.com` |
Code also implements (not in GOLDEN `connectivity_check_entries`):
| value | internal name | HTTP check URL |
|------:|---------------|----------------|
| 10 | Xiaomi / MIUI | `http://connect.rom.miui.com/generate_204` |
| 11 | GrapheneOS | `http://connectivitycheck.grapheneos.network/generate_204` |
Note: value `3` constants are named `DIVESTOS_*` in smali but point at
`captiveportal.axpos.org` and are labeled **AXP.OS (DE)** in the UI.
## Clone target for LOS 23.2 (sans axp.os)
**Drop** value 3 / AXP.OS / `*.axpos.org` entirely (spec: no axp.os endpoints).
Ship UI (renumber values contiguously after drop):
| UI label | HTTP | HTTPS |
|----------|------|-------|
| Disabled | — | — |
| Amazon Fire OS (US) | `http://fireoscaptiveportal.com/generate_204` | `https://fireoscaptiveportal.com/generate_204` |
| Cloudflare (US) | `http://cp.cloudflare.com` | `https://cp.cloudflare.com` |
| Google (US) [default] | `http://connectivitycheck.gstatic.com/generate_204` | `https://www.google.com/generate_204` |
| Huawei (CN) | `http://connectivitycheck.platform.hicloud.com/generate_204` | `https://connectivitycheck.platform.hicloud.com/generate_204` |
| Kuketz (DE) | `http://captiveportal.kuketz.de` | `https://captiveportal.kuketz.de` |
| Microsoft Edge (US) | `http://edge-http.microsoft.com/captiveportal/generate_204` | same (AXP uses HTTP URL for https slot) |
| openSUSE (DE) | `http://conncheck.opensuse.org` | `https://conncheck.opensuse.org` |
| Ubuntu (UK) | `http://connectivity-check.ubuntu.com` | `https://connectivity-check.ubuntu.com` |
Optional extras already in GOLDEN controller (owner choice later): Xiaomi, GrapheneOS.
Google default also sets:
- fallback: `http://www.google.com/gen_204`
- other fallback: `http://play.googleapis.com/generate_204`
GrapheneOS (if enabled later) also sets:
- fallback: `http://grapheneos.online/gen_204`
- other: `http://grapheneos.online/generate_204`
+229
View File
@@ -0,0 +1,229 @@
# Auditoría de los fallos de arranque del kernel — 2026-09-26
Revisión de documentación local, scripts, fuentes y artefactos de `rom-dev01`.
No se ha compilado, flasheado, reiniciado ni modificado el servidor o los teléfonos.
Este documento registra evidencias y un punto de reanudación; no cambia requisitos.
## Conclusión
**Hallazgo prioritario posterior: los bisect cambian TARGET_RELEASE de bp4a
a bp2a.** La comparación binaria y el log demuestran que no se está aislando
el hardening. Ver la sección siguiente antes de construir o probar más boots.
Hay errores verificables en la preparación de los experimentos y en su trazabilidad.
Todavía no hay una traza que identifique la causa exacta del fallo de arranque.
El siguiente paso debe recuperar un experimento controlado, no volver a aplicar
todo el hardening/CVE/deblob desde cero.
## Hallazgo principal: cambio accidental de release Android en los bisect
Tras confirmar el dueño que GOODMAKE también arranca, se han desempaquetado
GOODMAKE y el boot mild y extraído sus configuraciones IKCONFIG y ramdisks.
[Evidencia y diff de configuración](009-kernel-boot-image-comparison-20260926.txt).
- GOODMAKE: cabecera con parche `2026-09`; ramdisk declara
`ro.build.version.security_patch=2026-09-01`, SDK completo `36.1`.
- MILD: cabecera con parche `2025-08`; ramdisk declara
`ro.build.version.security_patch=2025-08-05`, SDK completo `36.0`.
- DTB idéntico. Ramdisk diferente, incluyendo bibliotecas y propiedades.
- Configuración del kernel: además de DMESG/SLAB cambian VT/fbcon, watchdog
y PANIC_TIMEOUT (de 0 a 5), entre otros cambios derivados. La base buena
conservaba configuración de depuración y el bloque Kconfig de KernelSU,
aunque CONFIG_KSU estaba desactivado.
Origen confirmado en el servidor:
- `scripts/009-bacon-axp.sh:87` usa `breakfast sunfish userdebug`.
- `vendor/lineage/build/envsetup.sh` hace que breakfast lea
`vendor/lineage/vars/aosp_target_release`, cuyo valor actual es `bp4a`.
- Los bisect fuerzan `lunch lineage_sunfish-bp2a-userdebug`.
- El log `detach-009-bisect-dc-20260921T180802Z.log:53` registra literalmente
`TARGET_RELEASE ("bp4a" -> "bp2a")`.
- `build/release/flag_values/bp2a/RELEASE_PLATFORM_SECURITY_PATCH.textproto`
contiene `2025-08-05`.
- Los dos scripts nuevos del 26 de septiembre, `009-bisect-dmesg-only.sh`
y `009-bisect-slab-only.sh`, también fuerzan **bp2a en la línea 32**.
No se han detenido ni modificado sus procesos desde esta auditoría.
**Defecto demostrado:** los experimentos denominados «solo una/dos opciones»
cambian también la release Android y metadatos de seguridad del boot.
Que GOODMAKE arranque no valida la equivalencia del entorno que los recompila.
**Hipótesis causal prioritaria, aún no confirmada en LAB:** el retroceso del
nivel de parche o su inconsistencia con el sistema instalado puede interferir
con Keymaster y las claves necesarias para montar datos. AOSP documenta
[version binding](https://source.android.com/docs/security/features/keystore/version-binding):
las claves están vinculadas a versiones/niveles de parche y no se pueden
degradar libremente. Los flags AVB que desactivan verificación no constituyen
una prueba de compatibilidad de esas claves. Falta traza o prueba controlada;
no afirmar que esto explique también todos los OTA Stage1 anteriores.
**Corrección del experimento:** recuperar la release y metadatos efectivos
del build bueno; verificar cabecera, propiedades y AVB del resultado antes de
flashear. Cambiar simplemente a bp4a no basta como verificación: el archivo
bp4a actual declara `2025-12-05`, mientras GOODMAKE declara `2026-09-01`, por
lo que hay que localizar/reproducir sus overrides y no inventar una fecha.
Usar salida aislada y empezar con un control recompilado sin hardening nuevo.
No hacer factory reset como método de validación. Después aislar kernel y
módulos sin variar simultáneamente ramdisk, release o metadatos.
## Historial aportado por el dueño después de la revisión
El 26 de septiembre el dueño aporta una conversación previa:
- «Tanto con uno como el otro» el teléfono reinicia en recovery y muestra
«Try again / Factory data reset». El fragmento no identifica inequívocamente
los dos archivos por nombre/hash; no asignar este resultado a mild.
- Tras restaurar el boot GOOD de `20260918T143547Z`, confirma «estoy en el
sistema». No se relata un borrado de datos. Es evidencia de recuperación
con el boot conocido, no una prueba de corrupción permanente de `/data`.
- El agente anterior informa ADB `unauthorized` en recovery; después, ya en
sistema, informa ausencia de `su`, depuración root desactivada y ningún log
útil obtenido. No hay salidas originales que permitan verificar qué rutas
pudo leer: «no pude obtener evidencia» no equivale a «no se generó evidencia».
- La conversación termina proponiendo mild como prueba pendiente. No aporta
una respuesta posterior que confirme su ejecución ni su resultado.
Este historial matiza el registro «nunca recovery/Android»: al menos en los
intentos relatados sí se llega a recovery tras el fallo. No demuestra que el
kernel del arranque normal alcanzara una fase concreta, porque recovery es
un arranque posterior. Preparar acceso diagnóstico en el sistema GOOD antes
de otro ensayo, sin completar Magisk únicamente para obtener logs ni mezclar
su activación con el cambio de kernel. No interpretar el menú de recovery
como una indicación de que sea necesario hacer factory reset.
## 1. Imagen antigua dentro del ensayo nuevo (confirmado por SHA-256)
Raíz de artefactos remota: `/srv/rom/artifacts/009-axp-los23-port/`.
Estos dos archivos tienen el mismo SHA-256, recalculado el 26 de septiembre:
- `20260921T185024Z-bisect-defconfig-only/boot.img`
- `20260918T231654Z-axp-kh-full/boot.img`
SHA-256: `3715f9f20c8823e5a23323792600b5d76d9f25e73eed3492c28f457a751d3c51`.
El script remoto `scripts/009-bisect-defconfig-only.sh` ejecuta `mka bootimage`
y luego busca el primer `target_files_intermediates/.../IMAGES/boot.img`.
Ese segundo archivo pertenece al empaquetado anterior: el ensayo termina
conteniendo dos imágenes con kernels distintos.
El `boot-make.img` del ensayo tiene SHA-256 registrado
`f52405c6b39a14d3357efd59441c9a28128bbce982186b1d86c71b01da8846b1`.
El README sí indica usar ese archivo. No he encontrado en lo revisado un
registro de flasheo con hash que permita confirmar cuál se probó. Por tanto,
la identidad equivocada está demostrada; que se flashease la imagen equivocada,
no. El script posterior `009-bisect-defconfig-mild.sh` ya evita esta copia.
## 2. «Solo defconfig» también cambia código de FORTIFY (confirmado)
El mismo script añade a `lib/string.c` definiciones exportadas de
`__read_overflow`, `__read_overflow2`, `__read_overflow3` y `__write_overflow`,
todas con cuerpo `BUG()`. El log
`/srv/rom/artifacts/detach-009-bisect-dc-20260921T180802Z.log` confirma
`added fortify stubs`.
En las fuentes LOS inspeccionadas, `include/linux/string.h:241` y siguientes
declaran los helpers de lectura con `__compiletime_error`. Proporcionarles
un cuerpo permite resolver símbolos que impedían enlazar, pero no demuestra
que las llamadas sean correctas ni que no se ejecuten. Si se alcanza uno de
esos cuerpos se ejecuta `BUG()`. Falta investigar los sitios de llamada y su
relación con Clang/LTO; no atribuir el bootloop a ellos sin traza.
La conclusión previa «defconfig extras alone are enough to kill boot» es
demasiado fuerte: el ensayo incluye cambios C, varias opciones simultáneas y
la ambigüedad de imágenes anterior. Además cambia `SLAB_HARDENED` de Stage1
por `SLAB_FREELIST_HARDENED`, por lo que tampoco reproduce exactamente su config.
## 3. Se avanzó de etapa sin validar arranque (confirmado documentalmente)
`docs/009-kernel-hardening-map.md` ordena diferir los CVE hasta que Stage1
arranque, pero registra tres builds el 18 de septiembre: Stage1, Stage1 con
unos 500 CVE, y hardening ampliado. Los tres fallaron en LAB según el registro
del 21. Compilar correctamente no cumplía esa condición.
Stage1 ya agrupaba 30 parches y varias opciones; también se documentan restos
de modificaciones SusFS en el árbol inicial. El script de bisect posterior
sí limpia las fuentes hasta `28f9290ae067`; no confundir ambos estados.
## 4. Aplicación de parches y reparaciones no reproducibles
El `apply_stage1.sh` local usa `patch --batch` sin exigir fuzz cero. Ya existe
un caso documentado de aplicación en la función equivocada: `slab/0014` entró
en `is_root_cache` en vez de `slab_equal_or_root`.
El listado sigue incluyendo ese parche. Las correcciones de slab y FORTIFY
se describen en `BUILD-FIXES.md`, pero no están implementadas por el aplicador
local. Ejecutar la receta publicada no reproduce por sí solo el árbol corregido.
Otros defectos visibles del aplicador:
- Si falta un archivo, incrementa `fail` y continúa; al acabar puede devolver
éxito porque el último comando es `echo`.
- Ante fallo elimina `.rej` y `.orig`, perdiendo evidencia; no revierte los
hunks que se hayan aplicado antes del fallo.
- `--dry-run` prueba cada parche sobre el mismo árbol sin aplicar sus
predecesores: no valida fielmente una serie con dependencias.
En el servidor, `scripts/009-cve-compile-fix.sh` intenta seleccionar parches
para excluir por tokens extraídos del mensaje del compilador y registra el
código de salida de su reversión sin exigir que sea cero. Esto no verifica
dependencias ni garantiza que el árbol coincida con la denylist. Son defectos
del método; esta revisión no establece qué rondas concretas los ejercitaron.
## 5. Kernel y módulos: compatibilidad pendiente de demostrar
Los dos scripts de bisect generan y guardan únicamente imágenes de arranque;
sus instrucciones reutilizan la ROM `20260918T143547Z-axp-full` instalada.
No guardan ni indican desplegar un conjunto correspondiente de módulos vendor.
El código actual `include/linux/slub_def.h:120` añade el campo `random` a
`struct kmem_cache` bajo `CONFIG_SLAB_FREELIST_HARDENED`. La `.config` generada
actual contiene esa opción y `CONFIG_MODVERSIONS=y`.
Esto justifica comprobar ABI/CRC de los módulos realmente cargados y los que
van en el ramdisk/vendor antes de interpretar un ensayo de solo boot. No prueba
por sí solo incompatibilidad ni explica necesariamente los primeros tres OTA.
La misma precaución ya consta en `docs/007-susfs-source-audit.md`.
## 6. Faltan observabilidad y continuidad entre sesiones
El logo de Google no identifica por sí solo la fase exacta del bloqueo.
El pstore vacío tampoco demuestra que no hubiera traza: la auditoría de `007`
documenta un error de descifrado de ramoops en LAB. Es evidencia histórica;
no se ha vuelto a medir el estado actual del teléfono en esta revisión.
El mapa local acaba proponiendo el ensayo mild, pero este ya fue compilado:
- Artefacto: `20260921T192533Z-bisect-defconfig-mild/boot-make.img`.
- SHA-256 registrado en su log:
`6ed0351edb762bdf4bfe2dd96d7e4e2fa43ccf0ad497d7fce35ab88cd722f4f2`.
- Estado del proceso: `exit=0`, finalizado el 21 a las 19:25:33 UTC.
- Resultado de arranque: **no encontrado en los registros revisados**.
- Árbol remoto actual: HEAD `28f9290ae067d3e7857126eb6312720dbe9c7c80`;
único archivo modificado según Git: `sunfish_defconfig`, con KSU desactivado,
`SECURITY_DMESG_RESTRICT=y` y `SLAB_FREELIST_HARDENED=y`.
- `.config` actual: FORTIFY e INIT_ON_ALLOC/FREE desactivados. No sustituye
a una configuración archivada de cada build anterior.
## Punto de reanudación propuesto
1. Conservar como referencia el build `20260918T143547Z-axp-full`, cuyo
arranque está confirmado por el dueño en el mapa. Identificar por hash el
boot realmente probado en cada bisect y aclarar el resultado de mild.
2. Reproducir un control sin hardening nuevo con fuentes, herramienta de
compilación, salida aislada y módulos identificados. Validar arranque en LAB.
3. Separar las variables: una opción por ensayo. Tratar FORTIFY más sus
modificaciones C como una investigación propia; no ocultar errores de enlace
bajo la etiqueta «solo config».
4. Para cambios que afecten ABI, comprobar o desplegar un conjunto compatible
de kernel y módulos. Registrar slot, particiones, hashes y resultado.
5. Recuperar diagnóstico del fallo antes de atribuirlo a un subsistema.
No borrar datos, alternar slots o añadir parches como sustituto de evidencia.
6. Congelar cada estado probado: revisión y diff de fuentes, parches y sus
hashes, `.config` efectiva, compilador, imágenes/módulos, log y resultado.
No avanzar a CVE ni deblob hasta aceptar la etapa anterior.
Deblob no es una causa demostrada en estos ensayos: el registro de `009`
lo declara pendiente, y la retirada de IPA se omitió expresamente. No se ha
realizado aquí una auditoría exhaustiva del contenido de todos los payloads.
@@ -0,0 +1,125 @@
Comparación directa de imágenes — 2026-09-26
GOODMAKE: .local-artifacts/009-flash-20260918T143547Z/boot-make.img
MILD: rom-dev01:/srv/rom/artifacts/009-axp-los23-port/20260921T192533Z-bisect-defconfig-mild/boot-make.img
good: SHA256=fcc52ec5c7c077def20ce9d9b9ac3782475e0834817f453e845eb2c1e66d1255
header patch level: 2026-09
ro.build.version.sdk_full=36.1
ro.build.version.security_patch=2026-09-01
ro.build.version.sdk_full=36.1
ro.build.version.security_patch=2026-09-01
kernel: SHA256=5db3af0d7eb76dcd26d7fdbe7dad554d7493073bfa3495f1b49c1aa323ad6b4f
ramdisk.cpio: SHA256=a2e412792fa236a1db3416b6bf7ed374e606f88c714339319759b04f84d90067
dtb: SHA256=2fca15709ff6d9f48fea938952439e8d00c2b998c73e7a216172ae3965b07566
mild: SHA256=6ed0351edb762bdf4bfe2dd96d7e4e2fa43ccf0ad497d7fce35ab88cd722f4f2
header patch level: 2025-08
ro.build.version.sdk_full=36.0
ro.build.version.security_patch=2025-08-05
ro.build.version.sdk_full=36.0
ro.build.version.security_patch=2025-08-05
kernel: SHA256=c7829fa4751643067da5ca6e726d402771c781cfc10771201ab989d73a10cdf8
ramdisk.cpio: SHA256=17d51096168cffb1bb0d93682045203d50e3fc00783f4339e4b79adf0785b3eb
dtb: SHA256=2fca15709ff6d9f48fea938952439e8d00c2b998c73e7a216172ae3965b07566
Configuración extraída de IKCONFIG de cada kernel:
--- GOODMAKE.config
+++ MILD.config
@@ -243,7 +243,7 @@
# CONFIG_SLOB is not set
CONFIG_SLAB_MERGE_DEFAULT=y
# CONFIG_SLAB_FREELIST_RANDOM is not set
-# CONFIG_SLAB_FREELIST_HARDENED is not set
+CONFIG_SLAB_FREELIST_HARDENED=y
CONFIG_SLUB_CPU_PARTIAL=y
CONFIG_SYSTEM_DATA_VERIFICATION=y
CONFIG_PROFILING=y
@@ -2282,12 +2282,7 @@
# Character devices
#
CONFIG_TTY=y
-CONFIG_VT=y
-CONFIG_CONSOLE_TRANSLATIONS=y
-CONFIG_VT_CONSOLE=y
-CONFIG_VT_CONSOLE_SLEEP=y
-CONFIG_HW_CONSOLE=y
-CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_VT is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_SERIAL_NONSTANDARD is not set
@@ -3564,16 +3559,6 @@
# CONFIG_BACKLIGHT_ARCXCNN is not set
# CONFIG_VGASTATE is not set
CONFIG_HDMI=y
-
-#
-# Console display driver support
-#
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_DUMMY_CONSOLE_COLUMNS=80
-CONFIG_DUMMY_CONSOLE_ROWS=25
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
-CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
@@ -4493,7 +4478,6 @@
#
# Speakup console speech
#
-# CONFIG_SPEAKUP is not set
# CONFIG_STAGING_MEDIA is not set
#
@@ -4780,7 +4764,7 @@
CONFIG_QCOM_MEMORY_DUMP_V2=y
# CONFIG_MSM_DEBUG_LAR_UNLOCK is not set
CONFIG_QCOM_WATCHDOG_V2=y
-# CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC is not set
+CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
CONFIG_QCOM_WDOG_IPI_ENABLE=y
CONFIG_QCOM_SMEM_STATE=y
CONFIG_QCOM_SMP2P=y
@@ -5331,11 +5315,6 @@
CONFIG_ESOC_MDM_DRV=y
CONFIG_ESOC_MDM_DBG_ENG=y
# CONFIG_MDM_DBG_REQ_ENG is not set
-
-#
-# KernelSU
-#
-# CONFIG_KSU is not set
#
# Firmware Drivers
@@ -5651,7 +5630,7 @@
# CONFIG_PANIC_ON_OOPS is not set
CONFIG_PANIC_ON_OOPS_VALUE=0
# CONFIG_PANIC_ON_WARN_DEFAULT_ENABLE is not set
-CONFIG_PANIC_TIMEOUT=0
+CONFIG_PANIC_TIMEOUT=5
CONFIG_SCHED_DEBUG=y
CONFIG_SCHED_INFO=y
# CONFIG_PANIC_ON_SCHED_BUG is not set
@@ -5830,7 +5809,7 @@
# CONFIG_PFT is not set
CONFIG_PFK=y
# CONFIG_PFK_WRAPPED_KEY_SUPPORTED is not set
-# CONFIG_SECURITY_DMESG_RESTRICT is not set
+CONFIG_SECURITY_DMESG_RESTRICT=y
CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y
CONFIG_SECURITY=y
# CONFIG_SECURITY_WRITABLE_HOOKS is not set
@@ -6139,10 +6118,6 @@
CONFIG_MPILIB=y
CONFIG_LIBFDT=y
CONFIG_OID_REGISTRY=y
-CONFIG_FONT_SUPPORT=y
-# CONFIG_FONTS is not set
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
# CONFIG_SG_SPLIT is not set
CONFIG_SG_POOL=y
CONFIG_ARCH_HAS_SG_CHAIN=y
+267
View File
@@ -0,0 +1,267 @@
# 009 kernel hardening map (FR-017)
> **Priority finding, 2026-09-26:** Bisect scripts (including the new dmesg-only
> and slab-only scripts) force **bp2a**, whereas the GOOD build used **bp4a**.
> Direct image comparison finds GOODMAKE security patch 2026-09 / SDK 36.1
> versus mild 2025-08 / SDK 36.0. GOODMAKE boots according to the owner.
> These are not isolated defconfig trials; see the audit below before testing.
> **Audit 2026-09-26:** Before resuming builds, read
> [the boot investigation](009-kernel-boot-audit-20260926.md).
> The defconfig-only experiment also added FORTIFY C stubs and its `boot.img`
> is byte-identical to the older full-hardening image; only `boot-make.img`
> represents the new build. Its reported boot failure does not yet isolate
> configuration alone. The later mild build already exists; its LAB boot
> result was not found in the reviewed records.
> Subsequent owner-provided history reports failed attempts rebooting into
> recovery (Try again / Factory data reset), followed by successful system
> boot after restoring GOOD. Thus "never recovery" below is not a universal
> description. That history still presents mild as pending; see the audit.
**Base**: LineageOS 23.2 `sunfish` / `kernel/google/msm-4.14` (non-GKI).
**Not base**: GrapheneOS A13 sunfish tree, random prebuilts, KernelSU.
## Inventory (2026-09-18, `rom-dev01`)
| Item | Value |
|------|--------|
| LOS tree | `/srv/rom/src/lineage/kernel/google/msm-4.14` |
| LOS rev | `28f9290ae067` — *Revert "BACKPORT: module: Do not offer sha224…"* |
| Version | `4.14.357-openela` |
| AXP stack | `/srv/rom/references/axp/kernel_patches` @ `df3cab2155b3` (codeberg mirror) |
| Dry-run worktree | `/srv/rom/artifacts/009-axp-los23-port/kernel-harden-dryrun/` |
| Iodé manifest | `/srv/rom/references/iode/android-manifest` (`v5-staging`) |
### LOS `sunfish_defconfig` already on
`CFI_CLANG`, `SHADOW_CALL_STACK`, `CC_STACKPROTECTOR_STRONG`, `RANDOMIZE_BASE`,
`ARM64_SW_TTBR0_PAN`, `SECURITY_PERF_EVENTS_RESTRICT`, `HARDENED_USERCOPY`(+PAGESPAN),
`BUG_ON_DATA_CORRUPTION`, `SCHED_STACK_END_CHECK`, `# CONFIG_DEVMEM is not set`,
`BPF_JIT_ALWAYS_ON`.
`# CONFIG_UNMAP_KERNEL_AT_EL0 is not set` (kept as LOS).
### LOS defconfig gaps (vs typical Graphene/AH)
Not set in `sunfish_defconfig` (may need Kconfig + patches first):
`FORTIFY_SOURCE`, `INIT_ON_ALLOC_DEFAULT_ON`, `INIT_ON_FREE_DEFAULT_ON`,
`SLAB_FREELIST_RANDOM`, `SLAB_FREELIST_HARDENED`, `SHUFFLE_PAGE_ALLOCATOR`,
`PAGE_POISONING`, `SECURITY_DMESG_RESTRICT`, `DEBUG_LIST`, `REFCOUNT_FULL`.
### AXP `kernel_patches` shape
| Series | 4.14 patches | Role |
|--------|-------------:|------|
| `0001-LinuxIncrementals` | 335 | Version bumps — **skip** (tree already 4.14.357-openela) |
| `0004`–`0006`, `0008-*`, `0009` | ~40 Graphene/AH | Stage-1 candidates (below) |
| `CVE-*` dirs | ~2301 with 4.14 | Mega CVE stage — **later**, after Stage 1 boots |
| Location-related | — | **Skip** (FR-018 policy) |
### IodéOS
`v5-staging` manifest cloned; **no** `sunfish` / `msm-4.14` kernel project in
snippets. Public gitlab device/kernel repos need auth. Treat Iodé as
**userspace privacy** for this device; no extra 4.14 kernel delta found.
## Source priority (owner 2026-09-18)
| Priority | Source | Role |
|----------|--------|------|
| 1 | **AXP** sunfish kernel / build patches | Clone first (max) |
| 2 | **LOS 23.2** msm-4.14 as shipped | Inventory; skip dupes |
| 3 | **IodéOS** (LOS fork) | Diff for extra 4.14-safe hardening/deblob |
| 4 | **GrapheneOS** | Optional: modern techniques / docs; A13 sunfish only if clearly useful |
| — | **DivestOS** standalone | **Do not hunt** (EOL). AXP-inherited commits OK via AXP clone |
## Location policy
**Do not** extra-cap location vs LOS defaults (FR-018). Skip AXP location
lockdown patches; document as skipped. Goal: **precise, fast GPS** like
stock LOS 23.2 — not AXP privacy lockdown. Deblob/CVE stages must not
reintroduce location hardening by accident.
## Sequential apply probe (Graphene/AH only)
Clean worktree @ `28f9290ae067`, patches from AXP `kernel_patches` in Divest-like
order (`4.14` then `ANY`). Result: **OK=30, SKIP_ALREADY=4, FAIL=12**.
Full machine log:
`/srv/rom/artifacts/009-axp-los23-port/kernel-harden-dryrun/apply-sequential-summary.txt`
## Patch ledger
| id | title | source | AXP? | 4.14-safe? | decision | notes |
|----|-------|--------|------|------------|----------|-------|
| KH-INC | LinuxIncrementals 4.14 (335) | AXP `0001` @ df3cab215 | Y | n/a | **skip** | Already 4.14.357-openela |
| KH-004 | Perf events restrict | AXP `0004` ANY/0001 | Y | Y | **skip** | Already in LOS (`SKIP_ALREADY` + defconfig) |
| KH-005 | Deny USB (toggle) | AXP `0005-Graphene-Deny_USB` 4.14/0003 | Y | Y | **stage1 apply** | Clean apply |
| KH-006 | wcnss buffer fixes | AXP `0006` ANY/0001–0003 | Y | ? | **skip/port later** | Wrong path on this tree (`can't find file`) |
| KH-008-as | alloc_size attrs | AXP `0008-…-allocsize` | Y | Y | **stage1 apply** | OK: 0002,0011,0016,0021; FAIL: 0007 (vmalloc.h hunk) |
| KH-008-bug | ksize BUG_ON | AXP `0008-…-bugon` 0010 | Y | Y | **stage1 apply** | OK |
| KH-008-fort | FORTIFY intra-object | AXP `0008-…-fortify` 0004 | Y | Y | **stage1 apply** | OK; then enable `CONFIG_FORTIFY_SOURCE` |
| KH-008-misc | misc Graphene | AXP `0008-…-misc` | Y | Y | **stage1 apply** | OK 0001,0005,0010,0018; SKIP 0021 + ANY/0015 |
| KH-008-rnd | brk/arg randomize | AXP `0008-…-random` | Y | Y | **stage1 apply** | All 4 OK when sequential |
| KH-008-ro | __ro_after_init / sysctl RO | AXP `0008-…-ro` | Y | partial | **stage1 apply** | OK most; FAIL 0007, 0034 (sysctl drift) |
| KH-008-san | page/slab sanitize | AXP `0008-…-sanitize` | Y | Y | **stage1 apply** | All 4 OK sequential |
| KH-008-slab | SLAB_HARDENED | AXP `0008-…-slab` | Y | partial | **stage1 apply** | OK 0006,0014; FAIL 0010,0018 |
| KH-008-un | unused-fn noise | AXP `0008-…-unused` | Y | Y | **stage1 apply** | OK (build hygiene) |
| KH-009 | rfc4941bis IPv6 | AXP `0009` | Y | partial | **skip** | 4.14/0003 already present; ANY/* fail |
| KH-CVE | CVE clean-offset 429 + denylist | AXP `CVE-*` | Y | LAB OK `#47` | **ship partial** | `cve-clean-offset.list` (ex-430−49980); high-offset ≥200 quarantined; `CVE-2022-49980` denylist (udc_lock); see `009-cve-bisect-plan.md` / `009-axp-graphene-remaining.md` |
| KH-LOC | AXP location lockdown | AXP | Y | — | **skip** | FR-018 |
| KH-IODE | Iodé kernel delta | Iodé | — | — | **skip** | No sunfish 4.14 fork found |
| KH-CFG | Hardening defconfig | LOS+AXP | — | Y | **stage1 after patches** | Flip gaps that Kconfig allows post-patch |
| KH-US-S5-1 | Yama + SLAB_FREELIST_RANDOM | Graphene/AXP class | Y | Y | **apply** | `apply_uss5_1_defconfig.sh`; LSM already listed yama |
### Stage 1 apply list (exact files)
From host `$KP=/srv/rom/references/axp/kernel_patches` — **only** these (order
matters):
```
0005-Graphene-Deny_USB/4.14/0003.patch
0008-Graphene-Kernel_Hardening-allocsize/4.14/0002.patch
0008-Graphene-Kernel_Hardening-allocsize/4.14/0011.patch
0008-Graphene-Kernel_Hardening-allocsize/4.14/0016.patch
0008-Graphene-Kernel_Hardening-allocsize/4.14/0021.patch
0008-Graphene-Kernel_Hardening-bugon/4.14/0010.patch
0008-Graphene-Kernel_Hardening-fortify/4.14/0004.patch
0008-Graphene-Kernel_Hardening-misc/4.14/0001.patch
0008-Graphene-Kernel_Hardening-misc/4.14/0005.patch
0008-Graphene-Kernel_Hardening-misc/4.14/0010.patch
0008-Graphene-Kernel_Hardening-misc/4.14/0018.patch
0008-Graphene-Kernel_Hardening-random/4.14/0002.patch
0008-Graphene-Kernel_Hardening-random/4.14/0007.patch
0008-Graphene-Kernel_Hardening-random/4.14/0012.patch
0008-Graphene-Kernel_Hardening-random/4.14/0017.patch
0008-Graphene-Kernel_Hardening-ro/4.14/0002.patch
0008-Graphene-Kernel_Hardening-ro/4.14/0012.patch
0008-Graphene-Kernel_Hardening-ro/4.14/0017.patch
0008-Graphene-Kernel_Hardening-ro/4.14/0028.patch
0008-Graphene-Kernel_Hardening-ro/4.14/0030.patch
0008-Graphene-Kernel_Hardening-ro/4.14/0032.patch
0008-Graphene-Kernel_Hardening-ro/4.14/0038.patch
0008-Graphene-Kernel_Hardening-sanitize/4.14/0005.patch
0008-Graphene-Kernel_Hardening-sanitize/4.14/0009.patch
0008-Graphene-Kernel_Hardening-sanitize/4.14/0015.patch
0008-Graphene-Kernel_Hardening-sanitize/4.14/0017.patch
0008-Graphene-Kernel_Hardening-slab/4.14/0006.patch
0008-Graphene-Kernel_Hardening-slab/4.14/0014.patch
0008-Graphene-Kernel_Hardening-unused/4.14/0001.patch
0008-Graphene-Kernel_Hardening-unused/4.14/0002.patch
```
Then defconfig (only options that exist after patches): at least
`CONFIG_FORTIFY_SOURCE=y`; evaluate `INIT_ON_*` / slab freelist / dmesg restrict
against Kconfig `depends on` before flipping.
## Applied / skipped summary
- **Applied (2026-09-18, live tree):** Stage 1 — 30 AXP Graphene/AH patches via
`vendor/sunfish-a16/patches/009-kernel-hardening/apply_stage1.sh` onto
`/srv/rom/src/lineage/kernel/google/msm-4.14` (Stage1 alone ~28 paths;
tree also had prior Magisk-track dirt: KSU/SusFS `# CONFIG_* is not set`
stubs + residual SusFS-touched fs/overlayfs etc. — not Stage1).
- **Defconfig (same day):** `CONFIG_FORTIFY_SOURCE=y`,
`CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y`, `CONFIG_INIT_ON_FREE_DEFAULT_ON=y`,
`CONFIG_SECURITY_DMESG_RESTRICT=y`, `CONFIG_SLAB_HARDENED=y`.
- Skipped: location lockdown (policy); Divest-as-hunt (policy); LinuxIncrementals;
KH-004 (already present); KH-006 wcnss (path miss); KH-009 ANY; Iodé kernel
(none found); CVE mega (in progress via `cve_checker`)
- Failed probe (port later): allocsize/0007, ro/0007+0034, slab/0010+0018
- **Build fix 2026-09-18:** Stage1 `slab/0014` misfuzzed into `is_root_cache`
(`return p == s` with no `p`) — reverted that stub. Intent was
`slab_equal_or_root`; LOS already has `return s == p` there.
- **Build fix 2026-09-18b:** `CONFIG_FORTIFY_SOURCE=y` + Clang LTO left
`__read_overflow*` undefined in modules (qcacld/techpack) — added `BUG()`
stubs + `EXPORT_SYMBOL` in `lib/string.c`.
- **Bacon OK (Stage1 only):**
`/srv/rom/artifacts/009-axp-los23-port/20260918T180359Z-axp-kh-stage1/`
- **CVE bacon OK:**
`/srv/rom/artifacts/009-axp-los23-port/20260918T215034Z-axp-kh-cve/`
Stage1 + ~500 CVE patches that compile. ~34 incomplete series on denylist
(`cve-stage/denylist.txt`) — skipped, not silently dropped without a log.
Magisk preroot present; KernelSU absent.
- **More complete bacon OK:**
`/srv/rom/artifacts/009-axp-los23-port/20260918T231654Z-axp-kh-full/`
AXP `hardenDefconfig` on the CVE tree (only options this Kconfig has).
Left on: `IO_URING`, `USERFAULTFD`, WireGuard, IPA. Magisk preroot OK.
- **Not done:** userspace Deblob.sh (Widevine/IMS/CNE). Kernel deblob in AXP
is mostly IPA removal — skipped so mobile data keeps working.
- **Flash target (LAB 2026-09-21):** back on
`20260918T143547Z-axp-full` (pre-kernel-hardening). Owner confirmed boot OK.
- **Boot-fail (LAB 2026-09-21):** all three KH artifacts hang at Google logo
(bootloader splash, never recovery/Android):
- `231654Z-axp-kh-full`, `215034Z-axp-kh-cve`, `180359Z-axp-kh-stage1`
- Stage1 **`boot-make.img` (no Magisk)** also hangs → kernel Stage1 (+
Stage1 defconfig extras), not Magisk packaging.
- OTA `payload` boot == Magisk artifact boot; OTA `dtbo` identical across
good vs Stage1. Loose `dtbo.img`/`vbmeta.img` in artifact dirs ≠ payload
(do not flash those sueltos). Embedded boot `dtb` identical all four.
- `/sys/fs/pstore` empty after failed boots (no ramoops).
- **Bisect 2026-09-21:** `20260921T185024Z-bisect-defconfig-only`
(clean LOS + FORTIFY/INIT_ON_*/DMESG/SLAB_FREELIST_HARDENED, no Graphene
patches) → LAB **bootloop** / try-again recovery.
- **LAB 2026-09-28:** Clang FORTIFY nested-`strlen` fix (`strlcpy`/`strcpy` →
`__underlying_strlen`). Family `full` + **combo4+FORTIFY** boot. Magisk bacon:
`apply_combo4_fortify.sh` / `009-bacon-axp-combo4-fortify.sh`.
- **LAB 2026-09-29 (ship kernel pack):** Stage1 (30) + combo4 + Clang FORTIFY
Magisk bacon `20260929T123401Z-axp-stage1-combo4` — boots, Wi‑Fi CRC OK,
Deny USB sysctl present. Attribution: `docs/009-gate-g-kernel-attribution.md`.
Apply: `apply_stage1_combo4.sh`. Bacon: `009-bacon-axp-stage1-combo4.sh`.
- **CVE re-try 2026-09-29:** full `cve-strict` (503) = LAB Google logo hang.
Bisect: `docs/009-cve-bisect-plan.md` (`cve-bisect-h1/h2.list`).
- **Bisect 2026-09-21 mild:** `DMESG_RESTRICT` + `SLAB_FREELIST_HARDENED`
only → same failure.
- **Control 2026-09-26:** `20260918T143547Z` **boot-make.img** (no Magisk,
no extra CONFIG) flashed onto Magisk system → **boots OK**.
- **Audit 2026-09-26 (owner second opinion):** bisect scripts wrongly used
`lunch …-bp2a-userdebug` while good bacon uses `breakfast` → `bp4a`.
Mild/defconfig-only boots carry `security_patch=2025-08-05` / SDK 36.0 vs
GOODMAKE `2026-09-01` / 36.1; ramdisk and other kernel options also differ.
**Invalidates** “DMESG/SLAB alone kill boot”. bp2a one-config builds aborted.
See `docs/009-kernel-boot-audit-20260926.md`.
- **Control ksync 2026-09-26:** new breakfast/bp4a kernel (no Stage1 CONFIG)
injected into GOODMAKE ramdisk → LAB **boots OK** (`20260926T161646Z-bisect-ksync-control`).
Method validated. Next: same inject path, one CONFIG at a time (DMESG then SLAB).
**Future tests:** always `breakfast`/bp4a + inject kernel into GOODMAKE ramdisk;
never bp2a-only bootimage as a “config” experiment. Lessons also in agent
personal store `009-kernel-bisect-lessons.md`.
Deblob still deferred (GPS: no AXP location lockdown).
## CVE / hardening / deblob policy (owner 2026-09-18 evening)
- **Source of truth**: AXP method (`kernel_patches` + `cve_checker`), applied onto
LOS23 `msm-4.14` — not inventing our own CVE hunt.
- **Skip if already fixed** in LOS tree (patcher “already applied” / reverse
hunks). LOS23 is newer than AXP22; many CVEs may already be present via
`4.14.357-openela`. Hardening/deblob are where AXP usually still wins.
- **Loose 4.19**: when enabled, the patcher may also try patches filed under
`4.19/` (and with extreme matching, even `^5.x`/`^6.x`) on a `4.14` tree.
First pass with loose ON applied ~185 non-4.14 patches and **broke the
build** (incomplete binder/bpf/f2fs series). **OFF for CVE apply** (exact
`4.14` + `ANY` only). Re-evaluate later if needed.
- **On failure**: do not silent-drop — attempt fix / adapt / re-apply; only
then document skip with reason (AXP `Fix_CVE_Patchers` style).
- **Deblob**: AXP deblob pass after CVE/hardening inventory (separate from CVE
IDs); Lineage rarely matches AXP here.
- **Flash**: owner on return; agent does not need to flash for this phase.
## 2026 catalog refresh (started 2026-09-19)
CIP `kernel-sec` cloned at `/srv/rom/references/cip-kernel-sec` @ `025be706`
(2026-09-19). Scrape vs AXP catalog `df3cab215` (2025-10-30): **7086** CVEs
not in that list (6317× CVE-2026, 769× CVE-2025). **None** have a `4.14`
backport link; one has `4.19`. The rest are mainline / 5.10+.
kernel.org `linux-stable` `v4.14.*` stops at **4.14.336**. Nothing newer to
incremental-apply; the LOS tree is already `4.14.357-openela`.
Android bulletins (new URL `/docs/security/bulletin/YYYY/YYYY-MM-01`, which
the jar scraper does not accept) have **no** `git.kernel.org` links. Kernel
rows point at `android.googlesource.com/kernel/common`: 2025-12 (44),
2026-03 (36), 2026-06 (2), 2026-09 (10). Links saved in
`/srv/rom/artifacts/009-axp-los23-port/cve-2026/asb-links.txt`.
Download + checker (read-only on the live tree; does not reset the flashed
kernel) is detached as tmux `009-cve-2026`. One mainline patch per new CVE
lands in `/srv/rom/references/axp/kernel_patches_2026/`. Apply is **not**
started: 2026 patches are 6.x and the last loose pass broke 4.14.
+22
View File
@@ -0,0 +1,22 @@
# LAB acceptance note — 20261002T103558Z (AVB infra ship)
Device: `11231JEC207477`
Artifact: `20261002T103558Z-axp-stage1-combo4-cve-hi-releasekeys`
Ship zip twin: `AXP-Resurection-Pro-23.2-20261002-sunfish.zip` (= lineage zip bytes)
Owner smoke 2026-10-02: no errors reported after sideload + boot/vbmeta reinforce.
| Gate | Status | Notes |
|------|--------|-------|
| A Boot/HW | pass (owner) | Boots home; Wi‑Fi/BT/call smoke OK per owner |
| B Google stack | pass (prior+owner) | microG/Phonesky path unchanged this bacon |
| C Toggles | pass (prior) | Spoof / call-rec not regressed this bacon |
| D Magisk | pass | `magiskd` present; preroot; unlocked orange |
| E Banking | deferred | Not MVP |
| F Usability | pass (prior) | Bundled apps / WebView LOS |
| G Hardening | partial | Release-keys + AVB **signing** infra (flags 3); US-S4 stage0 measure done; US-S4-1 code pending next content bacon |
`ro.lineage.version` on this flash is still `23.2-20261002-UNOFFICIAL-sunfish`
(pre-branding.mk). Next content bacon picks up
`…-UNOFFICIAL-AXP-Resurection-Pro-…`.
+27
View File
@@ -0,0 +1,27 @@
# LAB acceptance — 20261002T151944Z (US-S4-1 + Pro branding)
Device: `11231JEC207477`
Artifact: `20261002T151944Z-axp-stage1-combo4-cve-hi-releasekeys`
Ship: `AXP-Resurection-Pro-23.2-20261002-sunfish.zip`
Sideload + boot/vbmeta/dtbo reinforce 2026-10-02 evening. Owner/ChatGPT artifact
gates + LAB post-boot checks below.
| Gate | Status | Notes |
|------|--------|-------|
| A Boot/HW | pass | `sys.boot_completed=1`, slot `_a` |
| B Google stack | pass (prior) | microG/Phonesky unchanged this bacon |
| C Toggles | pass (prior) | Not regressed |
| D Magisk | pass | `magiskd` pid present; TF Magisk boot reinforced |
| E Banking | deferred | |
| F Usability | pass (prior) | |
| G Hardening | pass (this pack) | AVB **signing** infra flags=3; US-S4-1 OpenSSH/rsync/procmem absent; `init.openssh.rc` present (AXP) |
Props:
- `ro.lineage.version=23.2-20261002-UNOFFICIAL-AXP-Resurection-Pro-sunfish`
- `ro.axp.resurection.track=pro`
- `ro.boot.flash.locked=0`
- no `/product/bin/sshd`, no `/product/bin/rsync`
- `/product/etc/init/init.openssh.rc` present
Prior AVB-only ship note: `docs/009-lab-acceptance-20261002-avb.md` (`103558Z`).
+27
View File
@@ -0,0 +1,27 @@
# LAB acceptance — 20261002T162840Z (US-S5-1 Yama + SLAB_FREELIST_RANDOM)
Device: `11231JEC207477`
Artifact: `20261002T162840Z-axp-stage1-combo4-cve-hi-releasekeys`
Ship: `AXP-Resurection-Pro-23.2-20261002-sunfish.zip`
Sideload Pro zip + reinforce Magisk `boot`/`dtbo`/`vbmeta`/`vbmeta_system` on
active slot `_b` (2026-10-02 evening).
| Gate | Status | Notes |
|------|--------|-------|
| A Boot/HW | pass | `sys.boot_completed=1`, slot `_b` |
| B Google stack | pass (prior) | microG/Phonesky unchanged this bacon |
| C Toggles | pass (prior) | Not regressed |
| D Magisk | pass | `magiskd` present; TF Magisk boot reinforced |
| E Banking | deferred | PIF/Vector BL spoof — owner config, not this pack |
| F Usability | pass (prior) | |
| G Hardening | pass (this pack) | US-S5-1: `CONFIG_SECURITY_YAMA=y`, `CONFIG_SLAB_FREELIST_RANDOM=y`, LSM lists `yama`; US-S4-1 OpenSSH still absent; `init.openssh.rc` present |
Props:
- `ro.lineage.version=23.2-20261002-UNOFFICIAL-AXP-Resurection-Pro-sunfish`
- `ro.axp.resurection.track=pro`
- `ro.boot.flash.locked=0`, `verifiedbootstate=orange`
- `/proc/config.gz`: YAMA + SLAB_FREELIST_RANDOM + `LSM=…,yama,…`
Recover baseline: `20261002T085915Z-axp-stage1-combo4-cve-hi-releasekeys` (README).
Prior US-S4 LAB: `docs/009-lab-acceptance-20261002-uss4.md` (`151944Z`).
+22
View File
@@ -0,0 +1,22 @@
# 009 localization / location: AXP vs LOS (deferred — FR-018)
**Status**: Look later — **not** an MVP acceptance gate.
Owner note (2026-09-17): AXP has historically felt aggressive on localization /
location; want a deliberate compare vs stock LineageOS before cloning that
policy blindly.
## What to compare later
| Area | AXP / GOLDEN | Stock LOS 23 | Decision TBD |
|------|--------------|--------------|--------------|
| Network location / NLP backends | microG BeaconDB path (see `004`/`005` docs) | LOS + microG defaults | |
| Location permission defaults | | | |
| Privacy toggles / sensors | | | |
| Extra lockdown patches | | | |
| UX: “how much it capea” | Owner complaint baseline | | |
## Until then
Do **not** invent extra location lockdown beyond what the rest of the AXP clone
already implies. Matrix row = `deferred`.
+111
View File
@@ -0,0 +1,111 @@
# 009 Magisk preinstall runbook (AXP / GOLDEN class)
**Device roles**: GOLDEN `11071JEC203839` = `adb` **read-only** oracle.
LAB `11231JEC207477` = flash/test only. **Never** flash or Magisk-change GOLDEN.
**Evidence**: `/srv/rom/artifacts/009-axp-los23-port/`
**Contract**: `specs/009-axp-los23-port/contracts/magisk-preinstall.md`
## Ship policy (owner 2026-09-17)
- **Clone AXP first (mandatory):** Magisk packaging = EXTENDROM
`EXTENDROM_PREROOT_BOOT` method. Copy that flow; do **not** invent alternate
Magisk install paths. Only diverge if LOS23 / Magisk version breaks the
AXP/EXTENDROM path, and document why.
- **Magisk clean**: ship Magisk preroot only — **do not** bake GOLDEN modules
(`playintegrityfix`, `teesim`, `hosts`, `flag-secure-disabler`,
`zygisk_vector`, …). Owner installs modules later if wanted.
- **Manager UI**: stock **Magisk** upstream (not Magia branding).
- **Dormant until activation (AXP Pro):** after flash, Magisk is pre-rooted in
boot but root must stay inactive until the user opens Magisk and completes
Additional Setup. Skipping setup ⇒ no `su` / no Magisk binaries in the OS
(undetectable). Do **not** bake Magisk as `PRODUCT_PACKAGE`; do **not**
sideload the full Magisk APK before measuring virgin LAB state.
- **Build host**: LAB/GOLDEN USB **not required** to compile. Phones only for
measurement (GOLDEN `adb`) or flash validation (LAB).
## GOLDEN measurement (2026-09-17, live `adb`)
| Item | Value |
|------|--------|
| Build | `22.2-2026.003-sunfish-pro` / `BP1A.250505.005` |
| Magisk binary | **29.0:MAGISK:R** (`29000`) at `/system_ext/bin/magisk` |
| Also present | `/system_ext/bin/magiskpolicy` |
| Runtime | `/data/adb/magisk/` full toolkit + `stub.apk`; `magisk.db` |
| Settings (sqlite via `magisk --sqlite`) | `zygisk=1`, `denylist=1`, `mnt_ns=2`, `bootloop=0` |
| Manager UI | Magisk app **hidden/renamed** (random pkg `oq.aq.cjn`, `versionName=1.0`) — AXP brands this UI as **Magia** in docs/screenshots; package name is not stable after “Hide the Magisk app” |
| Modules seen | `flag-secure-disabler`, `hosts`, `playintegrityfix`, `teesim`, `zygisk_vector` |
| Secure toggles | `allow_signature_fake=1`, `extendrom_call_recording=1` |
**Important:** GOLDEN is already **fully activated**. The virgin
“preinstalled but not fully activated” UX is the **first-boot / additional
setup** Magisk flow after an AXP-style preroot image (see AXP setup guide +
EXTENDROM FAQ: “Requires Additional Setup”). Measure that class from AXP docs +
EXTENDROM `PREINITDEVICE=userdata` behaviour — do not wipe GOLDEN to re-see it.
## How AXP / EXTENDROM builds Magisk into the ROM
Attribute: **sfX-android `android_vendor_extendrom`** + Magisk APK.
1. `EXTENDROM_PREROOT_BOOT=true` — Magisk is **not** a normal PRODUCT_PACKAGE;
it patches **boot / init_boot** at image build time.
2. Magisk APK (v22+) is unzipped under `out/.magisk/`; `boot_patch.sh` runs via
`vendor/extendrom/config/magisk/patch.sh`.
3. Releasetools inject: patch under
`config/magisk/{lineage|axp}/A{version}/0001-build_make_tools_releasetools_common.py`
hooks `common.py` `_BuildBootableImage` / prebuilt boot.
4. Patcher env of note: `KEEPVERITY=true`, `KEEPFORCEENCRYPT=true`,
`PREINITDEVICE=userdata`, `BOOTMODE=false`.
5. Post-flash **virgin**: stub may appear; `/system_ext/bin/magisk` and `su`
appear only **after** user activation (AXP FAQ “Revert Magisk activation”).
Measure virgin before opening Magisk. GOLDEN already activated is not virgin.
Host reference tree: `/srv/rom/references/extendrom/` on `rom-dev01`.
## Enable Magisk on next bacon (009)
```bash
export ANDROID_BUILD_TOP=/srv/rom/src/lineage
export OUT_DIR=/srv/rom/src/lineage/out # or /srv/rom/out-009 for parallel
export SUNFISH_A16_MAGISK_PREROOT=1
# Copy staged runtime into OUT (or re-run prepare):
# rsync -a /srv/rom/prebuilts/magisk/runtime/ "$OUT_DIR/.magisk/"
# or: MAGISK_STAGE_DIR=$OUT_DIR/.magisk vendor/sunfish-a16/magisk/prepare_magisk.sh
```
Hook is already in `build/make/tools/releasetools/common.py` but **no-ops** unless
`SUNFISH_A16_MAGISK_PREROOT=1` (008 in-flight stays safe).
1. Clean-flash LAB with Magisk-preroot `009` images (wipe `/data` if LAB had
Magisk activated before).
2. **Virgin check (before opening Magisk):**
`adb shell 'which su; which magisk; ps -A | grep magiskd'` — expect no `su`,
no Magisk binaries (AXP dormant). Record under `…/magisk/pre-activation.md`.
3. Open Magisk stub → download/install full Magisk if prompted → complete
**Additional setup** → reboot (AXP setup guide).
4. Confirm `magisk -v` matches pin (target: newest workable stable; host aims
at **v30.7** unless regression).
5. Enable Zygisk + DenyList as needed.
6. For DenyList smoke (MVP): hide a **non-bank test package** before first open.
7. Banking DenyList workflow = **deferred** (US3 / Gate E).
## Optional KernelSU recycle (FR-016)
Paths under `/srv/rom/artifacts/007-*/` — debug/reference only. **Not ship.**
Never gate Magisk acceptance on KSU.
**Hard rule for Magisk LAB:** `sunfish_defconfig` must keep `# CONFIG_KSU is not
set` (and SusFS off). Magisk + in-kernel ReSukiSU/KSU on the same boot causes
app `failed to attach` / `start timeout` and hung `su`.
**Full AXP-clone bacon (detached):**
`/srv/rom/artifacts/009-axp-los23-port/scripts/009-bacon-axp.sh`
session `009-bacon-axp` — Magisk preroot + noksu + Phonesky exact-alarm +
WMS FLAG_SECURE (no `ro.debuggable` gate). After zip sideload, flash
artifact `boot.img` (TF IMAGES) to both slots.
## Staged known-good images (FR-013)
Keep prior LAB flashables + SHA-256 under
`/srv/rom/artifacts/009-axp-los23-port/<build-id>/` before each risky Magisk or
hardening stage.
+34
View File
@@ -0,0 +1,34 @@
# AXP Private DNS providers (from GOLDEN Settings)
Source: `Settings.apk` on GOLDEN `11071JEC203839`
(`22.2-2026.003-sunfish-pro`), pulled 2026-09-18.
Artifact: `.local-artifacts/002-golden/20260918-private-dns/Settings.apk`
Stock AOSP/LOS radios: Off / Automatic / Provider hostname.
AXP adds the following preset radios (hostname → DoT provider):
| key (resource) | UI label (en) | hostname |
|----------------|---------------|----------|
| `adguard` | AdGuard (CT) | `dns.adguard.com` |
| `appliedprivacy` | AppliedPrivacy (AT) | `dot1.applied-privacy.net` |
| `cira` | CIRA (CA) | `protected.canadianshield.cira.ca` |
| `cleanbrowsing` | CleanBrowsing (US) | `security-filter-dns.cleanbrowsing.org` |
| `cloudflare` | Cloudflare (US) | `security.cloudflare-dns.com` |
| `controld` | Control D (CA) | `p2.freedns.controld.com` |
| `cznic` | CZ.NIC (CZ) | `odvr.nic.cz` |
| `dnssb` | DNS.SB (DE) | `dot.sb` |
| `dnszero` | DNS0 (FR) | `zero.dns0.eu` |
| `google` | Google (US) | `dns.google` |
| `mullvad` | Mullvad (SE) | `base.dns.mullvad.net` |
| `quadnine` | Quad9 (CH) | `dns.quad9.net` |
| `restena` | Restena (LU) | `kaitain.restena.lu` |
| `switch` | SWITCH (CH) | `dns.switch.ch` |
| `uncensoreddns` | UncensoredDNS (DK) | `anycast.censurfridns.dk` |
Plus stock: Off, Opportunistic (Automatic), custom Provider hostname.
AXP setup docs recommend Quad9 (`dns.quad9.net`) and DNS0 (`zero.dns0.eu`).
Clone target for LOS 23.2: extend `PrivateDnsModeDialogPreference` +
`private_dns_mode_dialog.xml` + strings to match this set (no `axp.os`
branding).
+30
View File
@@ -0,0 +1,30 @@
# 009 — Sideload system package updates (FR-019)
Owner cadence: refresh bundled **system / privileged** packages about every
**2–3 months** without a full ROM reflash. **No** AXP OTA / external repos.
Status: **stub** — fill before final ship (task T046a). Packaging of the
shipping image MUST already preserve update eligibility.
## In scope
| Component | Intended update path | Signing constraint |
|-----------|----------------------|--------------------|
| microG GmsCore / companions | `adb install -r` / recovery sideload of upstream APK | **PRESIGNED** / same signer as shipped |
| Magisk | Magisk app self-update and/or documented boot re-patch | Manager + boot image must stay matched |
| Project Phonesky | Sideload project-signed APK | **Same project key** across releases |
| Other bundled system apps | Sideload matching-signer APK (or recovery zip if priv-app needs it) | Same identity as image |
## Out of scope
- Network OTA / AXP update servers
- Full `bacon` + clean flash for routine APK bumps (still OK for kernel /
framework / Magisk boot changes when required)
## Checklist before claiming FR-019 done
- [ ] Each row above has a concrete command/runbook step
- [ ] `pm install` / PackageManager does not reject for signature mismatch
- [ ] Privileged permissions still grant after update (or re-flash privapp XML noted)
- [ ] Magisk version after update matches kernel/boot expectation
- [ ] Record new versions in `docs/009-version-pins.md`
+52
View File
@@ -0,0 +1,52 @@
# US-S4 — Userspace hardening (first stage)
Status 2026-10-02. No bacon solely for this doc.
## Stage 0 — LAB baseline (measure, closed)
On LAB `11231JEC207477` after AVB ship `20261002T103558Z` (+ boot/vbmeta reinforce):
| Check | Result |
|-------|--------|
| SELinux | Enforcing |
| Encryption | `ro.crypto.state=encrypted`, `ro.crypto.type=file` |
| Verified boot | orange / `flash.locked=0` (unlocked Magisk track) |
| `security.perf_harden` | 1 (already) |
| Yama / `ptrace_scope` | **done** (US-S5-1 `162840Z`) — `CONFIG_SECURITY_YAMA=y` |
## Stage 1 — US-S4-1 drop product OpenSSH / rsync / procmem
**Oracle**: `AXP.OS-22.2-20260324-PRO-sunfish.zip` product (+ system) images —
no `sshd`/`ssh`/`rsync`/`procmem` binaries; orphan `init.openssh.rc` only.
**Shipped in tree**: `vendor/sunfish-a16/hardening.mk` +
`patches/009-axp-los23-port/hardening/README.md`.
Removes Lineage product OpenSSH binaries + `rsync`, `procmem` (DEBUG).
**Keeps** `init.openssh.rc` (AXP PRO still has it). Admin path: adb + Magisk.
LAB verify after flash: no `/product/bin/sshd`, no `/product/bin/rsync`,
`/product/etc/init/init.openssh.rc` present, Magisk still up.
## Stage 2 — US-S4-2 drop Jelly + Gallery2
**Oracle**: AXP PRO product has neither; Fossify on system_ext. See
`docs/009-axp-pro-product-apps-20260324.md`.
Wired: `apply_009_drop_jelly_gallery2.py`, `NoLineageJelly` phony override,
hardening.mk filter, bacon gate. Pending next bacon + LAB.
## Later candidates (one per bacon when risk unclear)
1. Mount / noexec where stock sunfish already allows (verify HW first)
2. Package-visibility / query hardening (high app-compat risk → later)
3. Further debug-tool trim (`adb_root` only if LAB proves unused)
Promote from `docs/hardening-backlog.md` only with upstream attribution.
## Out of scope here
- `WITH_AVB=true` / flags 0
- Bootloader relock
- `lineage_sunfish-user` default lunch (US-S6)
- Kernel Yama / more CVE (US-S5)
+24
View File
@@ -0,0 +1,24 @@
# 009 version pins
Policy: newest stable (or newest tagged pre-release upstream ships) that works
on sunfish / LOS 23.2 — except Phonesky = project artifact, WebView = LOS
default. Refresh with `git fetch --tags` / release APIs before long builds.
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/` |
| 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 |
| Kernel sunfish | 4.14.357-openela | | `kernel/google/msm-4.14` @ `28f9290ae067` | los_default + FR-017 stage1 | 2026-09-18 | AXP `kernel_patches` @ `df3cab2155b3`; see `docs/009-kernel-hardening-map.md` |
| Aurora Store | present on GOLDEN | | `com.aurora.store` | newest_stable | 2026-09-17 seen | Stage APK later |
| 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 |
| Island | deferred | | `com.oasisfeng.island.fdroid` | | | US3 deferred |
## Host artifact hashes (copy from host VERSIONS when refreshed)
See `/srv/rom/prebuilts/*/VERSIONS.txt` on `rom-dev01`.
+1 -1
View File
@@ -39,7 +39,7 @@ feature. Signing/AVB, userspace hardening, and kernel hardening remain `011`–
| Magisk / preroot | Magisk (**Magia** UI on GOLDEN, 29.0) | **Substitute:** KernelSU-Next (+ SusFS) / evaluate ReSukiSU | substitute | Captured in `002`; do **not** fix GOLDEN; project root = `007` on LAB |
| DenyList / umount for banks | Magia DenyList (pkg list in `docs/002-golden-inventory.md`) | KernelSU app profiles + verified umount | todo | `007` re-runs `006`; GOLDEN DenyList captured `002` |
| Insular work profile | AXP docs say Insular; **GOLDEN measures Island** (`com.oasisfeng.island.fdroid` 6.4.2) | Banking workflow parity (Island or equivalent) | todo | `006`; capture in `002` |
| Yuh in Insular/Island | Historically worked; **FAIL since ~weeks** (HA / “certificate invalid”; KeyMint/TEE errors in `002` logs) | Hard-gate Compatibility MVP (rootless in `006`); **Revolut not a hard-gate** | partial | `002` evidence; LAB may need SusFS+TrickyStore-class stack (`reference-sources.md` §8); never GOLDEN |
| Yuh in Insular/Island | Was FAIL ~weeks (HA); **PASS again 2026-10-02 on GOLDEN** with Vector **bootloader spoofer** (`002`) | Hard-gate Compatibility MVP (rootless in `006`); **Revolut not a hard-gate** | partial | `002`; Gate E on LAB = DenyList + PIF/teesim + Vector BL spoof (sunfish-coherent); never flash GOLDEN |
| Swissquote in Insular/Island | **PASS** on GOLDEN (owner report, DenyList) | Hard-gate Compatibility MVP (rootless in `006`) | partial | `002`; re-test in `006`/`007`/`011` |
| Unrestricted call recording | Yes | Yes — native ROM on Android 16 | todo | AXP/EXTENDROM/iodé as references only; re-validate on LOS 23.2; `008` |
| DNS blocker / privacy DNS | Yes | Wanted; exact UX TBD | decide | `010` |
+21 -16
View File
@@ -55,31 +55,32 @@ Status: `candidate` | `investigate` | `accepted→spec` | `rejected` | `los-prov
The kernel base remains the LineageOS 23.2-compatible sunfish kernel.
**Priority (009 / owner 2026-09-18):** AXP clone first → LOS inventory →
IodéOS diff → optional Graphene (modern techniques / selective A13).
**Do not** separately mine DivestOS EOL. See `docs/009-kernel-hardening-map.md`.
```text
┌─ historical GOS sunfish
┌─ AXP sunfish (max priority clone)
│
LOS23/A16 sunfish 4.14 ←─┼─ AXP own + DivestOS
LOS23/A16 sunfish 4.14 ←─┼─ LOS23 already-present
OUR BASE │
├─ modern GOS techniques
├─ IodéOS (LOS fork, hardened/deblobbed)
│
└─ original upstream fixes
└─ Graphene optional (modern / selective A13)
```
**Not:** GrapheneOS Android 13 (or any old GrapheneOS) kernel tree as our base.
**Not:** DivestOS as a hunt target (EOL).
Candidate hardening comes from four classes:
Candidate hardening comes from:
1. **Historical GrapheneOS sunfish** — device-specific patches/configuration known
to have run on sunfish (real commits, not only `.config`).
2. **AXP.OS / DivestOS sunfish** — audit the actual patch stack; distinguish
AXP-owned changes from inherited changes.
3. **Modern GrapheneOS** — use current kernel hardening as a source of
techniques/security properties; adapt/backport only where feasible on
non-GKI Linux 4.14; do not assume current Pixel kernel patches cherry-pick
cleanly.
4. **Original upstream** — where a GrapheneOS/AXP/Divest patch derives from AOSP,
Android common, Linux stable, or another upstream source, prefer the
appropriate original upstream fix when practical.
1. **AXP.OS sunfish** — primary; audit actual patch stack on `rom-dev01`.
2. **LineageOS 23.2 msm-4.14** — what is already applied.
3. **IodéOS** — diff vs LOS for extra hardening/deblob worth porting.
4. **GrapheneOS** — optional: modern Pixel techniques adaptable to 4.14;
historical sunfish A13 only if clearly still valuable.
5. **Original upstream** — when a patch derives from Linux/AOSP common,
prefer upstream form when practical.
For each candidate record:
@@ -96,6 +97,10 @@ For each candidate record:
- test result;
- final decision.
**Location:** do not extra-cap vs LOS (owner GPS UX); skip AXP location
lockdown in this track unless revisited later.
## Much later / evaluate
| Idea | Notes | Status |