Files
AXP-Resurection/docs/009-kernel-hardening-map.md
T
sunfish-admin deaaf42caa 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.
2026-10-05 10:42:00 +02:00

268 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.