diff options
author | Tao Bao | 2017-07-21 17:15:31 -0500 |
---|---|---|
committer | Tao Bao | 2017-07-21 19:17:03 -0500 |
commit | 5a1dee01df3af346729b5791606b72d59b8e9815 (patch) | |
tree | 323b3f45522f35b5a75ccc5a922456baa1f13f6c /update_verifier | |
parent | 9187f1cc51cc04155754d0ed34a5fc875acb9af4 (diff) | |
download | platform-bootable-recovery-5a1dee01df3af346729b5791606b72d59b8e9815.tar.gz platform-bootable-recovery-5a1dee01df3af346729b5791606b72d59b8e9815.tar.xz platform-bootable-recovery-5a1dee01df3af346729b5791606b72d59b8e9815.zip |
update_verifier: Handle legacy care_map.txt gracefully.
update_verifier should be backward compatible to not reject legacy
care_map.txt from old releases, which could otherwise fail to boot into
the new release.
For example, we've changed the care_map format between N and O. An O
update_verifier would fail to work with an N care_map.txt - a) we have
switched update_verifier to read from device mapper in O; b) the last
few blocks that contain metadata can't be read via device mapper. This
could be a result of sideloading an O OTA while the device having a
pending N update.
Bug: 63544345
Test: As follows on sailfish:
1. Flash the device with this CL;
2. Put a copy of N care_map.txt at /data/ota_package/. Restore the
permissions properly ('cache' group);
3. `adb reboot bootloader`;
4. `fastboot set_active <current_slot>`
5. Device boots up into home screen, with a warning in logcat that says
it has skipped legacy care_map.txt.
Change-Id: I6acc88c9e655a9245e6531f176fef7953953935f
Diffstat (limited to 'update_verifier')
-rw-r--r-- | update_verifier/update_verifier.cpp | 71 |
1 files changed, 42 insertions, 29 deletions
diff --git a/update_verifier/update_verifier.cpp b/update_verifier/update_verifier.cpp index d3a5185b..b49011a1 100644 --- a/update_verifier/update_verifier.cpp +++ b/update_verifier/update_verifier.cpp | |||
@@ -175,40 +175,53 @@ static bool read_blocks(const std::string& partition, const std::string& range_s | |||
175 | return true; | 175 | return true; |
176 | } | 176 | } |
177 | 177 | ||
178 | // Returns true to indicate a passing verification (or the error should be ignored); Otherwise | ||
179 | // returns false on fatal errors, where we should reject the current boot and trigger a fallback. | ||
180 | // Note that update_verifier should be backward compatible to not reject care_map.txt from old | ||
181 | // releases, which could otherwise fail to boot into the new release. For example, we've changed | ||
182 | // the care_map format between N and O. An O update_verifier would fail to work with N | ||
183 | // care_map.txt. This could be a result of sideloading an O OTA while the device having a pending N | ||
184 | // update. | ||
178 | bool verify_image(const std::string& care_map_name) { | 185 | bool verify_image(const std::string& care_map_name) { |
179 | android::base::unique_fd care_map_fd(TEMP_FAILURE_RETRY(open(care_map_name.c_str(), O_RDONLY))); | 186 | android::base::unique_fd care_map_fd(TEMP_FAILURE_RETRY(open(care_map_name.c_str(), O_RDONLY))); |
180 | // If the device is flashed before the current boot, it may not have care_map.txt | 187 | // If the device is flashed before the current boot, it may not have care_map.txt |
181 | // in /data/ota_package. To allow the device to continue booting in this situation, | 188 | // in /data/ota_package. To allow the device to continue booting in this situation, |
182 | // we should print a warning and skip the block verification. | 189 | // we should print a warning and skip the block verification. |
183 | if (care_map_fd.get() == -1) { | 190 | if (care_map_fd.get() == -1) { |
184 | PLOG(WARNING) << "Failed to open " << care_map_name; | 191 | PLOG(WARNING) << "Failed to open " << care_map_name; |
185 | return true; | 192 | return true; |
186 | } | 193 | } |
187 | // Care map file has four lines (two lines if vendor partition is not present): | 194 | // Care map file has four lines (two lines if vendor partition is not present): |
188 | // First line has the block partition name (system/vendor). | 195 | // First line has the block partition name (system/vendor). |
189 | // Second line holds all ranges of blocks to verify. | 196 | // Second line holds all ranges of blocks to verify. |
190 | // The next two lines have the same format but for vendor partition. | 197 | // The next two lines have the same format but for vendor partition. |
191 | std::string file_content; | 198 | std::string file_content; |
192 | if (!android::base::ReadFdToString(care_map_fd.get(), &file_content)) { | 199 | if (!android::base::ReadFdToString(care_map_fd.get(), &file_content)) { |
193 | LOG(ERROR) << "Error reading care map contents to string."; | 200 | LOG(ERROR) << "Error reading care map contents to string."; |
194 | return false; | 201 | return false; |
195 | } | 202 | } |
196 | 203 | ||
197 | std::vector<std::string> lines; | 204 | std::vector<std::string> lines; |
198 | lines = android::base::Split(android::base::Trim(file_content), "\n"); | 205 | lines = android::base::Split(android::base::Trim(file_content), "\n"); |
199 | if (lines.size() != 2 && lines.size() != 4) { | 206 | if (lines.size() != 2 && lines.size() != 4) { |
200 | LOG(ERROR) << "Invalid lines in care_map: found " << lines.size() | 207 | LOG(ERROR) << "Invalid lines in care_map: found " << lines.size() |
201 | << " lines, expecting 2 or 4 lines."; | 208 | << " lines, expecting 2 or 4 lines."; |
202 | return false; | 209 | return false; |
203 | } | 210 | } |
204 | 211 | ||
205 | for (size_t i = 0; i < lines.size(); i += 2) { | 212 | for (size_t i = 0; i < lines.size(); i += 2) { |
206 | if (!read_blocks(lines[i], lines[i+1])) { | 213 | // We're seeing an N care_map.txt. Skip the verification since it's not compatible with O |
207 | return false; | 214 | // update_verifier (the last few metadata blocks can't be read via device mapper). |
208 | } | 215 | if (android::base::StartsWith(lines[i], "/dev/block/")) { |
216 | LOG(WARNING) << "Found legacy care_map.txt; skipped."; | ||
217 | return true; | ||
218 | } | ||
219 | if (!read_blocks(lines[i], lines[i+1])) { | ||
220 | return false; | ||
209 | } | 221 | } |
222 | } | ||
210 | 223 | ||
211 | return true; | 224 | return true; |
212 | } | 225 | } |
213 | 226 | ||
214 | static int reboot_device() { | 227 | static int reboot_device() { |