K2GO-90 fix(rootfs): move the manifest onto the product's name, reading both - #532
Merged
Merged
Conversation
… broken window The identity manifest, its integrity sibling and the kind they declare are matched under both the iiab- and k2go- names. The builder still writes the old one: this only removes the reason it cannot stop. The reader has to ship before the writer changes. An app that only knew the new name would reject every archive built before the switch — including the backups users are told to make before migrating, which is the one moment when a rejected restore is unrecoverable. The integrity member is matched the same way for a sharper reason: it is excluded from the tree hash it declares, so failing to recognise it would fold it into its own digest and read every archive as CORRUPT.
The fallback name for the staged OTA APK was iiab_update.apk. It is only used when the download URL does not end in .apk, so it rarely surfaces — but it was spelled out twice, once when staging the file and once as the default when reading the name back out of SharedPreferences. Two literals for one fact: drifting apart would stage the file under one name and have the verifier look for it under another, on the one path nobody exercises. It is k2go_update.apk now, in a single constant both sides read.
Both writers move together: BackupEngine, which stamps the manifest into user backups, and build-iiab-rootfs.sh, which stamps it into the images. They have to agree, because the validator compares an archive against what a rootfs image looks like. Done now rather than later on purpose. The installed base is developers and a handful of users, so the set of archives carrying the old name closes today instead of growing with every backup written from here on — which is what would have made the tolerance for it impossible to ever drop. Verified on device: an image built with the old writer installs, a backup taken from it carries the new name as the tar's first member, and restoring that backup completes. The integrity member is recognised under the new name too, which is the failure that would otherwise have read every archive as CORRUPT.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The app reads the rootfs manifest under both the
iiab-andk2go-names, and both writers nowproduce the new one. The staged OTA APK follows.
Why both halves land together
The reader has to be tolerant before anything writes the new name, or archives built either side of
the switch stop being restorable. That much is ordering. The reason to write it now rather than
later is the population: with developers and a handful of users, the set of archives carrying the
old name closes today. Ship the writer later and it grows with every backup taken in between —
which is what would make the tolerance impossible to ever drop.
RootfsIdentitykind=iiab-rootfsork2go-rootfsRootfsManifestiiab/.iiab-rootfs.jsonoriiab/.k2go-rootfs.jsonRootfsIntegrity.integrity.jsonsiblingBackupEngine.k2go-rootfs.json,kind: k2go-rootfs, first tar membertools/rootfs-builderThe integrity member is matched for a sharper reason than symmetry: it is excluded from the tree
hash it declares, so failing to recognise it would fold it into its own digest and read every
archive as CORRUPT.
Verified on device, both names in one session
An image built by the old writer — the one in the bucket today — installs and carries
.iiab-rootfs.json. A backup taken from it carries.k2go-rootfs.jsonas the tar's first member.Restoring that backup completes, and the restored tree carries the new manifest. If the integrity
member had gone unrecognised, validation would have reported CORRUPT before extraction began.
Incidentally confirming a change from earlier in this ticket: at 62% — still the verify pass — the
damage marker was not yet planted. It goes down at the first byte written, so an ungraceful exit
during verification no longer declares a false DAMAGED.
The staged OTA APK
Its fallback name — used only when the download URL does not end in
.apk— becomesk2go_update.apk. It had been spelled out twice, once when staging the file and once as the defaultwhen reading the name back out of SharedPreferences: drifting apart would stage the file under one
name and have the verifier look for it under another, on the one path nobody exercises. One constant
now, read by both sides.
Tests
Four cases on the pure rule, including the actual risk of this change: accepting a second
kindmust not become a way around the ABI check. A
k2go-rootfsbuilt for 32-bit is stillWRONG_ARCHon a 64-bit device, and anything that is neither kind is still
NOT_A_ROOTFS.Not in scope
The seven
iiab_*SharedPreferences names, the ADB keystore alias and theiiab_synchandshaketoken stay as they are. Those are not branding: renaming a preferences file abandons its contents,
the alias renames a key that is already paired, and the handshake token is verified by the phone on
the other end.