009: Closure wave 3 deblob, handoff, and optional wave4/malloc bacons.
Ship script gates wave 4 behind AXP_DEBLOB_WAVE4, documents secrets cert path, and adds deblob appliers plus tests; docs capture Swissquote fix and parity. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
deaaf42caa
commit
3f941e8451
64 files changed
+6270
-86
No files matched your search
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
# Isolated AVB flags 0 candidate. Same ship pack as the release-key bacon.
|
||||
# WITH_AVB=true makes device/google/sunfish/BoardConfigLineage.mk skip
|
||||
# `--flags 3`. The project avb.pem and SHA256_RSA4096 stay.
|
||||
# Do not start this while another ninja owns /srv/rom/src/lineage/out.
|
||||
# Do not flash until the zip is checked and the owner asks. LAB only.
|
||||
set -euo pipefail
|
||||
export AXP_AVB_FLAGS=0
|
||||
export WITH_AVB=true
|
||||
exec "$(dirname "$0")/009-bacon-axp-stage1-combo4-cve-hi-releasekeys.sh"
|
||||
@@ -1,9 +1,21 @@
|
||||
#!/bin/bash
|
||||
# 009 bacon — ship pack with project release keys (US-S2).
|
||||
# Stage1+combo4+FORTIFY + CVE clean + hi-batch1+2+3 + PRODUCT_DEFAULT_DEV_CERTIFICATE.
|
||||
# Requires $HOME/.android-certs/releasekey.{pk8,x509.pem}. userdebug.
|
||||
# CVE-2022-49980 ships as the lock-scope port; the AXP one-liner (uevent under
|
||||
# udc_lock) stays denylisted because it hung LAB at the Google logo.
|
||||
# Requires $HOME/.android-certs/releasekey.{pk8,x509.pem}.
|
||||
# Lunch is lineage_sunfish-user (same flavor GOLDEN reports). PRO is branding,
|
||||
# not a different lunch target.
|
||||
set -e
|
||||
cd /srv/rom/src/lineage
|
||||
# Default ship keeps vbmeta flags 3. The isolated flags-0 candidate sets
|
||||
# AXP_AVB_FLAGS=0, which exports WITH_AVB=true before lunch. That is the only
|
||||
# effect in device/google/sunfish/BoardConfigLineage.mk: skip `--flags 3`.
|
||||
AXP_AVB_FLAGS="${AXP_AVB_FLAGS:-3}"
|
||||
if [[ "$AXP_AVB_FLAGS" == "0" ]]; then
|
||||
export WITH_AVB=true
|
||||
fi
|
||||
echo "AXP_AVB_FLAGS=$AXP_AVB_FLAGS WITH_AVB=${WITH_AVB:-unset}"
|
||||
export HOME=/home/android-build
|
||||
export CCACHE_DIR=/srv/rom/ccache
|
||||
export USE_CCACHE=1
|
||||
@@ -20,7 +32,15 @@ exec > >(tee -a "$LOG") 2>&1
|
||||
|
||||
echo "=== START 009-bacon-axp-cve-hi-releasekeys $(date -Is) ==="
|
||||
|
||||
CERT_DIR="${ANDROID_CERTS_DIR:-$HOME/.android-certs}"
|
||||
if [[ -z "${ANDROID_CERTS_DIR:-}" ]]; then
|
||||
if [[ -f /srv/rom/secrets/android-certs/releasekey.pk8 ]]; then
|
||||
CERT_DIR=/srv/rom/secrets/android-certs
|
||||
else
|
||||
CERT_DIR="$HOME/.android-certs"
|
||||
fi
|
||||
else
|
||||
CERT_DIR="$ANDROID_CERTS_DIR"
|
||||
fi
|
||||
if [[ ! -f "$CERT_DIR/releasekey.pk8" || ! -f "$CERT_DIR/releasekey.x509.pem" ]]; then
|
||||
echo "FAIL: missing $CERT_DIR/releasekey.{pk8,x509.pem}" >&2
|
||||
exit 1
|
||||
@@ -50,6 +70,22 @@ chmod +x "$KH"/apply_stage1_combo4.sh "$KH"/apply_cve_strict.sh \
|
||||
|
||||
bash "$KH/apply_stage1_combo4.sh" "$LIVE"
|
||||
|
||||
# AXP hunks that no longer apply cleanly, ported onto this msm-4.14.
|
||||
# misc/0021 stays omitted: LOS already has its KSYM_NAME_LEN=192 result.
|
||||
# slab/0010 and slab/0018 are already covered by virt_to_cache() plus
|
||||
# CONFIG_SLAB_FREELIST_HARDENED.
|
||||
grep -q '^#define KSYM_NAME_LEN 192$' "$LIVE/include/linux/kallsyms.h" \
|
||||
|| { echo "FAIL: KSYM_NAME_LEN is not 192 after Stage1" >&2; exit 1; }
|
||||
for PORT in \
|
||||
"$KH/ports/allocsize-0007-vmalloc-alloc-size.patch" \
|
||||
"$KH/ports/ro-0007-0034-sysctl-read-only.patch"
|
||||
do
|
||||
test -f "$PORT"
|
||||
patch -d "$LIVE" -p1 --forward --dry-run < "$PORT"
|
||||
patch -d "$LIVE" -p1 --forward < "$PORT"
|
||||
echo "applied $(basename "$PORT")"
|
||||
done
|
||||
|
||||
# US-S5-1 — Yama + SLAB_FREELIST_RANDOM (Graphene/AXP defconfig gaps)
|
||||
chmod +x "$KH/apply_uss5_1_defconfig.sh" 2>/dev/null || true
|
||||
bash "$KH/apply_uss5_1_defconfig.sh" "$LIVE"
|
||||
@@ -67,6 +103,14 @@ for L in "$LIST_HI1" "$LIST_HI2" "$LIST_HI3"; do
|
||||
bash "$KH/apply_cve_strict.sh" "$LIVE"
|
||||
done
|
||||
|
||||
PORT49980="$KH/ports/cve-2022-49980-lock-scope.patch"
|
||||
test -f "$PORT49980"
|
||||
patch -d "$LIVE" -p1 --forward --dry-run < "$PORT49980"
|
||||
patch -d "$LIVE" -p1 --forward < "$PORT49980"
|
||||
grep -q 'device_add() emits a uevent' "$LIVE/drivers/usb/gadget/udc/core.c" \
|
||||
|| { echo "FAIL: CVE-2022-49980 lock-scope missing" >&2; exit 1; }
|
||||
echo "applied $(basename "$PORT49980")"
|
||||
|
||||
DEF=$LIVE/arch/arm64/configs/sunfish_defconfig
|
||||
if grep -qE "^CONFIG_KSU.*=y" "$DEF"; then
|
||||
echo "FAIL: KernelSU in defconfig" >&2
|
||||
@@ -77,6 +121,12 @@ for k in FORTIFY_SOURCE INIT_ON_ALLOC_DEFAULT_ON INIT_ON_FREE_DEFAULT_ON \
|
||||
SECURITY_YAMA SLAB_FREELIST_RANDOM; do
|
||||
grep -q "^CONFIG_${k}=y" "$DEF" || { echo "FAIL missing $k" >&2; exit 1; }
|
||||
done
|
||||
grep -q '^# CONFIG_USERFAULTFD is not set$' "$DEF" \
|
||||
|| { echo "FAIL: USERFAULTFD still enabled (GOLDEN leaves it unset)" >&2; exit 1; }
|
||||
if grep -q '^CONFIG_USERFAULTFD=y$' "$DEF"; then
|
||||
echo "FAIL: CONFIG_USERFAULTFD=y" >&2
|
||||
exit 1
|
||||
fi
|
||||
grep -q "ret = __underlying_strlen(q);" "$LIVE/include/linux/string.h"
|
||||
grep -q "mmget_still_valid" "$LIVE/mm/madvise.c"
|
||||
echo "OK: Stage1+combo4+FORTIFY + CVE-clean + hi-batch1+2+3 markers present"
|
||||
@@ -85,13 +135,62 @@ rm -f out/target/product/sunfish/obj/KERNEL_OBJ/arch/arm64/boot/Image.lz4 \
|
||||
out/target/product/sunfish/obj/KERNEL_OBJ/arch/arm64/boot/Image \
|
||||
out/target/product/sunfish/kernel
|
||||
|
||||
python3 vendor/sunfish-a16/patches/008-call-rec-flag-secure/apply_wms_disable_secure_debuggable_gate.py
|
||||
python3 vendor/sunfish-a16/patches/005-sigspoof/apply_005_sigspoof.py
|
||||
python3 vendor/sunfish-a16/patches/008-call-rec-flag-secure/apply_008_call_rec_flag_secure.py
|
||||
grep -q 'SUNFISH_A16_008_CALL_REC_FLAG_SECURE' \
|
||||
frameworks/base/core/java/android/provider/Settings.java
|
||||
grep -q 'extendrom_call_recording' \
|
||||
packages/apps/Dialer/java/com/android/incallui/call/CallRecorder.java
|
||||
grep -q 'extendrom_call_recording' \
|
||||
packages/apps/Settings/res/xml/development_settings.xml
|
||||
python3 vendor/sunfish-a16/patches/009-axp-los23-port/apply_009_disable_user_apps.py
|
||||
python3 vendor/sunfish-a16/patches/009-axp-los23-port/apply_009_private_dns_providers.py
|
||||
python3 vendor/sunfish-a16/patches/009-axp-los23-port/apply_009_connectivity_check.py
|
||||
python3 vendor/sunfish-a16/patches/009-axp-los23-port/apply_009_unofficial_build_id.py
|
||||
python3 vendor/sunfish-a16/patches/009-axp-los23-port/apply_009_supl_privacy.py
|
||||
python3 vendor/sunfish-a16/patches/009-axp-los23-port/apply_009_axp_identity.py
|
||||
grep -q '^VENDOR_SECURITY_PATCH = 2023-09-05$' device/google/sunfish/device-common.mk
|
||||
python3 vendor/sunfish-a16/patches/009-axp-los23-port/apply_009_yama_ptrace.py
|
||||
python3 vendor/sunfish-a16/patches/009-axp-los23-port/apply_009_cmdline_mode.py
|
||||
grep -q 'CHECKCALL(chmod("/proc/cmdline", 0440));' \
|
||||
system/core/init/first_stage_init.cpp
|
||||
python3 vendor/sunfish-a16/patches/009-axp-los23-port/apply_009_a15_small.py
|
||||
python3 vendor/sunfish-a16/patches/009-axp-los23-port/apply_009_a15_reboot_timeouts.py
|
||||
python3 vendor/sunfish-a16/patches/009-axp-los23-port/apply_009_a15_settings_timeouts.py
|
||||
grep -q 'settings_reboot_after_timeout' \
|
||||
frameworks/base/core/java/android/provider/Settings.java
|
||||
grep -q 'isAllowedWhenLocked' \
|
||||
frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
|
||||
grep -q 'auto_reboot' packages/apps/Settings/res/xml/security_dashboard_settings.xml
|
||||
grep -q 'bluetooth_timeout' packages/apps/Settings/res/xml/connected_devices.xml
|
||||
grep -q 'wifi_timeout' packages/apps/Settings/res/xml/wifi_configure_settings.xml
|
||||
grep -q 'MAX_FAILED_ATTEMPTS_LOCKOUT_PERMANENT = 5;' \
|
||||
frameworks/base/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/LockoutFrameworkImpl.java
|
||||
grep -q 'final String buildSerial = Build.UNKNOWN;' \
|
||||
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
|
||||
grep -q 'AXP/Calyx 0042' \
|
||||
frameworks/base/packages/SystemUI/src/com/android/systemui/screenshot/ImageExporter.java
|
||||
grep -q 'Serial number constraint not permitted' \
|
||||
bootable/recovery/install/install.cpp
|
||||
# openeuicc-deps 5402167 was generated against SDK 37. LOS 23.2 ships
|
||||
# prebuilts/sdk/37 without public/android.jar, so compile these prebuilt
|
||||
# libraries against 36 (Android 16).
|
||||
sed -i 's/^ sdk_version: "37",$/ sdk_version: "36",/' prebuilts/openeuicc-deps/Android.bp
|
||||
if grep -q 'sdk_version: "37"' prebuilts/openeuicc-deps/Android.bp; then
|
||||
echo "FAIL: openeuicc-deps still asks for SDK 37" >&2
|
||||
exit 1
|
||||
fi
|
||||
python3 vendor/sunfish-a16/patches/009-axp-los23-port/apply_009_drop_openssh_packages.py
|
||||
python3 vendor/sunfish-a16/patches/009-axp-los23-port/apply_009_drop_jelly_gallery2.py
|
||||
python3 vendor/sunfish-a16/patches/009-axp-los23-port/apply_009_drop_euicc_google.py
|
||||
python3 vendor/sunfish-a16/patches/009-axp-los23-port/apply_009_drop_carrier_google.py
|
||||
python3 vendor/sunfish-a16/patches/009-axp-los23-port/apply_009_drop_lineage_tools.py
|
||||
# Wave 4 (diag/bpftool/imsrcsd): only when AXP_DEBLOB_WAVE4=1 (see 009-bacon-wave4-deblob.sh).
|
||||
AXP_DEBLOB_WAVE4="${AXP_DEBLOB_WAVE4:-0}"
|
||||
if [[ "$AXP_DEBLOB_WAVE4" == 1 ]]; then
|
||||
python3 vendor/sunfish-a16/patches/009-axp-los23-port/apply_009_drop_lab_only_commands.py
|
||||
fi
|
||||
# Jelly stays (owner 2026-10-07). Gallery is FossifyGallery. Do not re-add
|
||||
# Gallery2. The product gate requires Jelly.apk and FossifyGallery, and
|
||||
# fails if Gallery2.apk is present.
|
||||
|
||||
# Host prebuilts → vendor/sunfish-a16/prebuilt (rsync --delete must not wipe these).
|
||||
mkdir -p vendor/sunfish-a16/prebuilt
|
||||
@@ -110,7 +209,7 @@ link_prebuilt FossifyGallery.apk /srv/rom/prebuilts/axp-apps/FossifyGallery.apk
|
||||
AAPT=/srv/rom/src/lineage/prebuilts/sdk/tools/linux/bin/aapt
|
||||
"$AAPT" dump permissions vendor/sunfish-a16/prebuilt/Phonesky.apk 2>/dev/null | grep -q USE_EXACT_ALARM
|
||||
|
||||
# Early hook so LINEAGE_VERSION includes AXP-Resurection-Pro (before version.mk).
|
||||
# Early hook before version.mk (identity itself is apply_009_axp_identity.py).
|
||||
mkdir -p vendor/extra
|
||||
ln -sfn ../sunfish-a16/extra-product.mk vendor/extra/product.mk
|
||||
test -f vendor/extra/product.mk
|
||||
@@ -132,15 +231,27 @@ set +u
|
||||
# shellcheck disable=SC1091
|
||||
source build/envsetup.sh
|
||||
set -e
|
||||
# re-export after envsetup (some trees clear it)
|
||||
export PRODUCT_DEFAULT_DEV_CERTIFICATE="$CERT_DIR/releasekey"
|
||||
breakfast sunfish userdebug
|
||||
# re-export after envsetup (some trees clear it). signing.mk sets the same path.
|
||||
export PRODUCT_DEFAULT_DEV_CERTIFICATE=vendor/lineage-priv/keys/releasekey
|
||||
breakfast sunfish user
|
||||
test "${TARGET_RELEASE:-}" = "bp4a"
|
||||
BT_SEPOL=$(get_build_var MAINLINE_BLUETOOTH_SEPOLICY_DEV_CERTIFICATES)
|
||||
echo "MAINLINE_BLUETOOTH_SEPOLICY_DEV_CERTIFICATES=$BT_SEPOL"
|
||||
case "$BT_SEPOL" in
|
||||
*vendor/sunfish-a16/certs*) ;;
|
||||
*) echo "FAIL: BT sepolicy certs still AOSP default ($BT_SEPOL)" >&2; exit 1 ;;
|
||||
*vendor/lineage-priv/keys*) ;;
|
||||
*) echo "FAIL: BT sepolicy certs not vendor/lineage-priv/keys ($BT_SEPOL)" >&2; exit 1 ;;
|
||||
esac
|
||||
SYS_CERT=$(get_build_var DEFAULT_SYSTEM_DEV_CERTIFICATE)
|
||||
B_TYPE=$(get_build_var LINEAGE_BUILDTYPE)
|
||||
L_VER=$(get_build_var LINEAGE_VERSION)
|
||||
echo "DEFAULT_SYSTEM_DEV_CERTIFICATE=$SYS_CERT LINEAGE_BUILDTYPE=$B_TYPE LINEAGE_VERSION=$L_VER"
|
||||
case "$SYS_CERT" in
|
||||
vendor/lineage-priv/keys/releasekey) ;;
|
||||
*) echo "FAIL: system cert $SYS_CERT would tag dev-keys" >&2; exit 1 ;;
|
||||
esac
|
||||
[[ "$B_TYPE" == "PRO" ]] || { echo "FAIL: LINEAGE_BUILDTYPE=$B_TYPE (want PRO)" >&2; exit 1; }
|
||||
case "$L_VER" in
|
||||
*UNOFFICIAL*) echo "FAIL: version still UNOFFICIAL ($L_VER)" >&2; exit 1 ;;
|
||||
esac
|
||||
AVB_KEY=$(get_build_var BOARD_AVB_KEY_PATH)
|
||||
AVB_ALG=$(get_build_var BOARD_AVB_ALGORITHM)
|
||||
@@ -192,18 +303,18 @@ for f in vendor.img product.img system.img system_ext.img; do
|
||||
done
|
||||
# Keep make OUT boot for forensics only (often stock / non-Magisk).
|
||||
cp -v "$PROD/boot.img" "$DEST/boot-make-out.img" 2>/dev/null || true
|
||||
cp -v "$PROD"/lineage-*-UNOFFICIAL*.zip "$DEST/" 2>/dev/null || \
|
||||
cp -v "$PROD"/lineage-*-PRO-sunfish.zip "$DEST/" 2>/dev/null || \
|
||||
cp -v "$PROD"/lineage-*.zip "$DEST/" 2>/dev/null || true
|
||||
|
||||
# Publish AXP Resurection Pro ship name (hardlink/copy). Lineage bacon.mk still
|
||||
# emits lineage-*.zip; do not rebuild solely to rename.
|
||||
ZIP_LINEAGE=$(ls "$DEST"/lineage-*.zip 2>/dev/null | head -1 || true)
|
||||
if [[ -n "${ZIP_LINEAGE:-}" ]]; then
|
||||
# lineage-23.2-YYYYMMDD-UNOFFICIAL[-AXP-Resurection[-Pro]]-sunfish.zip
|
||||
# lineage-23.2-YYYYMMDD-PRO-sunfish.zip
|
||||
# → AXP-Resurection-Pro-23.2-YYYYMMDD-sunfish.zip
|
||||
ZIP_BASE=$(basename "$ZIP_LINEAGE")
|
||||
ZIP_AXP=$(echo "$ZIP_BASE" | sed -E \
|
||||
's/^lineage-([0-9]+\.[0-9]+)-([0-9]{8})(-[0-9]{6})?-UNOFFICIAL(-AXP-Resurection(-Pro)?)?-sunfish\.zip$/AXP-Resurection-Pro-\1-\2\3-sunfish.zip/')
|
||||
's/^lineage-([0-9]+\.[0-9]+)-([0-9]{8})(_[0-9]{6})?-PRO-sunfish\.zip$/AXP-Resurection-Pro-\1-\2\3-sunfish.zip/')
|
||||
if [[ "$ZIP_AXP" == "$ZIP_BASE" ]]; then
|
||||
ZIP_AXP="AXP-Resurection-Pro-${ZIP_BASE#lineage-}"
|
||||
fi
|
||||
@@ -243,7 +354,20 @@ rm -rf "$MB_TMP"
|
||||
[[ "$MB_EC" -ne 0 ]] || { echo "FAIL: ship boot is stock (magiskboot cpio test=$MB_EC); expected Magisk" >&2; exit 1; }
|
||||
echo "magiskboot_cpio_test=$MB_EC (non-zero => Magisk present)"
|
||||
|
||||
ZIP=$(ls "$DEST"/lineage-*-UNOFFICIAL*.zip 2>/dev/null | head -1 || true)
|
||||
for bp in "$PROD/system/build.prop" "$PROD/product/etc/build.prop"; do
|
||||
[[ -f "$bp" ]] || continue
|
||||
if grep -q '^ro\.[a-z.]*build\.tags=' "$bp" && ! grep -q '^ro\.[a-z.]*build\.tags=release-keys$' "$bp"; then
|
||||
echo "FAIL: $bp build.tags is not release-keys" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
grep -q '^ro.lineage.releasetype=PRO$' "$PROD/product/etc/build.prop" || {
|
||||
echo "FAIL: ro.lineage.releasetype is not PRO" >&2
|
||||
exit 1
|
||||
}
|
||||
echo "identity OK (release-keys, ro.lineage.releasetype=PRO)"
|
||||
|
||||
ZIP=$(ls "$DEST"/lineage-*.zip 2>/dev/null | head -1 || true)
|
||||
if [[ -n "$ZIP" ]]; then
|
||||
unzip -p "$ZIP" META-INF/com/android/otacert 2>/dev/null | openssl x509 -noout -subject 2>/dev/null \
|
||||
| tee "$DEST/otacert-subject.txt" || true
|
||||
@@ -272,7 +396,7 @@ FLAGS=$(awk '/^Flags:/{print $2; exit}' "$DEST/vbmeta-info.txt")
|
||||
echo "avb_pubkey_sha1 artifact=$GOT project=$EXP flags=$FLAGS"
|
||||
[[ -n "$GOT" ]] || { echo "FAIL: could not parse vbmeta public key sha1" >&2; exit 1; }
|
||||
[[ "$GOT" == "$EXP" ]] || { echo "FAIL: vbmeta pubkey != project avb_pkmd.bin" >&2; exit 1; }
|
||||
[[ "$FLAGS" == "3" ]] || { echo "FAIL: expected vbmeta Flags 3 (Magisk track), got '$FLAGS'" >&2; exit 1; }
|
||||
[[ "$FLAGS" == "$AXP_AVB_FLAGS" ]] || { echo "FAIL: expected vbmeta Flags $AXP_AVB_FLAGS, got '$FLAGS'" >&2; exit 1; }
|
||||
|
||||
# Cryptographic check against TF sibling images in $DEST (hardlinked/copied).
|
||||
# Magisk boot footer is Algorithm NONE — chain trust is top-level vbmeta + project key.
|
||||
@@ -329,17 +453,78 @@ if ! debugfs -R "stat /etc/init/init.openssh.rc" "$PROD_RAW" 2>&1 | grep -q 'Ino
|
||||
fi
|
||||
echo "US-S4-1 product surface OK (no ssh/rsync bins; init.openssh.rc present)"
|
||||
|
||||
# US-S4-2 — AXP PRO: no Jelly / Gallery2 *apps* on product (Fossify stays).
|
||||
# Note: LOCAL_OVERRIDES removes Gallery2.apk but stale JNI symlink dirs under
|
||||
# product/app/Gallery2/lib can remain from older out/ — gate on the APK.
|
||||
for p in /app/Jelly/Jelly.apk /app/Gallery2/Gallery2.apk; do
|
||||
if debugfs -R "stat $p" "$PROD_RAW" 2>&1 | grep -q 'Inode:'; then
|
||||
rm -f "$PROD_RAW"
|
||||
echo "FAIL: US-S4-2 expected absent $p on product.img" >&2
|
||||
# Lineage tools absent on GOLDEN. curl and vim stay.
|
||||
SYS_RAW=$(mktemp /tmp/axp-system-XXXX.img)
|
||||
SYSEXT_RAW=$(mktemp /tmp/axp-systemext-XXXX.img)
|
||||
"$SIMG" "$DEST/system.img" "$SYS_RAW"
|
||||
"$SIMG" "$DEST/system_ext.img" "$SYSEXT_RAW"
|
||||
if debugfs -R "stat /addon.d/50-lineage.sh" "$SYS_RAW" 2>&1 | grep -q 'Inode:'; then
|
||||
rm -f "$PROD_RAW" "$SYS_RAW" "$SYSEXT_RAW"
|
||||
echo "FAIL: expected system/addon.d/50-lineage.sh absent" >&2
|
||||
exit 1
|
||||
fi
|
||||
if ! debugfs -R "stat /bin/curl" "$SYS_RAW" 2>&1 | grep -q 'Inode:'; then
|
||||
rm -f "$PROD_RAW" "$SYS_RAW" "$SYSEXT_RAW"
|
||||
echo "FAIL: expected system/bin/curl present" >&2
|
||||
exit 1
|
||||
fi
|
||||
for p in /bin/bash /bin/htop /bin/nano /bin/unrar; do
|
||||
if debugfs -R "stat $p" "$SYSEXT_RAW" 2>&1 | grep -q 'Inode:'; then
|
||||
rm -f "$PROD_RAW" "$SYS_RAW" "$SYSEXT_RAW"
|
||||
echo "FAIL: expected system_ext$p absent" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
# Directory-only Gallery2 leftover (jni symlinks) is not a shipped app — warn.
|
||||
if [[ "$AXP_DEBLOB_WAVE4" == 1 ]]; then
|
||||
for p in /bin/bpftool /bin/alloctop /bin/pbtombstone /bin/apexd-lsof.sh; do
|
||||
if debugfs -R "stat $p" "$SYS_RAW" 2>&1 | grep -q 'Inode:'; then
|
||||
rm -f "$PROD_RAW" "$SYS_RAW" "$SYSEXT_RAW"
|
||||
echo "FAIL: expected system$p absent" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if ! debugfs -R "stat /bin/vim" "$SYSEXT_RAW" 2>&1 | grep -q 'Inode:'; then
|
||||
rm -f "$PROD_RAW" "$SYS_RAW" "$SYSEXT_RAW"
|
||||
echo "FAIL: expected system_ext/bin/vim present" >&2
|
||||
exit 1
|
||||
fi
|
||||
rm -f "$SYS_RAW" "$SYSEXT_RAW"
|
||||
echo "lineage tools surface OK (no bash/htop/nano/unrar/addon.d; curl+vim kept)"
|
||||
if [[ "$AXP_DEBLOB_WAVE4" == 1 ]]; then
|
||||
VENDOR_RAW=$(mktemp /tmp/axp-vendor-XXXX.img)
|
||||
"$SIMG" "$DEST/vendor.img" "$VENDOR_RAW"
|
||||
for p in /bin/cnss_diag /bin/diag_klog /bin/diag_mdlog /bin/diag_socket_log /bin/diag_uart_log /bin/ssr_diag /bin/test_diag /bin/imsrcsd /bin/disable_configstore /etc/init/imsrcsd.rc; do
|
||||
if debugfs -R "stat $p" "$VENDOR_RAW" 2>&1 | grep -q 'Inode:'; then
|
||||
rm -f "$PROD_RAW" "$VENDOR_RAW"
|
||||
echo "FAIL: expected vendor$p absent" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
for p in /bin/loc_launcher /bin/lowi-server /bin/xtra-daemon; do
|
||||
if ! debugfs -R "stat $p" "$VENDOR_RAW" 2>&1 | grep -q 'Inode:'; then
|
||||
rm -f "$PROD_RAW" "$VENDOR_RAW"
|
||||
echo "FAIL: expected vendor$p present" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
rm -f "$VENDOR_RAW"
|
||||
echo "lab-only commands surface OK (diag/imsrcsd/debug tools gone; GPS daemons kept)"
|
||||
fi
|
||||
|
||||
# US-S4-2 — Jelly stays. FossifyGallery stays; Gallery2 does not.
|
||||
# Stale JNI symlink dirs under product/app/Gallery2/lib can remain from
|
||||
# older out/ — gate Gallery2 on the APK.
|
||||
if ! debugfs -R "stat /app/Jelly/Jelly.apk" "$PROD_RAW" 2>&1 | grep -q 'Inode:'; then
|
||||
rm -f "$PROD_RAW"
|
||||
echo "FAIL: US-S4-2 expected Jelly.apk on product.img" >&2
|
||||
exit 1
|
||||
fi
|
||||
if debugfs -R "stat /app/Gallery2/Gallery2.apk" "$PROD_RAW" 2>&1 | grep -q 'Inode:'; then
|
||||
rm -f "$PROD_RAW"
|
||||
echo "FAIL: US-S4-2 expected Gallery2.apk absent on product.img" >&2
|
||||
exit 1
|
||||
fi
|
||||
if debugfs -R "stat /app/Gallery2" "$PROD_RAW" 2>&1 | grep -q 'Inode:'; then
|
||||
echo "WARN: US-S4-2 /app/Gallery2 dir still present (likely stale jni symlinks; no APK)"
|
||||
fi
|
||||
@@ -349,20 +534,27 @@ if ! debugfs -R "stat /app/FossifyGallery" "$PROD_RAW" 2>&1 | grep -q 'Inode:';
|
||||
exit 1
|
||||
fi
|
||||
rm -f "$PROD_RAW"
|
||||
echo "US-S4-2 product surface OK (no Jelly/Gallery2 APK; FossifyGallery present)"
|
||||
echo "US-S4-2 product surface OK (Jelly + FossifyGallery; no Gallery2 APK)"
|
||||
|
||||
{
|
||||
echo "artifact=$DEST"
|
||||
echo "list_clean=$LIST_CLEAN (429)"
|
||||
echo "list_hi=batch1+2+3"
|
||||
echo "hardening=Stage1+combo4+FORTIFY + CVE-clean + hi-batch1+2+3 + US-S4-1-no-openssh + US-S4-2-no-jelly-gallery2 + US-S5-1-yama-slabrand"
|
||||
echo "kernel_stage1=30 (misc/0021 omitted; base KSYM_NAME_LEN=192 retained)"
|
||||
echo "hardening=Stage1+combo4+FORTIFY + CVE-clean + hi-batch1+2+3 + US-S4-1-no-openssh + US-S4-2-jelly-fossify + US-S5-1-yama-slabrand + CVE-2022-49980-lock-scope"
|
||||
echo "vendor_security_patch=2023-09-05"
|
||||
echo "branding=AXP-Resurection-Pro"
|
||||
echo "signing=$PRODUCT_DEFAULT_DEV_CERTIFICATE"
|
||||
echo "avb_infra=$AVB_KEY alg=$AVB_ALG flags=3 (HASHTREE_DISABLED|VERIFICATION_DISABLED)"
|
||||
echo "avb_infra=$AVB_KEY alg=$AVB_ALG flags=$AXP_AVB_FLAGS"
|
||||
echo "avb_runtime_enforce=no (unlocked Magisk track; not AVB-hardened boot)"
|
||||
echo "avb_pubkey_sha1=$GOT"
|
||||
echo "magiskboot_cpio_test=$MB_EC"
|
||||
echo "ship_images=target_files/IMAGES (not OUT make images)"
|
||||
if [[ "$AXP_DEBLOB_WAVE4" == 1 ]]; then
|
||||
echo "deblob=wave1-euicc-google+wave2-carrier-google-and-aosp-rcs+wave3-lineage-tools+wave4-lab-only-commands"
|
||||
else
|
||||
echo "deblob=wave1-euicc-google+wave2-carrier-google-and-aosp-rcs+wave3-lineage-tools"
|
||||
fi
|
||||
echo "ship_zip_brand=AXP-Resurection-Pro-*-sunfish.zip (sibling of lineage-*.zip; not slim)"
|
||||
echo "flash=sideload AXP-Resurection-Pro zip (or lineage twin); boot-only insufficient"
|
||||
echo "recover=20261002T085915Z-axp-stage1-combo4-cve-hi-releasekeys"
|
||||
@@ -375,6 +567,20 @@ echo "US-S4-2 product surface OK (no Jelly/Gallery2 APK; FossifyGallery present)
|
||||
lineage-*.zip AXP-Resurection-Pro-*.zip 2>/dev/null || true) \
|
||||
| tee "$DEST/SHA256SUMS"
|
||||
|
||||
# AXP publishes a hash file next to the zip and a detached signature of that
|
||||
# file. Sign only when this user already has a secret key.
|
||||
shopt -s nullglob
|
||||
for pro in "$DEST"/AXP-Resurection-Pro-*.zip; do
|
||||
(cd "$DEST" && sha512sum "$(basename "$pro")") | tee "$pro.sha512sum"
|
||||
if gpg --batch --list-secret-keys 2>/dev/null | grep -q '^sec'; then
|
||||
gpg --batch --yes --detach-sign --armor -o "$pro.sha512sum.asc" "$pro.sha512sum" \
|
||||
|| echo "WARN: gpg detach-sign failed for $pro.sha512sum"
|
||||
else
|
||||
echo "SKIP: no GPG secret key; left $pro.sha512sum unsigned"
|
||||
fi
|
||||
done
|
||||
shopt -u nullglob
|
||||
|
||||
echo "FLASH_READY $DEST"
|
||||
echo "=== DONE $DEST $(date -Is) ==="
|
||||
exit 0
|
||||
@@ -0,0 +1,29 @@
|
||||
#!/bin/bash
|
||||
# 012 bacon: current ship pack plus Graphene hardened_malloc.
|
||||
# Compiles libc first. The full bacon runs only if that link succeeds.
|
||||
# Does not change AVB flags or run the userspace deblob.
|
||||
set -e
|
||||
cd /srv/rom/src/lineage
|
||||
export HOME=/home/android-build
|
||||
export CCACHE_DIR=/srv/rom/ccache
|
||||
export USE_CCACHE=1
|
||||
export PATH=/home/android-build/bin:/usr/local/bin:/usr/bin:/bin:$PATH
|
||||
unset OUT_DIR || true
|
||||
|
||||
python3 vendor/sunfish-a16/patches/012-hardened-malloc/apply_012_hardened_malloc.py
|
||||
grep -q 'SUNFISH_A16_012_HARDENED_MALLOC' bionic/libc/Android.bp
|
||||
grep -q 'libhardened_malloc' bionic/libc/Android.bp
|
||||
grep -q 'CONFIG_CLASS_REGION_SIZE=2147483648' external/hardened_malloc/Android.bp
|
||||
grep -A1 '__attribute__((noinline))$' bionic/libc/bionic/libc_init_dynamic.cpp | grep -q '__libc_preinit_impl'
|
||||
test -f external/hardened_malloc/h_malloc.c
|
||||
|
||||
set +u
|
||||
# shellcheck disable=SC1091
|
||||
source build/envsetup.sh
|
||||
set -e
|
||||
export PRODUCT_DEFAULT_DEV_CERTIFICATE=vendor/lineage-priv/keys/releasekey
|
||||
breakfast sunfish user
|
||||
echo "=== m libc $(date -Is) ==="
|
||||
m libc -j8
|
||||
echo "=== libc ok, starting bacon $(date -Is) ==="
|
||||
exec /srv/rom/artifacts/bin/009-bacon-axp-stage1-combo4-cve-hi-releasekeys.sh
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
# Wave 4 deblob candidate: closure pack plus diag/bpftool/imsrcsd drops.
|
||||
# Same AVB flags-0 track as the booted closure baseline. Do not flash until
|
||||
# checked. LAB only. Do not run while another ninja owns out/.
|
||||
set -euo pipefail
|
||||
export AXP_AVB_FLAGS=0
|
||||
export WITH_AVB=true
|
||||
export AXP_DEBLOB_WAVE4=1
|
||||
exec "$(dirname "$0")/009-bacon-axp-stage1-combo4-cve-hi-releasekeys.sh"
|
||||
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Read only Swissquote's RASP exception classification; never dump reports.
|
||||
|
||||
Requires an already authorized adb shell su. Does not launch, stop, modify,
|
||||
instrument, or grant root to Swissquote. Raw report data stays in memory.
|
||||
APK/report/session identifiers and other application data are not emitted.
|
||||
"""
|
||||
import argparse
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
|
||||
def classifications(value):
|
||||
if isinstance(value, dict):
|
||||
exception = value.get("exception")
|
||||
if isinstance(exception, dict):
|
||||
reason = exception.get("reason", "")
|
||||
if (exception.get("type") == "com.swissquote.android.FreeRaspException"
|
||||
and isinstance(reason, str) and reason.startswith("freeRASP: on")):
|
||||
yield reason
|
||||
for child in value.values():
|
||||
yield from classifications(child)
|
||||
elif isinstance(value, list):
|
||||
for child in value:
|
||||
yield from classifications(child)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--device", required=True, choices=["LAB", "GOLDEN"])
|
||||
args = parser.parse_args()
|
||||
serial = {"LAB": "11231JEC207477", "GOLDEN": "11071JEC203839"}[args.device]
|
||||
base = "/data/user/10/com.swissquote.android/files/.crashlytics.v3/com.swissquote.android"
|
||||
|
||||
def shell(command):
|
||||
return subprocess.check_output(
|
||||
["adb", "-s", serial, "shell", "su", "-c", "'" + command + "'"],
|
||||
text=True, timeout=15,
|
||||
)
|
||||
|
||||
results = []
|
||||
for path in shell("find " + base + " -maxdepth 4 -type f").splitlines():
|
||||
# Never interpolate arbitrary output into a shell command.
|
||||
if not path.startswith(base + "/") or any(c not in
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/._:-" for c in path):
|
||||
continue
|
||||
if not any(part in path for part in ("/event", "/reports/", "/priority-reports/")):
|
||||
continue
|
||||
size = shell("stat -c %s " + path).strip()
|
||||
if not size.isdigit() or int(size) > 4 * 1024 * 1024:
|
||||
continue
|
||||
try:
|
||||
value = json.loads(shell("cat " + path))
|
||||
except json.JSONDecodeError:
|
||||
continue
|
||||
results.extend(classifications(value))
|
||||
print(json.dumps({"device": args.device, "profile": 10,
|
||||
"rasp_exceptions": results,
|
||||
"note": "Retained events only; absence is not proof of PASS."}, indent=2))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in new issue
Block a user