diff --git a/fastboot/Android.bp b/fastboot/Android.bp index 3a2deb7dd..6b49fc74e 100644 --- a/fastboot/Android.bp +++ b/fastboot/Android.bp @@ -149,6 +149,7 @@ cc_binary { ], header_libs: [ + "avb_headers", "libsnapshot_headers", ] } diff --git a/fastboot/device/flashing.cpp b/fastboot/device/flashing.cpp index fd6ff8ea4..1bf4c9c9c 100644 --- a/fastboot/device/flashing.cpp +++ b/fastboot/device/flashing.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -122,6 +123,27 @@ int FlashBlockDevice(int fd, std::vector& downloaded_data) { } } +static void CopyAVBFooter(std::vector* data, const uint64_t block_device_size) { + if (data->size() < AVB_FOOTER_SIZE) { + return; + } + std::string footer; + uint64_t footer_offset = data->size() - AVB_FOOTER_SIZE; + for (int idx = 0; idx < AVB_FOOTER_MAGIC_LEN; idx++) { + footer.push_back(data->at(footer_offset + idx)); + } + if (0 != footer.compare(AVB_FOOTER_MAGIC)) { + return; + } + + // copy AVB footer from end of data to end of block device + uint64_t original_data_size = data->size(); + data->resize(block_device_size, 0); + for (int idx = 0; idx < AVB_FOOTER_SIZE; idx++) { + data->at(block_device_size - 1 - idx) = data->at(original_data_size - 1 - idx); + } +} + int Flash(FastbootDevice* device, const std::string& partition_name) { PartitionHandle handle; if (!OpenPartition(device, partition_name, &handle)) { @@ -131,8 +153,14 @@ int Flash(FastbootDevice* device, const std::string& partition_name) { std::vector data = std::move(device->download_data()); if (data.size() == 0) { return -EINVAL; - } else if (data.size() > get_block_device_size(handle.fd())) { + } + uint64_t block_device_size = get_block_device_size(handle.fd()); + if (data.size() > block_device_size) { return -EOVERFLOW; + } else if (data.size() < block_device_size && + (partition_name == "boot" || partition_name == "boot_a" || + partition_name == "boot_b")) { + CopyAVBFooter(&data, block_device_size); } WipeOverlayfsForPartition(device, partition_name); int result = FlashBlockDevice(handle.fd(), data);