Restore disable_configstore, EuiccDisabler and thermal CDEV guards, branding and rebuild/sync helpers; document device roles, laptop migration, and Gitea. Co-authored-by: Cursor <cursoragent@cursor.com>
268 lines
16 KiB
Markdown
268 lines
16 KiB
Markdown
# 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 | SLAB_FREELIST_RANDOM (Yama off like GOLDEN) | Graphene/AXP class | Y | Y | **apply** | `apply_uss5_1_defconfig.sh`; Yama scope 2 broke PairIP, reverted 2026-10-10 |
|
||
|
||
### 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.
|