Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for replacing otacerts.zip in the system image
Previously, overriding otacerts.zip in the system partition required the user to flash a Magisk/KernelSU module that would bind mount over the file during boot. While this worked well enough, it's insufficient for unrooted setups, which has become more important since unrooting is the only safe way to use the new OEM repair mode feature. With the stock otacerts.zip, the OEM's default OTA updater app could run and install an OS upgrade that's not signed by the user's key. With this key, the raw otacerts.zip bytes in the system partition are directly replaced with a new zip that contains the user's certificate. This method was inspired by @pascallj's comment in #216 suggestiing intentionally corrupting the otacerts.zip data in the filesystem. Because avbroot does not have filesystem parsers for ext4/f2fs/erofs, we rely on a heuristic-based search on the raw filesystem image. The file is always smaller than one block (which is at least 4096 bytes on all known devices), so the file data is stored continguously on disk and in the case of erofs, won't be compressed. None of the three filesystems are copy-on-write and thus, have no filesystem-level data checksums. For the dm-verity layer one level up, avbroot already knows how to recompute the hash tree and FEC data. Since the new approach is doing a raw search and replace, the old and new files must have the same size. When the new zip is smaller, null bytes are added to the zip archive comment field to pad to the correct size. When the new zip is larger, avbroot will attempt the following to try and make the file size smaller: 1. Enable zip deflate compression 2. Strip the X.509 signature from the certificate 3. Clear out the issuer RDN sequence from the certificate 4. Clear out the subject RDN sequence from the certificate The latter three changes work because Android never performs any PKI operations with the certificate. There is no CA certificate chain. The X.509 certificate file is nothing more than a way to transport an RSA public key. avbroot requires the user's key to be RSA 4096. If the original zip had the same key size, then none of these shrinking methods are needed. If it contained an RSA 2048 key, then the first two modifications are usually sufficient. The latter two modifications should only be needed if the user picked a really long subject value when generating the certificate. With these new changes, the OTA patching time will approximately double on a system with an SSD and modern CPU. This is dominated by the time it takes to XZ-compress the system partition image. The compression is already parallelized and scales linearly with the number of cores. There's likely not much more that can be done to further speed this up. Finally, these new changes are currently excluded from the e2e tests because including the system partition in the stripped OTAs would increase the file size by an order of magnitude. This could potentially be solved in the future by generating our own small OTAs to use for testing instead of running against real device OTAs. Fixes: #225 Signed-off-by: Andrew Gunnerson <[email protected]>
- Loading branch information