No Description

install.cpp 28KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784
  1. /*
  2. * Copyright (C) 2007 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "install.h"
  17. #include <ctype.h>
  18. #include <errno.h>
  19. #include <fcntl.h>
  20. #include <inttypes.h>
  21. #include <limits.h>
  22. #include <string.h>
  23. #include <sys/stat.h>
  24. #include <sys/wait.h>
  25. #include <unistd.h>
  26. #include <setjmp.h>
  27. #include <algorithm>
  28. #include <atomic>
  29. #include <chrono>
  30. #include <condition_variable>
  31. #include <functional>
  32. #include <limits>
  33. #include <map>
  34. #include <mutex>
  35. #include <string>
  36. #include <thread>
  37. #include <vector>
  38. #include <android-base/file.h>
  39. #include <android-base/logging.h>
  40. #include <android-base/parsedouble.h>
  41. #include <android-base/parseint.h>
  42. #include <android-base/properties.h>
  43. #include <android-base/stringprintf.h>
  44. #include <android-base/strings.h>
  45. #include <vintf/VintfObjectRecovery.h>
  46. #include <ziparchive/zip_archive.h>
  47. #include <cutils/properties.h>
  48. #include "common.h"
  49. #include "otautil/SysUtil.h"
  50. #include "otautil/ThermalUtil.h"
  51. #include "otautil/error_code.h"
  52. #include "private/install.h"
  53. #include "roots.h"
  54. #include "ui.h"
  55. #include "verifier.h"
  56. using namespace std::chrono_literals;
  57. // Default allocation of progress bar segments to operations
  58. static constexpr int VERIFICATION_PROGRESS_TIME = 60;
  59. static constexpr float VERIFICATION_PROGRESS_FRACTION = 0.25;
  60. static std::condition_variable finish_log_temperature;
  61. // This function parses and returns the build.version.incremental
  62. static std::string parse_build_number(const std::string& str) {
  63. size_t pos = str.find('=');
  64. if (pos != std::string::npos) {
  65. return android::base::Trim(str.substr(pos+1));
  66. }
  67. LOG(ERROR) << "Failed to parse build number in " << str;
  68. return "";
  69. }
  70. bool read_metadata_from_package(ZipArchiveHandle zip, std::string* metadata) {
  71. CHECK(metadata != nullptr);
  72. static constexpr const char* METADATA_PATH = "META-INF/com/android/metadata";
  73. ZipString path(METADATA_PATH);
  74. ZipEntry entry;
  75. if (FindEntry(zip, path, &entry) != 0) {
  76. LOG(ERROR) << "Failed to find " << METADATA_PATH;
  77. return false;
  78. }
  79. uint32_t length = entry.uncompressed_length;
  80. metadata->resize(length, '\0');
  81. int32_t err = ExtractToMemory(zip, &entry, reinterpret_cast<uint8_t*>(&(*metadata)[0]), length);
  82. if (err != 0) {
  83. LOG(ERROR) << "Failed to extract " << METADATA_PATH << ": " << ErrorCodeString(err);
  84. return false;
  85. }
  86. return true;
  87. }
  88. // Read the build.version.incremental of src/tgt from the metadata and log it to last_install.
  89. static void read_source_target_build(ZipArchiveHandle zip, std::vector<std::string>* log_buffer) {
  90. std::string metadata;
  91. if (!read_metadata_from_package(zip, &metadata)) {
  92. return;
  93. }
  94. // Examples of the pre-build and post-build strings in metadata:
  95. // pre-build-incremental=2943039
  96. // post-build-incremental=2951741
  97. std::vector<std::string> lines = android::base::Split(metadata, "\n");
  98. for (const std::string& line : lines) {
  99. std::string str = android::base::Trim(line);
  100. if (android::base::StartsWith(str, "pre-build-incremental")) {
  101. std::string source_build = parse_build_number(str);
  102. if (!source_build.empty()) {
  103. log_buffer->push_back("source_build: " + source_build);
  104. }
  105. } else if (android::base::StartsWith(str, "post-build-incremental")) {
  106. std::string target_build = parse_build_number(str);
  107. if (!target_build.empty()) {
  108. log_buffer->push_back("target_build: " + target_build);
  109. }
  110. }
  111. }
  112. }
  113. // Parses the metadata of the OTA package in |zip| and checks whether we are
  114. // allowed to accept this A/B package. Downgrading is not allowed unless
  115. // explicitly enabled in the package and only for incremental packages.
  116. static int check_newer_ab_build(ZipArchiveHandle zip) {
  117. std::string metadata_str;
  118. if (!read_metadata_from_package(zip, &metadata_str)) {
  119. return INSTALL_CORRUPT;
  120. }
  121. std::map<std::string, std::string> metadata;
  122. for (const std::string& line : android::base::Split(metadata_str, "\n")) {
  123. size_t eq = line.find('=');
  124. if (eq != std::string::npos) {
  125. metadata[line.substr(0, eq)] = line.substr(eq + 1);
  126. }
  127. }
  128. std::string value = android::base::GetProperty("ro.product.device", "");
  129. const std::string& pkg_device = metadata["pre-device"];
  130. if (pkg_device != value || pkg_device.empty()) {
  131. LOG(ERROR) << "Package is for product " << pkg_device << " but expected " << value;
  132. return INSTALL_ERROR;
  133. }
  134. // We allow the package to not have any serialno; and we also allow it to carry multiple serial
  135. // numbers split by "|"; e.g. serialno=serialno1|serialno2|serialno3 ... We will fail the
  136. // verification if the device's serialno doesn't match any of these carried numbers.
  137. value = android::base::GetProperty("ro.serialno", "");
  138. const std::string& pkg_serial_no = metadata["serialno"];
  139. if (!pkg_serial_no.empty()) {
  140. bool match = false;
  141. for (const std::string& number : android::base::Split(pkg_serial_no, "|")) {
  142. if (value == android::base::Trim(number)) {
  143. match = true;
  144. break;
  145. }
  146. }
  147. if (!match) {
  148. LOG(ERROR) << "Package is for serial " << pkg_serial_no;
  149. return INSTALL_ERROR;
  150. }
  151. }
  152. if (metadata["ota-type"] != "AB") {
  153. LOG(ERROR) << "Package is not A/B";
  154. return INSTALL_ERROR;
  155. }
  156. // Incremental updates should match the current build.
  157. value = android::base::GetProperty("ro.build.version.incremental", "");
  158. const std::string& pkg_pre_build = metadata["pre-build-incremental"];
  159. if (!pkg_pre_build.empty() && pkg_pre_build != value) {
  160. LOG(ERROR) << "Package is for source build " << pkg_pre_build << " but expected " << value;
  161. return INSTALL_ERROR;
  162. }
  163. value = android::base::GetProperty("ro.build.fingerprint", "");
  164. const std::string& pkg_pre_build_fingerprint = metadata["pre-build"];
  165. if (!pkg_pre_build_fingerprint.empty() && pkg_pre_build_fingerprint != value) {
  166. LOG(ERROR) << "Package is for source build " << pkg_pre_build_fingerprint << " but expected "
  167. << value;
  168. return INSTALL_ERROR;
  169. }
  170. // Check for downgrade version.
  171. int64_t build_timestamp =
  172. android::base::GetIntProperty("ro.build.date.utc", std::numeric_limits<int64_t>::max());
  173. int64_t pkg_post_timestamp = 0;
  174. // We allow to full update to the same version we are running, in case there
  175. // is a problem with the current copy of that version.
  176. if (metadata["post-timestamp"].empty() ||
  177. !android::base::ParseInt(metadata["post-timestamp"].c_str(), &pkg_post_timestamp) ||
  178. pkg_post_timestamp < build_timestamp) {
  179. if (metadata["ota-downgrade"] != "yes") {
  180. LOG(ERROR) << "Update package is older than the current build, expected a build "
  181. "newer than timestamp "
  182. << build_timestamp << " but package has timestamp " << pkg_post_timestamp
  183. << " and downgrade not allowed.";
  184. return INSTALL_ERROR;
  185. }
  186. if (pkg_pre_build_fingerprint.empty()) {
  187. LOG(ERROR) << "Downgrade package must have a pre-build version set, not allowed.";
  188. return INSTALL_ERROR;
  189. }
  190. }
  191. return 0;
  192. }
  193. int update_binary_command_ab(const std::string& package, ZipArchiveHandle zip,
  194. const std::string& binary_path, int /* retry_count */, int status_fd,
  195. std::vector<std::string>* cmd) {
  196. CHECK(cmd != nullptr);
  197. int ret = check_newer_ab_build(zip);
  198. if (ret != 0) {
  199. return ret;
  200. }
  201. // For A/B updates we extract the payload properties to a buffer and obtain the RAW payload offset
  202. // in the zip file.
  203. static constexpr const char* AB_OTA_PAYLOAD_PROPERTIES = "payload_properties.txt";
  204. ZipString property_name(AB_OTA_PAYLOAD_PROPERTIES);
  205. ZipEntry properties_entry;
  206. if (FindEntry(zip, property_name, &properties_entry) != 0) {
  207. LOG(ERROR) << "Failed to find " << AB_OTA_PAYLOAD_PROPERTIES;
  208. return INSTALL_CORRUPT;
  209. }
  210. uint32_t properties_entry_length = properties_entry.uncompressed_length;
  211. std::vector<uint8_t> payload_properties(properties_entry_length);
  212. int32_t err =
  213. ExtractToMemory(zip, &properties_entry, payload_properties.data(), properties_entry_length);
  214. if (err != 0) {
  215. LOG(ERROR) << "Failed to extract " << AB_OTA_PAYLOAD_PROPERTIES << ": " << ErrorCodeString(err);
  216. return INSTALL_CORRUPT;
  217. }
  218. static constexpr const char* AB_OTA_PAYLOAD = "payload.bin";
  219. ZipString payload_name(AB_OTA_PAYLOAD);
  220. ZipEntry payload_entry;
  221. if (FindEntry(zip, payload_name, &payload_entry) != 0) {
  222. LOG(ERROR) << "Failed to find " << AB_OTA_PAYLOAD;
  223. return INSTALL_CORRUPT;
  224. }
  225. long payload_offset = payload_entry.offset;
  226. *cmd = {
  227. binary_path,
  228. "--payload=file://" + package,
  229. android::base::StringPrintf("--offset=%ld", payload_offset),
  230. "--headers=" + std::string(payload_properties.begin(), payload_properties.end()),
  231. android::base::StringPrintf("--status_fd=%d", status_fd),
  232. };
  233. return 0;
  234. }
  235. int update_binary_command_legacy(const std::string& package, ZipArchiveHandle zip,
  236. const std::string& binary_path, int retry_count, int status_fd,
  237. std::vector<std::string>* cmd) {
  238. CHECK(cmd != nullptr);
  239. // On traditional updates we extract the update binary from the package.
  240. static constexpr const char* UPDATE_BINARY_NAME = "META-INF/com/google/android/update-binary";
  241. ZipString binary_name(UPDATE_BINARY_NAME);
  242. ZipEntry binary_entry;
  243. if (FindEntry(zip, binary_name, &binary_entry) != 0) {
  244. LOG(ERROR) << "Failed to find update binary " << UPDATE_BINARY_NAME;
  245. return INSTALL_CORRUPT;
  246. }
  247. unlink(binary_path.c_str());
  248. int fd = open(binary_path.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, 0755);
  249. if (fd == -1) {
  250. PLOG(ERROR) << "Failed to create " << binary_path;
  251. return INSTALL_ERROR;
  252. }
  253. int32_t error = ExtractEntryToFile(zip, &binary_entry, fd);
  254. close(fd);
  255. if (error != 0) {
  256. LOG(ERROR) << "Failed to extract " << UPDATE_BINARY_NAME << ": " << ErrorCodeString(error);
  257. return INSTALL_ERROR;
  258. }
  259. *cmd = {
  260. binary_path,
  261. std::to_string(kRecoveryApiVersion),
  262. std::to_string(status_fd),
  263. package,
  264. };
  265. if (retry_count > 0) {
  266. cmd->push_back("retry");
  267. }
  268. return 0;
  269. }
  270. static void log_max_temperature(int* max_temperature, const std::atomic<bool>& logger_finished) {
  271. CHECK(max_temperature != nullptr);
  272. std::mutex mtx;
  273. std::unique_lock<std::mutex> lck(mtx);
  274. while (!logger_finished.load() &&
  275. finish_log_temperature.wait_for(lck, 20s) == std::cv_status::timeout) {
  276. *max_temperature = std::max(*max_temperature, GetMaxValueFromThermalZone());
  277. }
  278. }
  279. static jmp_buf jb;
  280. static void sig_bus(int)
  281. {
  282. longjmp(jb, 1);
  283. }
  284. // If the package contains an update binary, extract it and run it.
  285. static int try_update_binary(const std::string& package, ZipArchiveHandle zip, bool* wipe_cache,
  286. std::vector<std::string>* log_buffer, int retry_count,
  287. int* max_temperature) {
  288. read_source_target_build(zip, log_buffer);
  289. int ret;
  290. int pipefd[2];
  291. pipe(pipefd);
  292. std::vector<std::string> args;
  293. bool ab_ota = false;
  294. #ifdef AB_OTA_UPDATER
  295. // A/B updates contain a payload.bin and a text file describing the payload.
  296. // We check for this file to see whether the update package has to be flashed using update_engine
  297. // or if it's a traditional package with an updater-script.
  298. static constexpr const char* AB_OTA_PAYLOAD_PROPERTIES = "payload_properties.txt";
  299. ZipString property_name(AB_OTA_PAYLOAD_PROPERTIES);
  300. ZipEntry properties_entry;
  301. if (FindEntry(zip, property_name, &properties_entry) == 0) {
  302. ab_ota = true;
  303. }
  304. #endif
  305. if (ab_ota) {
  306. ret = update_binary_command_ab(package, zip, "/sbin/update_engine_sideload", retry_count,
  307. pipefd[1], &args);
  308. } else {
  309. ret = update_binary_command_legacy(package, zip, "/tmp/update-binary", retry_count, pipefd[1],
  310. &args);
  311. }
  312. if (ret) {
  313. close(pipefd[0]);
  314. close(pipefd[1]);
  315. log_buffer->push_back(android::base::StringPrintf("error: %d", kUpdateBinaryCommandFailure));
  316. return ret;
  317. }
  318. // When executing the update binary contained in the package, the
  319. // arguments passed are:
  320. //
  321. // - the version number for this interface
  322. //
  323. // - an FD to which the program can write in order to update the
  324. // progress bar. The program can write single-line commands:
  325. //
  326. // progress <frac> <secs>
  327. // fill up the next <frac> part of of the progress bar
  328. // over <secs> seconds. If <secs> is zero, use
  329. // set_progress commands to manually control the
  330. // progress of this segment of the bar.
  331. //
  332. // set_progress <frac>
  333. // <frac> should be between 0.0 and 1.0; sets the
  334. // progress bar within the segment defined by the most
  335. // recent progress command.
  336. //
  337. // ui_print <string>
  338. // display <string> on the screen.
  339. //
  340. // wipe_cache
  341. // a wipe of cache will be performed following a successful
  342. // installation.
  343. //
  344. // clear_display
  345. // turn off the text display.
  346. //
  347. // enable_reboot
  348. // packages can explicitly request that they want the user
  349. // to be able to reboot during installation (useful for
  350. // debugging packages that don't exit).
  351. //
  352. // retry_update
  353. // updater encounters some issue during the update. It requests
  354. // a reboot to retry the same package automatically.
  355. //
  356. // log <string>
  357. // updater requests logging the string (e.g. cause of the
  358. // failure).
  359. //
  360. // - the name of the package zip file.
  361. //
  362. // - an optional argument "retry" if this update is a retry of a failed
  363. // update attempt.
  364. //
  365. // Convert the vector to a NULL-terminated char* array suitable for execv.
  366. const char* chr_args[args.size() + 1];
  367. chr_args[args.size()] = nullptr;
  368. for (size_t i = 0; i < args.size(); i++) {
  369. chr_args[i] = args[i].c_str();
  370. }
  371. pid_t pid = fork();
  372. if (pid == -1) {
  373. close(pipefd[0]);
  374. close(pipefd[1]);
  375. PLOG(ERROR) << "Failed to fork update binary";
  376. log_buffer->push_back(android::base::StringPrintf("error: %d", kForkUpdateBinaryFailure));
  377. return INSTALL_ERROR;
  378. }
  379. if (pid == 0) {
  380. umask(022);
  381. close(pipefd[0]);
  382. execv(chr_args[0], const_cast<char**>(chr_args));
  383. // Bug: 34769056
  384. // We shouldn't use LOG/PLOG in the forked process, since they may cause
  385. // the child process to hang. This deadlock results from an improperly
  386. // copied mutex in the ui functions.
  387. fprintf(stdout, "E:Can't run %s (%s)\n", chr_args[0], strerror(errno));
  388. _exit(EXIT_FAILURE);
  389. }
  390. close(pipefd[1]);
  391. std::atomic<bool> logger_finished(false);
  392. std::thread temperature_logger(log_max_temperature, max_temperature, std::ref(logger_finished));
  393. *wipe_cache = false;
  394. bool retry_update = false;
  395. char buffer[1024];
  396. FILE* from_child = fdopen(pipefd[0], "r");
  397. while (fgets(buffer, sizeof(buffer), from_child) != nullptr) {
  398. std::string line(buffer);
  399. size_t space = line.find_first_of(" \n");
  400. std::string command(line.substr(0, space));
  401. if (command.empty()) continue;
  402. // Get rid of the leading and trailing space and/or newline.
  403. std::string args = space == std::string::npos ? "" : android::base::Trim(line.substr(space));
  404. if (command == "progress") {
  405. std::vector<std::string> tokens = android::base::Split(args, " ");
  406. double fraction;
  407. int seconds;
  408. if (tokens.size() == 2 && android::base::ParseDouble(tokens[0].c_str(), &fraction) &&
  409. android::base::ParseInt(tokens[1], &seconds)) {
  410. ui->ShowProgress(fraction * (1 - VERIFICATION_PROGRESS_FRACTION), seconds);
  411. } else {
  412. LOG(ERROR) << "invalid \"progress\" parameters: " << line;
  413. }
  414. } else if (command == "set_progress") {
  415. std::vector<std::string> tokens = android::base::Split(args, " ");
  416. double fraction;
  417. if (tokens.size() == 1 && android::base::ParseDouble(tokens[0].c_str(), &fraction)) {
  418. ui->SetProgress(fraction);
  419. } else {
  420. LOG(ERROR) << "invalid \"set_progress\" parameters: " << line;
  421. }
  422. } else if (command == "ui_print") {
  423. ui->PrintOnScreenOnly("%s\n", args.c_str());
  424. fflush(stdout);
  425. } else if (command == "wipe_cache") {
  426. *wipe_cache = true;
  427. } else if (command == "clear_display") {
  428. ui->SetBackground(RecoveryUI::NONE);
  429. } else if (command == "enable_reboot") {
  430. // packages can explicitly request that they want the user
  431. // to be able to reboot during installation (useful for
  432. // debugging packages that don't exit).
  433. ui->SetEnableReboot(true);
  434. } else if (command == "retry_update") {
  435. retry_update = true;
  436. } else if (command == "log") {
  437. if (!args.empty()) {
  438. // Save the logging request from updater and write to last_install later.
  439. log_buffer->push_back(args);
  440. } else {
  441. LOG(ERROR) << "invalid \"log\" parameters: " << line;
  442. }
  443. } else {
  444. LOG(ERROR) << "unknown command [" << command << "]";
  445. }
  446. }
  447. fclose(from_child);
  448. int status;
  449. waitpid(pid, &status, 0);
  450. logger_finished.store(true);
  451. finish_log_temperature.notify_one();
  452. temperature_logger.join();
  453. if (retry_update) {
  454. return INSTALL_RETRY;
  455. }
  456. if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
  457. LOG(ERROR) << "Error in " << package << " (Status " << WEXITSTATUS(status) << ")";
  458. return INSTALL_ERROR;
  459. }
  460. return INSTALL_SUCCESS;
  461. }
  462. // Verifes the compatibility info in a Treble-compatible package. Returns true directly if the
  463. // entry doesn't exist. Note that the compatibility info is packed in a zip file inside the OTA
  464. // package.
  465. bool verify_package_compatibility(ZipArchiveHandle package_zip) {
  466. LOG(INFO) << "Verifying package compatibility...";
  467. static constexpr const char* COMPATIBILITY_ZIP_ENTRY = "compatibility.zip";
  468. ZipString compatibility_entry_name(COMPATIBILITY_ZIP_ENTRY);
  469. ZipEntry compatibility_entry;
  470. if (FindEntry(package_zip, compatibility_entry_name, &compatibility_entry) != 0) {
  471. LOG(INFO) << "Package doesn't contain " << COMPATIBILITY_ZIP_ENTRY << " entry";
  472. return true;
  473. }
  474. std::string zip_content(compatibility_entry.uncompressed_length, '\0');
  475. int32_t ret;
  476. if ((ret = ExtractToMemory(package_zip, &compatibility_entry,
  477. reinterpret_cast<uint8_t*>(&zip_content[0]),
  478. compatibility_entry.uncompressed_length)) != 0) {
  479. LOG(ERROR) << "Failed to read " << COMPATIBILITY_ZIP_ENTRY << ": " << ErrorCodeString(ret);
  480. return false;
  481. }
  482. ZipArchiveHandle zip_handle;
  483. ret = OpenArchiveFromMemory(static_cast<void*>(const_cast<char*>(zip_content.data())),
  484. zip_content.size(), COMPATIBILITY_ZIP_ENTRY, &zip_handle);
  485. if (ret != 0) {
  486. LOG(ERROR) << "Failed to OpenArchiveFromMemory: " << ErrorCodeString(ret);
  487. return false;
  488. }
  489. // Iterate all the entries inside COMPATIBILITY_ZIP_ENTRY and read the contents.
  490. void* cookie;
  491. ret = StartIteration(zip_handle, &cookie, nullptr, nullptr);
  492. if (ret != 0) {
  493. LOG(ERROR) << "Failed to start iterating zip entries: " << ErrorCodeString(ret);
  494. CloseArchive(zip_handle);
  495. return false;
  496. }
  497. std::unique_ptr<void, decltype(&EndIteration)> guard(cookie, EndIteration);
  498. std::vector<std::string> compatibility_info;
  499. ZipEntry info_entry;
  500. ZipString info_name;
  501. while (Next(cookie, &info_entry, &info_name) == 0) {
  502. std::string content(info_entry.uncompressed_length, '\0');
  503. int32_t ret = ExtractToMemory(zip_handle, &info_entry, reinterpret_cast<uint8_t*>(&content[0]),
  504. info_entry.uncompressed_length);
  505. if (ret != 0) {
  506. LOG(ERROR) << "Failed to read " << info_name.name << ": " << ErrorCodeString(ret);
  507. CloseArchive(zip_handle);
  508. return false;
  509. }
  510. compatibility_info.emplace_back(std::move(content));
  511. }
  512. CloseArchive(zip_handle);
  513. // VintfObjectRecovery::CheckCompatibility returns zero on success.
  514. std::string err;
  515. int result = android::vintf::VintfObjectRecovery::CheckCompatibility(compatibility_info, &err);
  516. if (result == 0) {
  517. return true;
  518. }
  519. LOG(ERROR) << "Failed to verify package compatibility (result " << result << "): " << err;
  520. return false;
  521. }
  522. static int really_install_package(std::string path, bool* wipe_cache, bool needs_mount,
  523. std::vector<std::string>* log_buffer, int retry_count,
  524. bool verify, int* max_temperature) {
  525. ui->SetBackground(RecoveryUI::INSTALLING_UPDATE);
  526. ui->Print("Finding update package...\n");
  527. // Give verification half the progress bar...
  528. ui->SetProgressType(RecoveryUI::DETERMINATE);
  529. ui->ShowProgress(VERIFICATION_PROGRESS_FRACTION, VERIFICATION_PROGRESS_TIME);
  530. // Resolve symlink in case legacy /sdcard path is used
  531. // Requires: symlink uses absolute path
  532. if (path.size() > 1) {
  533. size_t root_pos = path.find('/', 1);
  534. if (root_pos != std::string::npos) {
  535. char link_path[PATH_MAX];
  536. ssize_t link_len;
  537. memset(link_path, 0, sizeof(link_path));
  538. link_len = readlink(path.substr(0, root_pos).c_str(),
  539. link_path, sizeof(link_path)-1);
  540. if (link_len > 0) {
  541. path = link_path + path.substr(root_pos);
  542. }
  543. }
  544. }
  545. LOG(INFO) << "Update location: " << path;
  546. // Map the update package into memory.
  547. ui->Print("Opening update package...\n");
  548. if (needs_mount) {
  549. if (path[0] == '@') {
  550. ensure_path_mounted(path.substr(1).c_str());
  551. } else {
  552. ensure_path_mounted(path.c_str());
  553. }
  554. }
  555. MemMapping map;
  556. if (!map.MapFile(path)) {
  557. LOG(ERROR) << "failed to map file";
  558. log_buffer->push_back(android::base::StringPrintf("error: %d", kMapFileFailure));
  559. return INSTALL_CORRUPT;
  560. }
  561. // Verify package.
  562. set_perf_mode(true);
  563. if (verify && !verify_package(map.addr, map.length)) {
  564. log_buffer->push_back(android::base::StringPrintf("error: %d", kZipVerificationFailure));
  565. set_perf_mode(false);
  566. return INSTALL_UNVERIFIED;
  567. }
  568. // Try to open the package.
  569. ZipArchiveHandle zip;
  570. int err = OpenArchiveFromMemory(map.addr, map.length, path.c_str(), &zip);
  571. if (err != 0) {
  572. LOG(ERROR) << "Can't open " << path << " : " << ErrorCodeString(err);
  573. log_buffer->push_back(android::base::StringPrintf("error: %d", kZipOpenFailure));
  574. CloseArchive(zip);
  575. set_perf_mode(false);
  576. return INSTALL_CORRUPT;
  577. }
  578. // Additionally verify the compatibility of the package.
  579. if (!verify_package_compatibility(zip)) {
  580. log_buffer->push_back(android::base::StringPrintf("error: %d", kPackageCompatibilityFailure));
  581. CloseArchive(zip);
  582. return INSTALL_CORRUPT;
  583. }
  584. // Verify and install the contents of the package.
  585. ui->Print("Installing update...\n");
  586. if (retry_count > 0) {
  587. ui->Print("Retry attempt: %d\n", retry_count);
  588. }
  589. ui->SetEnableReboot(false);
  590. int result = try_update_binary(path, zip, wipe_cache, log_buffer, retry_count, max_temperature);
  591. ui->SetEnableReboot(true);
  592. ui->Print("\n");
  593. CloseArchive(zip);
  594. set_perf_mode(false);
  595. return result;
  596. }
  597. int install_package(const std::string& path, bool* wipe_cache, const std::string& install_file,
  598. bool needs_mount, int retry_count, bool verify) {
  599. CHECK(!path.empty());
  600. CHECK(!install_file.empty());
  601. CHECK(wipe_cache != nullptr);
  602. modified_flash = true;
  603. auto start = std::chrono::system_clock::now();
  604. int start_temperature = GetMaxValueFromThermalZone();
  605. int max_temperature = start_temperature;
  606. int result;
  607. std::vector<std::string> log_buffer;
  608. if (setup_install_mounts() != 0) {
  609. LOG(ERROR) << "failed to set up expected mounts for install; aborting";
  610. result = INSTALL_ERROR;
  611. } else {
  612. result = really_install_package(path, wipe_cache, needs_mount, &log_buffer, retry_count,
  613. verify, &max_temperature);
  614. }
  615. // Measure the time spent to apply OTA update in seconds.
  616. std::chrono::duration<double> duration = std::chrono::system_clock::now() - start;
  617. int time_total = static_cast<int>(duration.count());
  618. bool has_cache = volume_for_mount_point("/cache") != nullptr;
  619. // Skip logging the uncrypt_status on devices without /cache.
  620. if (has_cache) {
  621. static constexpr const char* UNCRYPT_STATUS = "/cache/recovery/uncrypt_status";
  622. if (ensure_path_mounted(UNCRYPT_STATUS) != 0) {
  623. LOG(WARNING) << "Can't mount " << UNCRYPT_STATUS;
  624. } else {
  625. std::string uncrypt_status;
  626. if (!android::base::ReadFileToString(UNCRYPT_STATUS, &uncrypt_status)) {
  627. PLOG(WARNING) << "failed to read uncrypt status";
  628. } else if (!android::base::StartsWith(uncrypt_status, "uncrypt_")) {
  629. LOG(WARNING) << "corrupted uncrypt_status: " << uncrypt_status;
  630. } else {
  631. log_buffer.push_back(android::base::Trim(uncrypt_status));
  632. }
  633. }
  634. }
  635. // The first two lines need to be the package name and install result.
  636. std::vector<std::string> log_header = {
  637. path,
  638. result == INSTALL_SUCCESS ? "1" : "0",
  639. "time_total: " + std::to_string(time_total),
  640. "retry: " + std::to_string(retry_count),
  641. };
  642. int end_temperature = GetMaxValueFromThermalZone();
  643. max_temperature = std::max(end_temperature, max_temperature);
  644. if (start_temperature > 0) {
  645. log_buffer.push_back("temperature_start: " + std::to_string(start_temperature));
  646. }
  647. if (end_temperature > 0) {
  648. log_buffer.push_back("temperature_end: " + std::to_string(end_temperature));
  649. }
  650. if (max_temperature > 0) {
  651. log_buffer.push_back("temperature_max: " + std::to_string(max_temperature));
  652. }
  653. std::string log_content =
  654. android::base::Join(log_header, "\n") + "\n" + android::base::Join(log_buffer, "\n") + "\n";
  655. if (!android::base::WriteStringToFile(log_content, install_file)) {
  656. PLOG(ERROR) << "failed to write " << install_file;
  657. }
  658. // Write a copy into last_log.
  659. LOG(INFO) << log_content;
  660. return result;
  661. }
  662. bool verify_package(const unsigned char* package_data, size_t package_size) {
  663. static constexpr const char* PUBLIC_KEYS_FILE = "/res/keys";
  664. std::vector<Certificate> loadedKeys;
  665. if (!load_keys(PUBLIC_KEYS_FILE, loadedKeys)) {
  666. LOG(ERROR) << "Failed to load keys";
  667. return false;
  668. }
  669. LOG(INFO) << loadedKeys.size() << " key(s) loaded from " << PUBLIC_KEYS_FILE;
  670. // Verify package.
  671. ui->Print("Verifying update package...\n");
  672. auto t0 = std::chrono::system_clock::now();
  673. int err;
  674. // Because we mmap() the update file which is backed by FUSE, we get
  675. // SIGBUS when the host aborts the transfer. We handle this by using
  676. // setjmp/longjmp.
  677. signal(SIGBUS, sig_bus);
  678. if (setjmp(jb) == 0) {
  679. err = verify_file(package_data, package_size, loadedKeys,
  680. std::bind(&RecoveryUI::SetProgress, ui, std::placeholders::_1));
  681. std::chrono::duration<double> duration = std::chrono::system_clock::now() - t0;
  682. ui->Print("Update package verification took %.1f s (result %d).\n", duration.count(), err);
  683. } else {
  684. err = VERIFY_FAILURE;
  685. }
  686. signal(SIGBUS, SIG_DFL);
  687. if (err != VERIFY_SUCCESS) {
  688. LOG(ERROR) << "Signature verification failed";
  689. LOG(ERROR) << "error: " << kZipVerificationFailure;
  690. return false;
  691. }
  692. return true;
  693. }
  694. void
  695. set_perf_mode(bool enable) {
  696. property_set("recovery.perf.mode", enable ? "1" : "0");
  697. }