diff options
authorDavid Anderson2018-07-30 14:54:53 -0500
committerDavid Anderson2018-07-30 16:48:13 -0500
commit0c7bde8de630f1668cf554e14641bffd56617e1e (patch)
parentd5f825c78bc98027a485d8bdecd14e8563a449ba (diff)
fastboot: Fix hang when sparse images end in small chunks.
When host fastboot sends sparse blocks to the device, it tries to only send blocks in multiples of 1024 bytes. If a block is not aligned to this size, the excess bytes are prepended to the next write operation. This is implemented by doing the write in two steps: first the previous excess from the last write (plus new data up to alignment), then a second write for the aligned remainder of the new data. This logic has a bug if the final block plus the previous excess data contains >= 1024 but < 2048 bytes. In this case the first write will drain 1024 bytes from the data, and the second write will not have 1024 bytes to write. Instead of retaining this data for the next write, it tries to write 0 chunks (and thus 0 bytes), which hangs the ioctl() call. Bug: N/A Test: "fastboot flash super super.img" where super.img is generated by lpmake, containing system and product_services partitions and images. Change-Id: I9e8523c976ec84d5a57b36a28f4b1ca800edb7e7
1 files changed, 4 insertions, 0 deletions
diff --git a/fastboot/fastboot_driver.cpp b/fastboot/fastboot_driver.cpp
index c30842055..aabc620d4 100644
--- a/fastboot/fastboot_driver.cpp
+++ b/fastboot/fastboot_driver.cpp
@@ -462,6 +462,10 @@ RetCode FastBootDriver::SendBuffer(const std::vector<char>& buf) {
462} 462}
463 463
464RetCode FastBootDriver::SendBuffer(const void* buf, size_t size) { 464RetCode FastBootDriver::SendBuffer(const void* buf, size_t size) {
465 if (!size) {
466 return SUCCESS;
467 }
465 // Write the buffer 469 // Write the buffer
466 ssize_t tmp = transport->Write(buf, size); 470 ssize_t tmp = transport->Write(buf, size);
467 471