Public version. This is a redacted copy of an internal document. Device identifiers, the carrier's identity, the regional sales code, the exact verified-boot byte, and the owner's account names have been removed. See "What is deliberately not in this document" at the end. Nothing here is legal advice, and no binaries are distributed.
I worked with Claude Opus 5 to get Android 17 running on the Samsung Galaxy A53. Samsung stopped at Android 16 for that model phone. This is the output of a week of sessions with AI to get the phone running and major features working. I have a SIM for Tello which operates on the T-Mobile network which I used for testing.
The answer to "if I wanted to get AOSP 17 running on this phone, what is stock, what did we write, and what came from somebody else?"
Four origins throughout:
| Origin | Means |
|---|---|
| AOSP | Google's, unmodified |
| Samsung | the stock SM-A536E firmware A536EXXSBEXI4, unmodified |
| Third party | somebody else in the Android community, named, unmodified |
| Ours | written or modified here, with what changed and why |
One firmware, two Android versions. A536EXXSBEXI4's system partition is Android 14
(UP1A.231005.007, SDK 34) and its vendor partition is Android 12
(SP1A.210812.016, API level 31), because Samsung never moved vendor off the device's launch
version. The ported IMS files come from the Android 14 system side; the untouched HALs are the
Android 12 vendor side. Corrected 2026-09-14: several notes in this project had called the
whole firmware "Android 12".
The short version: nothing about the phone's hardware support was written here. The kernel, the recovery and every vendor blob come from Samsung or from one community kernel maintainer. What was written here is three byte patches that let Google's GSI boot on Samsung's vendor, a dex-level port of Samsung's IMS stack so voice calling works, and the instruments that found out what to patch.
Every version and date below was read off the device or the staged files on 2026-09-14, not recalled from a session note.
The bootloader checks a signature chain before it runs anything. vbmeta is the root of that
chain: it holds the hashes of boot, dtbo, vendor and system, and if any one fails the device
refuses to boot. Nothing custom can run until this is relaxed.
| Component | Origin | Version / date | Detail | Why |
|---|---|---|---|---|
BL_A536EXXSBEXI4 stock firmware |
Samsung | A536EXXSBEXI4 (regional CSC omitted), built 2024-09-11, patch 2024-09-01 |
Pulled with samloader from Samsung's FUS SOAP endpoint. Source of the pristine vbmeta.img |
Needed as the baseline to patch. Also the only usable copy: the newer A536EXXSOGZH2 (2026-08) would move the phone to One UI 8 and destroy the unlock |
vbmeta-patched.img |
Ours, one byte in a public, documented field | patched 2026-09-11 | The AVB flags field is set to disable verification and the hashtree. Done with the public upstream tool's own logic; the exact offset and value are deliberately not reproduced here, see that tool | AVB rejects an unsigned recovery outright, so TWRP will not boot without it. The bootloader cannot be re-locked with our own keys on this device, so disabling is the only route |
vbmeta-disable-verification |
Third party: WessellUrdata | v1.0.4 | The tool TWRP's maintainer links to. We reimplemented its single-byte write locally | Running a third-party binary to flip one known byte adds a trust dependency for nothing. Reimplementing makes the change auditable |
Recovery is a second, self-contained Linux that boots instead of Android. It is the only
environment that can mount and write /system, because a booted Android refuses the write
even with root and an rw mount.
| Component | Origin | Version / date | Detail | Why |
|---|---|---|---|---|
| TWRP a53x unofficial | Third party: Flopster101 | 3.7.1_12-100526-2342, 2026-05-11 |
Used as downloaded. Embeds FloppyKernel v6.3.1 internally, which is irrelevant: it boots recovery from RECOVERY, never Android |
Every /system edit in this project goes through it. Re-confirmed 2026-09-14: writes to /system/etc/selinux/ are Permission denied from a booted system, so installing the enforcing policy needed a TWRP trip |
multidisabler |
Third party: ianmacd | v3.0, December 2020 | Staged, deliberately never flashed. Its jobs are covered by the patched vbmeta plus TWRP's own Format Data |
Its own maintainer removed it from the device tree on 2026-05-10 with "It is highly discouraged to use this nowadays", and grepping the staged recovery image finds zero occurrences of the string. Flashing it reflexively would be cargo cult |
The kernel from BOOT/VENDOR_BOOT brings up the SoC, drivers and the audio DSP, then
starts init. Samsung's stock kernel will not load an unsigned GSI's modules, so a community
kernel is required.
| Component | Origin | Version / date | Detail | Why |
|---|---|---|---|---|
| FloppyKernel exynos1280 | Third party: Flopster101 / FlopKernel-Series | v6.3.3, 2026-07-21, base Samsung's GPL s5e8825 source at 5.10.266, not mainline |
Four variants that differ only by the root implementation compiled in (KSUNext-SUSFS, ReSukiSU-SUSFS, XXKSU, Vanilla). Its substantive work is Panfrost, the open-source Mali driver ported onto Exynos with DRM/DPU, GPEX DVFS and thermal integration, plus an ntfsplus NTFS driver backported to 5.10, SUSFS at source level (fs/susfs.c), defconfig changes, and stable backports. Running: 5.10.266-Floppy-v6.3.3-KN-g7f807cc9c432 |
A GSI needs a kernel that permits unsigned modules and an unlocked boot. The version string embeds the commit, so which build is running is never ambiguous, and camera modules refuse to load on a vermagic mismatch, meaning a working camera also proves they came from the same build |
| EFS cal-size-0 patch | Ours, compiled from source | a personal fork of the kernel, patch commit 7062bcd "camera: mcd_v2: do not fail EFS handoff when a cal block is absent"; the running build is 7f807cc, a descendant of it. 6 commits of ours in total: the EFS patch, FTRACE_SYSCALLS for debugging, persistent ccache, a CI workflow fix, and two ramoops DTS commits (the second reverting no-map, which bootlooped) |
Built in the project's own GitHub Actions. Warm run ~13 min, cold ~33 | The kernel rejected a zero-sized camera calibration block, which no userspace change can work around. Built in CI because every toolchain option in kernel_build/scripts/tc.sh is an x86_64 Linux prebuilt, and qemu on an arm64 Mac turns a 20 minute build into hours. The only change of ours that is compiled rather than patched into a binary |
The system image is the OS: init, the SELinux policy, the framework, the apps. On this
Treble device it is a Generic System Image, meaning Google's stock AOSP build running
unmodified on Samsung's vendor partition.
| Component | Origin | Version / date | Detail | Why |
|---|---|---|---|---|
aosp_arm64-A17 GSI |
AOSP, Google | CP2A.260605.012, incremental 15430684, built 2026-05-15, patch 2026-06-05, SDK 37 / Android 17 |
The pristine zip is kept; the system.img inside hashes c0f4a055... |
This is the whole objective: stock Android 17 with no vendor modifications |
| LineageOS 23.2 GSI | Third party: MisterZtr build of LineageOS | 23.2-20260524-VANILLA-EXT4, 2026-05-24 |
The Android 16 baseline the A17 work is compared against | A known-good reference was needed: baseline-a16.md is what any A17 regression is measured against |
/efs in the image root |
Ours | first written 2026-09-12, corrected 2026-09-14 | Written offline with debugfs, labelled u:object_r:rootfs:s0. On A17 it must be a real directory, not a symlink |
Samsung's camera HAL and RIL read calibration and IMEI data from /efs, a path One UI has and AOSP does not. Without it the camera logs "failed to load awb" and, on A17, the radio dies outright |
plat_sepolicy.cil, 1 byte |
Ours | 2026-09-13 | ( -> ; turns a colliding genfscon line into a CIL comment |
Newer Google GSIs declare a genfscon that collides with Samsung's vendor policy and init aborts the policy compile. No boot at all without it, and it is one byte. gsi-sepolicy-collision.md |
ueventd.rc, 29 bytes |
Ours | 2026-09-13 | import /vendor/etc/ueventd.rc -> import /vendor/ueventd.rc + 4 spaces, length preserved so no ext4 metadata moves |
This is the regression that blocked Android 17 on this device. A17's ueventd imports a path Samsung's Android 12 vendor does not have, so device nodes are never created and the TEE never comes up. Found with a chroot bench at 8 s per arm. a17-blocker2-tee.md |
system-a17-min.img |
Ours = AOSP + those 3 edits | 2026-09-13, sha256 withheld | 3,221,225,472 bytes. Boots Enforcing with zero permissive=1 denials |
The keeper. All diagnostic scaffolding was removed and it still boots, which is what proves the three edits are the complete set. Three size-preserving byte patches and no new code is the entire cost of running stock AOSP 17 here |
system-a17-volte.img |
Ours = -min + the port |
2026-09-14, sha256 withheld | 38 files, 2 directories, sepolicy append. All 38 verified byte-identical to the running phone, all 40 paths verified for mode and SELinux label, e2fsck -fn clean |
The port lives entirely in /system, so a reflash wipes it. Baked in, a reflash carries voice with it. Not yet booted, which is the one claim here that is still inspection-only |
The vendor partition is Samsung's hardware support: camera, audio, graphics, and the RIL that talks to the modem. Treble's promise is that it stays untouched while the system side is replaced.
| Component | Origin | Version / date | Detail | Why |
|---|---|---|---|---|
All of /vendor, every HAL |
Samsung, untouched | SP1A.210812.016, Android 12 / API level 31, built 2024-09-11 KST, patch 2024-09-01 |
Samsung never moved vendor off the launch version even though the system side went to Android 14 | This is the point of Treble and the reason a GSI works at all. It is also why A17 reads ro.vendor.api_level=31, which makes Samsung's own IpcDispatcherFactory correctly choose the HIDL path over AIDL |
| Modem firmware | Samsung, untouched | CP27504336, baseband A536EXXSBEXI4, Samsung RIL v5.0 |
Independent of the Android version | Registration, VoLTE signalling and CP audio all terminate here. Nothing in this project can or should replace it |
libeden_osal.so, libexynoscamera3.so, media_profiles_V1_0.xml |
Samsung, 4-byte edits ours | patched 2026-09; stock md5 0bc974d5... for the first blob, patched md5s withheld |
module/BUILD.md asserts the stock md5 before patching |
eden_mem_free passed a four-byte ASCII constant (value withheld) as a munmap length, unmapping over a gigabyte including its own code page; m_transitState aborted the whole camera provider on a failed session configure, freezing the camera ~20 s; and the media profiles had no high-speed entries at all, so CameraX refused the 120 and 240fps the HAL actually delivers |
eden_munmap_guard |
Ours | v1.5, versionCode 6 | KernelSU module, bind-mounts the three patched blobs plus six Samsung permission XMLs from /data |
Vendor is read-only and reflashed as a unit, so the fixes cannot live there. A bind mount from /data survives reboots without touching the partition. The authoritative copy is in the 2026-09-13 backup, not the stale v1.0 zip in staging |
init compiles the platform, vendor and product CIL policy into one binary policy before
almost anything else runs. A malformed policy is a bootloop, and a missing domain means
init refuses to start a service at all.
| Component | Origin | Version / date | Detail | Why |
|---|---|---|---|---|
imsd CIL block |
Ours, ~116 lines | written 2026-09-14 | A domain for imsd, the init -> imsd type transition, the secims service name, /dev/socket/imsd, and the Treble-crossing rules that let a coredomain app reach Samsung's vendor RIL |
init refuses to start any service whose binary has no domain transition, and says so even in permissive mode, so a domain had to exist. Then three separate things each forced a rule: the secims binder name has no service_contexts entry so it lands on default_android_service, which system_app may not add; libsec-ims.so could not reach /dev/socket/imsd, so IPsec never came up and the authenticated REGISTER went out unprotected; and the audio path needs a vendor HIDL channel that Treble forbids a coredomain app from using, without which an answered call was torn down immediately with BYE |
(typepermissive imsd) replaced by 6 explicit rules |
Ours | made enforcing 2026-09-14 | (allow imsd self (key_socket (create read write))) and (allow imsd self (capability (net_admin))). Two directory searches left denied on purpose |
The flag was a placeholder from when nobody knew what a ported vendor daemon needed. Measured instead: with the domain permissive a clean boot gave zero denials and a full call gave exactly six. Granting those six and dropping the flag still passes 9 of 9 on the call suite. The two searches lead nowhere, nothing follows them, and granting one would also require making imsd mlstrustedsubject, since s0 does not dominate s0:c512,c768 |
secilc validation |
AOSP binary already on the device | run before every policy install | Control run on the unmodified policy first, then the candidate. Both exit 0 |
A malformed CIL is a bootloop, and the compile test costs seconds. It caught (permissive imsd) when the correct CIL keyword is typepermissive |
These start from /system/etc/init/*.rc before the framework. imsd manages the IPsec
security associations the carrier profile demands; multiclientd serves the socket Samsung's
IMS stack uses to reach the vendor RIL.
| Component | Origin | Version / date | Detail | Why |
|---|---|---|---|---|
imsd, multiclientd |
Samsung, unmodified | Android 14 A536EXXSBEXI4, UP1A.231005.007, SDK 34, 2024-09-11. imsd 28 KB |
Both labelled u:object_r:imsd_exec:s0 |
Without the label init runs them in its own domain and the type transition never fires. multiclientd was only discovered via prior art; before that we had written a 130-line relay to do its job |
imsd.rc |
Samsung, unmodified | same firmware, 183 bytes | Declares the imsd socket, NET_RAW, NET_ADMIN |
Stock and correct as shipped, so there was no reason to touch it |
multiclientd.rc |
Samsung, one line ours | 2026-09-14 | setenv LD_LIBRARY_PATH /system/lib64/hidl12 |
A17's libhidlbase routes HIDL lookups through the AIDL servicemanager, so multiclientd's ISehBridge lookup fails with "ISehBridge is disabled". Pointing it at the stock firmware's own copy restores the hwservicemanager path |
multisim-prop.rc |
Ours | 2026-09-14, 412 bytes | Sets ro.multisim.simslotcount 1 at early-init |
init logged cannot expand arguments: property 'ro.multisim.simslotcount' doesn't exist and refused to start multiclientd at all. AOSP never sets this property; One UI does |
19 libs in /system/lib64 |
Samsung, unmodified | same firmware. libsec-ims.so 9.19 MB, a reSIProcate SIP stack |
Includes android.hardware.radio@{1.0,1.1,1.2} and radio.config@1.0 |
A17 dropped those HIDL radio libraries and multiclientd failed with CANNOT LINK EXECUTABLE: android.hardware.radio@1.0.so not found. Every library was checked with tools/elfsyms.py before install: 616 undefined symbols, 0 unresolved. Nothing was installed on the hope that it would link |
hidl12/libhidlbase.so, libhwbinder.so |
Samsung, unmodified | the same Android 14 firmware's own /system copies, md5 98d72dff..., af088f8a... |
Corrected 2026-09-14: these are the Android 14 firmware's, not Android 12's. Confirmed against /vendor/lib64/libhwbinder.so, md5 abad0934..., which differs |
Used only by multiclientd. Kept in a private directory so nothing else in /system picks up an old HIDL implementation |
/system/etc/floating_feature.xml |
Samsung, copy of /vendor's |
21 KB | Placed at the /system path as well as the vendor one |
The Samsung system libraries read /system/etc/floating_feature.xml, not the vendor path, and silently fall back to default behaviour without it |
Loaded into an app's classloader at process start. uses-library entries in a manifest
resolve here, before any of the app's own code runs.
| Component | Origin | Version / date | Detail | Why |
|---|---|---|---|---|
imsmanager.jar |
Ours (composite) | assembled 2026-09-14, 51 MB, 8 dex | Samsung's classes.dex, our 8 shadow-stub classes as classes2.dex, and Samsung's six framework.jar dexes as classes3..8 |
Samsung's IMS app calls Samsung framework methods AOSP does not have. Replacing a BOOTCLASSPATH jar is not an option: such a jar ships a checksummed boot-*.vdex, so swapping it makes the runtime reject the whole container, which is what bootlooped attempt 1. Stacking the classes into a shared library jar sidesteps that, and classes2 is searched before Samsung's own copies so our stubs win for the few classes that need them |
samsung-imsmanager.xml |
Ours | 2026-09-14, 142 bytes | <library name="imsmanager" file="/system/framework/imsmanager.jar"/> |
A uses-library entry only resolves if a permission XML declares it; without this the app never starts |
vsimmanager.jar, EpdgManager.jar, rcsopenapi.jar + their 3 permission XMLs |
Samsung, unmodified | same Android 14 firmware | vsimmanager.jar is where gson lives |
The app declares all of them as uses-library. Omitting any one is a ClassNotFoundException at bind time |
Normal APKs, but these two are platform-signed and share android.uid.system, so they can
hold system permissions.
| Component | Origin | Version / date | Detail | Why |
|---|---|---|---|---|
imsservice.apk |
Samsung, modified by us | stock 9.57 MB from Android 14 A536EXXSBEXI4; patched build 9.1 MB, versionName 1.0, targetSdk 33; patched dex hash withheld |
singleUser cleared, five dex passes, re-signed with the AOSP platform testkey (c8a2e9bc...). Installed to /system/app, not priv-app |
Each patch answers one specific observed failure. singleUser on a non-system app makes PMS record the component as not exported and AMS refuse the bind. The 49 neutralised call sites are platform members A17 removed. isGbaSupported returning false makes Samsung reject the carrier's VoLTE profile outright. getAllCellInfoBySubId missing means no P-Access-Network-Info header. checkCallControl returning nothing makes every call NotAllowed. And needSkipUntilTelephonyReady postponed every inbound callback forever, because it waits on a Samsung-only API AOSP never calls, which is why a remote hangup did not disconnect the phone. priv-app is avoided because an unallowlisted privapp permission bootloops systemReady() |
CarrierConfig.apk |
AOSP, modified by us | 289 KB patched, 2026-09-14 | Adds a carrier_config_carrierid_<id>_<carrier>.xml asset plus the two matching mccmnc_* names, re-signed with the platform key |
AOSP's generic carrier config does not carry this carrier's VoLTE settings, and the Samsung stack reads them to decide whether to register at all. The added file is a superset of the stock config for that carrier |
| Aperture fork, "Camera (no-glare)" | LineageOS, forked by us | org.lineageos.aperture.dev, versionName 1.0, targetSdk 36 |
Front-camera glare removed. Gradle build from LineageOS/android_packages_apps_Aperture |
The glare is produced in the app's processing path, not the HAL, so the app is the only layer where it can be fixed |
| Component | Origin | Version / date | Detail | Why |
|---|---|---|---|---|
jameskdev/android_samsung_imsservice |
Third party: jameskdev | targets Android 11 / LineageOS 18.1, Galaxy A21s | Revealed that Samsung ships a multiclientd daemon and named six missing libraries. No code taken; the installed files are this phone's own |
Searching for prior art first was decisive and is now LESSONS 36. It also showed the hardest item in the community recipe is obsolete: that project refactors Samsung's smali onto Google's compat namespace, and Samsung has since migrated to android.telephony.ims.ImsService themselves. It did not explain the audio failure, which needed disassembly |
rilbridge.c, imspdn/ |
Ours, deleted | written and removed 2026-09-14 | A 130-line abstract-socket relay and an app holding a NET_CAPABILITY_IMS request open. Kept in tools/ for the technique only, not on the device |
Both were removed on evidence, not opinion: multiclientd already serves that socket, and the log shows Samsung requesting its own PDN (KPI[0]: PDN Setup 0.093s [Request by IMS : true]). Deleting work that turns out to be unnecessary is cheaper than maintaining it |
ro.build.type=userdebug |
Ours, reverted | 2026-09-13 | Set in two files, bootlooped the phone, recovered from .pre-userdebug backups via TWRP |
Recorded as a dead end so nobody tries it again. Paths inside the recovery mount are /mnt/sys/system/build.prop, because this is system-as-root |
None of these existed before this project. They are the reason the port is a list of known changes rather than a pile of guesses.
| Tool | Answers | Why it had to exist |
|---|---|---|
tools/dexref.py, missing_classes.py, missing_members.py |
Exactly which classes, methods and fields a ported app needs and the platform lacks | Turned "Samsung's IMS needs unknown framework additions" into 51 classes, 38 methods and 2 fields. The alternative is one ClassNotFoundException per boot |
tools/dexcode.py |
Walks and patches dex bytecode | verify parsed all 42394 methods with 0 misparses. Three earlier versions were wrong in three different ways (LESSONS 26-28), and each was caught by the tool checking itself rather than by a failing boot |
tools/dexdis.py |
Single-method disassembly with refs resolved | A call site's neighbours decide whether a patch is safe. The three hardest blockers in the port were all in code the blanket patch had already touched |
tools/elfsyms.py |
Will this Android 14 .so link against Android 17's libraries |
Answered 616 undefined, 0 unresolved before anything was installed, instead of discovering it from a boot failure |
tools/axml_patch.py |
Flips one boolean in a binary AndroidManifest.xml |
No chunk size changes, so the APK stays valid. Written specifically to clear android:singleUser, which silently unexports a component |
tools/uinode.py |
Resolves a uiautomator node to a tap point |
Driving an in-call UI by fixed coordinates does not work: the layout reflows on hold and a stale coordinate taps whatever moved into place |
tools/dex_txn.py, parcel_call.py, ipc_trace.py, dmbridge.c |
AIDL transaction ordinals, decoded reply parcels, Samsung IPC frames, the modem's diagnostic port over TCP | Transaction numbers are ordinals, so guessing one calls a different method on a live phone. The DM port is the only place the modem's own PLMN decisions are visible |
volte-build.sh, volte-install.sh, volte-bake.sh, volte-call-surface.sh |
Rebuild the port reproducibly, move all 38 files on and off a device, bake them into an image offline, prove the call surface | A sequence of shell commands in a session is the same as not existing. The build is verified byte-identical to the running phone, which is a stronger claim than "it produces something plausible" |
tee-bench.sh, gsi-boot-test.sh, a17-restore.sh, hal-casualties.py, tmo-signal.sh |
Run a vendor service inside any image from recovery at 8 s per arm, test a boot, re-apply the /data fixes, list HAL casualties, tell "no service" from "no usable signal" |
tee-bench.sh is what found the ueventd regression; tmo-signal.sh is what ended the A17 radio investigation |
| Step | Origin | Version | Why |
|---|---|---|---|
1. Patch vbmeta |
Samsung's file, ours: one byte | A536EXXSBEXI4, 2024-09-11 |
Nothing unsigned boots otherwise. Use the public upstream tool |
| 2. Flash TWRP | Third party: Flopster101 | 3.7.1_12, 2026-05-11 |
The only thing that can write /system |
| 3. Flash FloppyKernel Vanilla | Third party: Flopster101 | v6.3.3, 2026-07-21 | Boots a GSI and allows unsigned modules |
4. Flash system-a17-min.img |
AOSP CP2A.260605.012 + 3 byte patches ours |
built 2026-05-15, patched 2026-09-13 | The only code-level work required |
5. Leave /vendor alone |
Samsung | SP1A.210812.016, API 31 |
Treble does the rest |
Result: a booting, Enforcing Android 17, SDK 37, with working data and SMS and no voice. Add
stages 6 through 9 for voice. rebuild.md is the step-by-step procedure; this file is only
the ownership map.
| Piece | Why it is permanent |
|---|---|
Modem firmware and libsec-ril |
Everything about registration and CP audio goes through them. There is no open implementation |
| The camera HAL | The three patched blobs are 4-byte edits to Samsung's binaries, not reimplementations |
| The IMS stack itself | libsec-ims.so is Samsung's reSIProcate build; imsd and multiclientd are Samsung binaries. The port makes Android 17 able to host them, it does not replace them |
| Knox, Samsung Pay, Secure Folder, Samsung Health | The Knox fuse is blown and cannot be reset, regardless of what is flashed |
Removed because it identifies a person or a handset:
| Removed | Why |
|---|---|
| IMEI, serial number, Bluetooth MAC | Unique to one handset. They live in a device-identity.txt outside version control, mode 600, and are not reproducible if lost |
| The carrier's name, its carrier ID, and the MCC/MNC pair | Identifies the owner's operator and country. The mechanism is identical for any carrier, so naming one adds nothing technical |
| The regional CSC / sales code | A regional fingerprint that, combined with the carrier, narrows the owner considerably |
| Account and repository names | The kernel fork is public and GPL-attributed on its own; it does not need to be tied to this document |
| A third-party maintainer's email address, read out of a signing certificate | It is technically public inside a distributed image, but it is a real person's personal address. Roles, not addresses |
Cell identifiers (ci, pci, tac, earfcn) and the IMS IPv6 address |
A serving-cell identifier is a coarse location, and the IMS address is carrier-assigned and tied to the subscriber |
Removed because it is a constant lifted out of somebody else's proprietary binary:
| Removed | Why |
|---|---|
The four-byte ASCII constant eden_mem_free misuses as a length |
Naming the bug explains the fix; publishing the exact value from inside a closed-source library discloses its internals and hands over the edit rather than the reasoning. The behaviour is described in full, the magic number is not |
| The byte offsets of the blob edits, and every hash of something we built that contains vendor code: the patched blob md5s, the patched dex hash, and the sha256 of both derived system images | Same reasoning. What each edit changes semantically is stated, and that each is a small in-place edit, but not where to write it. The patched md5s are withheld too, since their only use is confirming somebody reproduced the exact edit. The stock hashes stay, including Google's pristine GSI and the unmodified Samsung libraries: those identify files the reader can obtain legitimately, and are an integrity check rather than a fingerprint of a derivative work. The AOSP platform testkey fingerprint stays too, since that key is published in AOSP |
| The verified-boot header magic and the patched offset | Both are in Google's public AVB specification and in the public upstream tool, so withholding them costs a reader nothing and keeps this document descriptive rather than a recipe |
Reduced, not removed:
| Item | Treatment |
|---|---|
| The verified-boot patch | The field that changes is named, because the reasoning matters and the AVB specification is public. The exact offset and value are not reproduced; the public upstream tool already publishes them |
| The blob patches | Described by effect (a guard on an absurd munmap length, an abort turned into the vendor's own non-fatal path, three added camcorder profiles) rather than by byte |
This document describes modifications. It contains no code or binaries from Samsung, Google or anyone else:
- the patched
imsservice.apkand the compositeimsmanager.jar, because they contain Samsung's proprietary dex, and a patched copy is a derivative work of it - the 19 Samsung native libraries,
imsdandmulticlientd, which are verbatim proprietary binaries - the patched camera blobs, same reason
- any
system.imgderived from Google's GSI plus the above
Anyone reproducing this extracts those files from their own handset's firmware.
What is freely shareable, and already is: the kernel fork, because it is GPLv2 and
publishing the source is an obligation rather than a favour; and the instruments in tools/,
which are original work that contains no vendor code.
The SELinux rules deliberately cross the Treble boundary. They let a coredomain
application use a vendor HAL, which the platform's own neverallow rules forbid, and they are
only tolerable here because the system-side component is the vendor's own IMS stack talking
to the vendor's own RIL. They weaken the sandbox. Do not copy them into anything you ship.
Verified boot is off on this device. That is the price of running a GSI, and it means the usual integrity guarantees are gone. It is a spare handset used for exactly this. It is not a sensible configuration for a phone holding anything you care about.