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

+26
View File
@@ -0,0 +1,26 @@
# Magisk preroot (sunfish-a16 / 009)
**Policy:** clone AXP / EXTENDROM `EXTENDROM_PREROOT_BOOT` — do not invent.
Diverge only if LOS23 or Magisk version breaks that path.
**Clean Magisk**, stock UI. No GOLDEN modules. No KernelSU in ship kernel.
| File | Role |
|------|------|
| `prepare_magisk.sh` | Unzip Magisk APK → `$OUT_DIR/.magisk` (same as extendrom `er.sh`) |
| `patch.sh` | From sfX extendrom — patches boot.img via Magisk `boot_patch.sh` |
| `apply_releasetools_hook.py` | Inject into releasetools `common.py` (A16) |
AXP virgin UX: Magisk not a `PRODUCT_PACKAGE`; root inactive until user
Additional Setup. See `docs/009-magisk-preinstall-runbook.md`.
```bash
export SUNFISH_A16_MAGISK_PREROOT=1 # optional; READY file is the real gate
MAGISK_STAGE_DIR=$ANDROID_BUILD_TOP/out/.magisk \
vendor/sunfish-a16/magisk/prepare_magisk.sh
python3 vendor/sunfish-a16/magisk/apply_releasetools_hook.py --top "$ANDROID_BUILD_TOP" --force
```
Hook **v2** runs when `out/.magisk/READY` exists (preferred) and/or
`SUNFISH_A16_MAGISK_PREROOT=1`. Env alone is unreliable under soong/ninja.
Without READY / env the hook no-ops.
+149
View File
@@ -0,0 +1,149 @@
#!/usr/bin/env python3
"""Idempotent Magisk preroot hook into releasetools common.py (LOS 23.2 / A16).
Gate (either is enough):
- ``out/.magisk/READY`` present (preferred — survives ninja/soong env scrubbing)
- ``SUNFISH_A16_MAGISK_PREROOT=1``
Matches sfX extendrom inject (always-on once staged), adapted for A16 + our
vendor path. ``RunAndCheckOutput`` env is merged with ``os.environ`` so PATH /
ANDROID_BUILD_TOP survive (extendrom only passed ``system_root_image``; that
works via shebang but is fragile under sandboxes).
"""
from __future__ import annotations
import argparse
import os
import pathlib
import re
import sys
MARKER = "SUNFISH_A16: Magisk preroot hook"
MARKER_VER = "SUNFISH_A16: Magisk preroot hook v2"
BUILD_HOOK = '''
# SUNFISH_A16: Magisk preroot hook v2 (before AVB)
# Gate: staged out/.magisk/READY and/or SUNFISH_A16_MAGISK_PREROOT=1
_sf_top = os.getenv("ANDROID_BUILD_TOP") or os.environ.get("PWD") or os.getcwd()
_sf_ready = os.path.isfile(os.path.join(_sf_top, "out", ".magisk", "READY"))
_sf_env = os.environ.get("SUNFISH_A16_MAGISK_PREROOT") == "1"
if _sf_ready or _sf_env:
if ((partition_name == "boot" and info_dict.get("init_boot") != "true")
or partition_name == "init_boot"):
mpatcher = [
os.path.join(_sf_top, "vendor/sunfish-a16/magisk/patch.sh"),
img.name,
_sf_top,
]
logger.info("SUNFISH_A16 Magisk patching (build): %s", img.name)
_sf_penv = os.environ.copy()
_sf_penv["system_root_image"] = info_dict.get("system_root_image", "false")
_sf_penv.setdefault("ANDROID_BUILD_TOP", _sf_top)
RunAndCheckOutput(mpatcher, verbose=True, env=_sf_penv)
'''
PREBUILT_HOOK = '''
# SUNFISH_A16: Magisk preroot hook v2 (prebuilt)
_sf_top = os.getenv("ANDROID_BUILD_TOP") or os.environ.get("PWD") or os.getcwd()
_sf_ready = os.path.isfile(os.path.join(_sf_top, "out", ".magisk", "READY"))
_sf_env = os.environ.get("SUNFISH_A16_MAGISK_PREROOT") == "1"
if _sf_ready or _sf_env:
if ((prebuilt_name == "boot.img" or prebuilt_name == "init_boot.img")
and os.path.exists(prebuilt_path)):
if info_dict is None:
info_dict = OPTIONS.info_dict
bimg = os.path.join(_sf_top, prebuilt_path)
logger.info("SUNFISH_A16 Magisk patching (prebuilt): %s", bimg)
mpatcher = [
os.path.join(_sf_top, "vendor/sunfish-a16/magisk/patch.sh"),
bimg,
_sf_top,
]
_sf_penv = os.environ.copy()
_sf_penv["system_root_image"] = info_dict.get("system_root_image", "false")
_sf_penv.setdefault("ANDROID_BUILD_TOP", _sf_top)
RunAndCheckOutput(mpatcher, verbose=True, env=_sf_penv)
'''
def _strip_old_hooks(text: str) -> str:
"""Remove prior SUNFISH Magisk hook blocks (v1 gated or v2)."""
# Build hook: from our comment through just before AVB block
text = re.sub(
r"\n # SUNFISH_A16: Magisk preroot hook(?: v2)? \(before AVB\).*?"
r"(?=\n # AVB: if enabled)",
"\n",
text,
count=1,
flags=re.S,
)
# Prebuilt hook: after BOOTABLE_IMAGES assign, before "if os.path.exists(prebuilt_path)"
text = re.sub(
r"( prebuilt_path = os\.path\.join\(unpack_dir, \"BOOTABLE_IMAGES\", prebuilt_name\)\n)"
r"\n # SUNFISH_A16: Magisk preroot hook(?: v2)? \(prebuilt\).*?"
r"(?=\n if os\.path\.exists\(prebuilt_path\):)",
r"\1",
text,
count=1,
flags=re.S,
)
return text
def main() -> int:
ap = argparse.ArgumentParser()
ap.add_argument("--top", default=os.environ.get("ANDROID_BUILD_TOP", ""))
ap.add_argument("--dry-run", action="store_true")
ap.add_argument(
"--force",
action="store_true",
help="Replace an existing SUNFISH Magisk hook with v2",
)
args = ap.parse_args()
top = pathlib.Path(args.top or ".")
target = top / "build/make/tools/releasetools/common.py"
if not target.is_file():
print(f"ERROR: missing {target}", file=sys.stderr)
return 2
text = target.read_text()
if MARKER_VER in text and not args.force:
print(f"already applied (v2): {target}")
return 0
if MARKER in text or MARKER_VER in text:
if not args.force and MARKER_VER not in text:
# old v1 present — upgrade
pass
text = _strip_old_hooks(text)
needle_avb = (
' # AVB: if enabled, calculate and add hash to boot.img or recovery.img.\n'
' if info_dict.get("avb_enable") == "true":\n'
' avbtool = info_dict["avb_avbtool"]\n'
' if partition_name == "recovery":'
)
idx = text.find(needle_avb)
if idx < 0:
print("ERROR: AVB anchor not found", file=sys.stderr)
return 3
text = text[:idx] + BUILD_HOOK + "\n" + text[idx:]
assign = ' prebuilt_path = os.path.join(unpack_dir, "BOOTABLE_IMAGES", prebuilt_name)\n'
idx2 = text.find(assign)
if idx2 < 0:
print("ERROR: prebuilt assign not found", file=sys.stderr)
return 4
insert_at = idx2 + len(assign)
text = text[:insert_at] + PREBUILT_HOOK + "\n" + text[insert_at:]
if args.dry_run:
print("dry-run OK (v2)")
return 0
target.write_text(text)
print(f"applied v2 -> {target}")
return 0
if __name__ == "__main__":
sys.exit(main())
+122
View File
@@ -0,0 +1,122 @@
#!/bin/bash
#########################################################################################################
#
# simple patch wrapper for patching a boot.img during the build process
#
#########################################################################################################
#
# Copyright (C) 2023-2024 steadfasterX <steadfasterX -AT- binbash #DOT# rocks>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#########################################################################################################
#
# usage:
# ./patch.sh <full-path-of-boot.img>
#
#########################################################################################################
# DO NOT set -e !
# parse calling params
export BOOTIMG="$1"
export TOP="$2"
[ -z "$TOP" -o ! -d "$TOP" ] && TOP=$PWD
# colored (optional) output
PRINT(){
MSG="$2"
case $1 in
[1-9]*|E|ERROR)
echo -e "\e[0;31m$0 - ERROR: ${MSG}\e[0m" ;;
I|INFO)
echo -e "\e[1;34m$0 - INFO: ${MSG}\e[0m" ;;
0|OK|SUCCESS)
echo -e "\e[0;32m$0 - OK: ${MSG}\e[0m" ;;
*)
echo -e "$0 - ${MSG}" ;;
esac
}
PRINT I "Starting: $0 with: >$BOOTIMG< (TOP=$TOP)"
# LEGACYSAR can't be detected by the magisk patcher so must be set by us where needed (e.g. fajita).
# LEGACYSAR ensures kernel gets patched if required.
# https://github.com/topjohnwu/Magisk/blob/9aa466c7730ef4ef73195b476f9804ebf86932d2/scripts/boot_patch.sh#L220-L243
export LEGACYSAR=${system_root_image}
PRINT I "system_root_image=$LEGACYSAR"
# PREINITDEVICE can't be detected during build so must be set manually
# otherwise "Requires Additional Setup" on first start will not be able to patch w/o direct flash
# which is a problem on locked devices (obviously)
# https://github.com/AXP-OS/build/wiki/Frequently-Asked-Questions#magisk-requires-additional-setup-on-start
export PREINITDEVICE=userdata
# tell magisk that we are not in booted android
export BOOTMODE=false
# set output file descriptor to pts0 which *should* be the current shell
export OUTFD=0
# do not remove verity nor encryption
export KEEPVERITY=true
export KEEPFORCEENCRYPT=true
# set magisk environment
export OUT_DIR=$TOP/out
export MAG_DIR="$OUT_DIR/.magisk"
# disable due to not allowed binary or useless within the build process
alias dos2unix=
alias mount=echo
alias umount=echo
# enable a fallback to get properties, according to:
# https://github.com/topjohnwu/Magisk/blob/4eaf701cb79cd9255333abad8482e69987f86280/scripts/util_functions.sh#L59
getprop(){
find $OUT_DIR/target/product -type f -name build.prop -exec grep $1 {} \; | tail -n1
}; export -f getprop
test -e $BOOTIMG
PRINT $? "testing existence of >$BOOTIMG< returned: $?"
# do the magisk magic
/bin/bash $MAG_DIR/boot_patch.sh "$BOOTIMG" \
&& cp -v $MAG_DIR/new-boot.img "$BOOTIMG"
RET=$?
# simple check if magisk can be found in the resulting boot.img
grep -q --text 'magisk' $BOOTIMG
MCHK=$?
# sometimes the above is not valid even though patching was successful
if [ $MCHK -ne 0 ];then
PRINT I "Simple magisk check failed, unpacking for a detailed test..\n"
[ -d "$MAG_DIR/test" ] && rm -rf $MAG_DIR/test
mkdir $MAG_DIR/test
cd $MAG_DIR/test
$MAG_DIR/magiskboot unpack $BOOTIMG && $MAG_DIR/magiskboot cpio ramdisk.cpio test
case $? in
1|4) MCHK=0;;
*) ;;
esac
cd $TOP
rm -rf $MAG_DIR/test
fi
# check & print result
if [ "$MCHK" -eq 0 ];then PRINT OK "MAGISK found in $BOOTIMG!";else PRINT E "Magisk not found in $BOOTIMG!";fi
RET=$((RET + $MCHK))
PRINT $RET "ended with: $RET\n\n"
exit $RET
+55
View File
@@ -0,0 +1,55 @@
#!/bin/bash
# Stage Magisk v22+ APK into $OUT_DIR/.magisk (or MAGISK_STAGE_DIR) for preroot.
# Attribute: sfX-android extendrom er.sh MAGISK block + Magisk upstream.
set -euo pipefail
TOP="${ANDROID_BUILD_TOP:-${1:-}}"
OUT_DIR="${OUT_DIR:-$TOP/out}"
STAGE="${MAGISK_STAGE_DIR:-$OUT_DIR/.magisk}"
APK="${MAGISK_APK:-/srv/rom/prebuilts/magisk/Magisk-v30.7.apk}"
ARCH="${MAGISK_TARGET_ARCH:-arm64}"
if [ -z "$TOP" ] || [ ! -d "$TOP" ]; then
echo "Usage: ANDROID_BUILD_TOP=/path prepare_magisk.sh" >&2
exit 2
fi
test -f "$APK" || { echo "Missing Magisk APK: $APK" >&2; exit 4; }
rm -rf "$STAGE"
mkdir -p "$STAGE"
unzip -q "$APK" -d "$STAGE/src"
# Host tools (x86_64) for patching during build
cp "$STAGE/src/lib/x86_64/libmagiskboot.so" "$STAGE/magiskboot" 2>/dev/null \
|| cp "$STAGE/src/lib/x86/libmagiskboot.so" "$STAGE/magiskboot"
chmod 755 "$STAGE/magiskboot"
if [ "$ARCH" = "arm64" ]; then
if [ -f "$STAGE/src/lib/arm64-v8a/libmagisk64.so" ]; then
cp "$STAGE/src/lib/arm64-v8a/libmagisk64.so" "$STAGE/magisk64"
else
cp "$STAGE/src/lib/arm64-v8a/libmagisk.so" "$STAGE/magisk"
fi
cp "$STAGE/src/lib/arm64-v8a/libmagiskinit.so" "$STAGE/magiskinit"
[ -f "$STAGE/src/lib/arm64-v8a/libinit-ld.so" ] && cp "$STAGE/src/lib/arm64-v8a/libinit-ld.so" "$STAGE/init-ld"
[ -f "$STAGE/src/lib/arm64-v8a/libmagiskpolicy.so" ] && cp "$STAGE/src/lib/arm64-v8a/libmagiskpolicy.so" "$STAGE/magiskpolicy"
else
echo "Unsupported MAGISK_TARGET_ARCH=$ARCH" >&2
exit 4
fi
chmod 755 "$STAGE/src/assets/boot_patch.sh"
rm -rf "$STAGE/src/assets/dexopt" "$STAGE/src/assets/chromeos" 2>/dev/null || true
cp "$STAGE/src/assets/"* "$STAGE/"
cp "$STAGE/src/assets/boot_patch.sh" "$STAGE/root_boot.sh"
chmod 755 "$STAGE/boot_patch.sh" "$STAGE/magiskinit" "$STAGE/magiskboot"
[ -f "$STAGE/magisk64" ] && chmod 755 "$STAGE/magisk64"
[ -f "$STAGE/magisk" ] && chmod 755 "$STAGE/magisk"
[ -f "$STAGE/init-ld" ] && chmod 755 "$STAGE/init-ld"
# Point patch.sh at our vendor copy
MARKER="$STAGE/READY"
echo "apk=$(basename "$APK")" > "$MARKER"
echo "arch=$ARCH" >> "$MARKER"
echo "staged=$(date -u -Iseconds)" >> "$MARKER"
echo "OK Magisk staged at $STAGE"
cat "$MARKER"