1/* 2 ** Copyright 2016, 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 17#include <algorithm> 18#include <inttypes.h> 19#include <limits> 20#include <random> 21#include <regex> 22#include <selinux/android.h> 23#include <selinux/avc.h> 24#include <stdlib.h> 25#include <string.h> 26#include <sys/capability.h> 27#include <sys/prctl.h> 28#include <sys/stat.h> 29#include <sys/wait.h> 30 31#include <android-base/logging.h> 32#include <android-base/macros.h> 33#include <android-base/stringprintf.h> 34#include <android-base/strings.h> 35#include <cutils/fs.h> 36#include <cutils/properties.h> 37#include <dex2oat_return_codes.h> 38#include <log/log.h> 39#include <private/android_filesystem_config.h> 40 41#include "dexopt.h" 42#include "file_parsing.h" 43#include "globals.h" 44#include "installd_constants.h" 45#include "installd_deps.h" // Need to fill in requirements of commands. 46#include "otapreopt_utils.h" 47#include "system_properties.h" 48#include "utils.h" 49 50#ifndef LOG_TAG 51#define LOG_TAG "otapreopt" 52#endif 53 54#define BUFFER_MAX 1024 /* input buffer for commands */ 55#define TOKEN_MAX 16 /* max number of arguments in buffer */ 56#define REPLY_MAX 256 /* largest reply allowed */ 57 58using android::base::EndsWith; 59using android::base::Join; 60using android::base::Split; 61using android::base::StartsWith; 62using android::base::StringPrintf; 63 64namespace android { 65namespace installd { 66 67// Check expected values for dexopt flags. If you need to change this: 68// 69// RUN AN A/B OTA TO MAKE SURE THINGS STILL WORK! 70// 71// You most likely need to increase the protocol version and all that entails! 72 73static_assert(DEXOPT_PUBLIC == 1 << 1, "DEXOPT_PUBLIC unexpected."); 74static_assert(DEXOPT_DEBUGGABLE == 1 << 2, "DEXOPT_DEBUGGABLE unexpected."); 75static_assert(DEXOPT_BOOTCOMPLETE == 1 << 3, "DEXOPT_BOOTCOMPLETE unexpected."); 76static_assert(DEXOPT_PROFILE_GUIDED == 1 << 4, "DEXOPT_PROFILE_GUIDED unexpected."); 77static_assert(DEXOPT_SECONDARY_DEX == 1 << 5, "DEXOPT_SECONDARY_DEX unexpected."); 78static_assert(DEXOPT_FORCE == 1 << 6, "DEXOPT_FORCE unexpected."); 79static_assert(DEXOPT_STORAGE_CE == 1 << 7, "DEXOPT_STORAGE_CE unexpected."); 80static_assert(DEXOPT_STORAGE_DE == 1 << 8, "DEXOPT_STORAGE_DE unexpected."); 81 82static_assert(DEXOPT_MASK == 0x1fe, "DEXOPT_MASK unexpected."); 83 84 85 86template<typename T> 87static constexpr T RoundDown(T x, typename std::decay<T>::type n) { 88 return DCHECK_CONSTEXPR(IsPowerOfTwo(n), , T(0))(x & -n); 89} 90 91template<typename T> 92static constexpr T RoundUp(T x, typename std::remove_reference<T>::type n) { 93 return RoundDown(x + n - 1, n); 94} 95 96class OTAPreoptService { 97 public: 98 // Main driver. Performs the following steps. 99 // 100 // 1) Parse options (read system properties etc from B partition). 101 // 102 // 2) Read in package data. 103 // 104 // 3) Prepare environment variables. 105 // 106 // 4) Prepare(compile) boot image, if necessary. 107 // 108 // 5) Run update. 109 int Main(int argc, char** argv) { 110 if (!ReadArguments(argc, argv)) { 111 LOG(ERROR) << "Failed reading command line."; 112 return 1; 113 } 114 115 if (!ReadSystemProperties()) { 116 LOG(ERROR)<< "Failed reading system properties."; 117 return 2; 118 } 119 120 if (!ReadEnvironment()) { 121 LOG(ERROR) << "Failed reading environment properties."; 122 return 3; 123 } 124 125 if (!CheckAndInitializeInstalldGlobals()) { 126 LOG(ERROR) << "Failed initializing globals."; 127 return 4; 128 } 129 130 PrepareEnvironment(); 131 132 if (!PrepareBootImage(/* force */ false)) { 133 LOG(ERROR) << "Failed preparing boot image."; 134 return 5; 135 } 136 137 int dexopt_retcode = RunPreopt(); 138 139 return dexopt_retcode; 140 } 141 142 int GetProperty(const char* key, char* value, const char* default_value) const { 143 const std::string* prop_value = system_properties_.GetProperty(key); 144 if (prop_value == nullptr) { 145 if (default_value == nullptr) { 146 return 0; 147 } 148 // Copy in the default value. 149 strncpy(value, default_value, kPropertyValueMax - 1); 150 value[kPropertyValueMax - 1] = 0; 151 return strlen(default_value);// TODO: Need to truncate? 152 } 153 size_t size = std::min(kPropertyValueMax - 1, prop_value->length()); 154 strncpy(value, prop_value->data(), size); 155 value[size] = 0; 156 return static_cast<int>(size); 157 } 158 159 std::string GetOTADataDirectory() const { 160 return StringPrintf("%s/%s", GetOtaDirectoryPrefix().c_str(), target_slot_.c_str()); 161 } 162 163 const std::string& GetTargetSlot() const { 164 return target_slot_; 165 } 166 167private: 168 169 struct Parameters { 170 const char *apk_path; 171 uid_t uid; 172 const char *pkgName; 173 const char *instruction_set; 174 int dexopt_needed; 175 const char* oat_dir; 176 int dexopt_flags; 177 const char* compiler_filter; 178 const char* volume_uuid; 179 const char* shared_libraries; 180 const char* se_info; 181 bool downgrade; 182 }; 183 184 bool ReadSystemProperties() { 185 static constexpr const char* kPropertyFiles[] = { 186 "/default.prop", "/system/build.prop" 187 }; 188 189 for (size_t i = 0; i < arraysize(kPropertyFiles); ++i) { 190 if (!system_properties_.Load(kPropertyFiles[i])) { 191 return false; 192 } 193 } 194 195 return true; 196 } 197 198 bool ReadEnvironment() { 199 // Parse the environment variables from init.environ.rc, which have the form 200 // export NAME VALUE 201 // For simplicity, don't respect string quotation. The values we are interested in can be 202 // encoded without them. 203 std::regex export_regex("\\s*export\\s+(\\S+)\\s+(\\S+)"); 204 bool parse_result = ParseFile("/init.environ.rc", [&](const std::string& line) { 205 std::smatch export_match; 206 if (!std::regex_match(line, export_match, export_regex)) { 207 return true; 208 } 209 210 if (export_match.size() != 3) { 211 return true; 212 } 213 214 std::string name = export_match[1].str(); 215 std::string value = export_match[2].str(); 216 217 system_properties_.SetProperty(name, value); 218 219 return true; 220 }); 221 if (!parse_result) { 222 return false; 223 } 224 225 if (system_properties_.GetProperty(kAndroidDataPathPropertyName) == nullptr) { 226 return false; 227 } 228 android_data_ = *system_properties_.GetProperty(kAndroidDataPathPropertyName); 229 230 if (system_properties_.GetProperty(kAndroidRootPathPropertyName) == nullptr) { 231 return false; 232 } 233 android_root_ = *system_properties_.GetProperty(kAndroidRootPathPropertyName); 234 235 if (system_properties_.GetProperty(kBootClassPathPropertyName) == nullptr) { 236 return false; 237 } 238 boot_classpath_ = *system_properties_.GetProperty(kBootClassPathPropertyName); 239 240 if (system_properties_.GetProperty(ASEC_MOUNTPOINT_ENV_NAME) == nullptr) { 241 return false; 242 } 243 asec_mountpoint_ = *system_properties_.GetProperty(ASEC_MOUNTPOINT_ENV_NAME); 244 245 return true; 246 } 247 248 const std::string& GetAndroidData() const { 249 return android_data_; 250 } 251 252 const std::string& GetAndroidRoot() const { 253 return android_root_; 254 } 255 256 const std::string GetOtaDirectoryPrefix() const { 257 return GetAndroidData() + "/ota"; 258 } 259 260 bool CheckAndInitializeInstalldGlobals() { 261 // init_globals_from_data_and_root requires "ASEC_MOUNTPOINT" in the environment. We 262 // do not use any datapath that includes this, but we'll still have to set it. 263 CHECK(system_properties_.GetProperty(ASEC_MOUNTPOINT_ENV_NAME) != nullptr); 264 int result = setenv(ASEC_MOUNTPOINT_ENV_NAME, asec_mountpoint_.c_str(), 0); 265 if (result != 0) { 266 LOG(ERROR) << "Could not set ASEC_MOUNTPOINT environment variable"; 267 return false; 268 } 269 270 if (!init_globals_from_data_and_root(GetAndroidData().c_str(), GetAndroidRoot().c_str())) { 271 LOG(ERROR) << "Could not initialize globals; exiting."; 272 return false; 273 } 274 275 // This is different from the normal installd. We only do the base 276 // directory, the rest will be created on demand when each app is compiled. 277 if (access(GetOtaDirectoryPrefix().c_str(), R_OK) < 0) { 278 LOG(ERROR) << "Could not access " << GetOtaDirectoryPrefix(); 279 return false; 280 } 281 282 return true; 283 } 284 285 bool ParseBool(const char* in) { 286 if (strcmp(in, "true") == 0) { 287 return true; 288 } 289 return false; 290 } 291 292 bool ParseUInt(const char* in, uint32_t* out) { 293 char* end; 294 long long int result = strtoll(in, &end, 0); 295 if (in == end || *end != '\0') { 296 return false; 297 } 298 if (result < std::numeric_limits<uint32_t>::min() || 299 std::numeric_limits<uint32_t>::max() < result) { 300 return false; 301 } 302 *out = static_cast<uint32_t>(result); 303 return true; 304 } 305 306 bool ReadArguments(int argc, char** argv) { 307 // Expected command line: 308 // target-slot [version] dexopt {DEXOPT_PARAMETERS} 309 310 const char* target_slot_arg = argv[1]; 311 if (target_slot_arg == nullptr) { 312 LOG(ERROR) << "Missing parameters"; 313 return false; 314 } 315 // Sanitize value. Only allow (a-zA-Z0-9_)+. 316 target_slot_ = target_slot_arg; 317 if (!ValidateTargetSlotSuffix(target_slot_)) { 318 LOG(ERROR) << "Target slot suffix not legal: " << target_slot_; 319 return false; 320 } 321 322 // Check for version or "dexopt" next. 323 if (argv[2] == nullptr) { 324 LOG(ERROR) << "Missing parameters"; 325 return false; 326 } 327 328 if (std::string("dexopt").compare(argv[2]) == 0) { 329 // This is version 1 (N) or pre-versioning version 2. 330 constexpr int kV2ArgCount = 1 // "otapreopt" 331 + 1 // slot 332 + 1 // "dexopt" 333 + 1 // apk_path 334 + 1 // uid 335 + 1 // pkg 336 + 1 // isa 337 + 1 // dexopt_needed 338 + 1 // oat_dir 339 + 1 // dexopt_flags 340 + 1 // filter 341 + 1 // volume 342 + 1 // libs 343 + 1; // seinfo 344 if (argc == kV2ArgCount) { 345 return ReadArgumentsV2(argc, argv, false); 346 } else { 347 return ReadArgumentsV1(argc, argv); 348 } 349 } 350 351 uint32_t version; 352 if (!ParseUInt(argv[2], &version)) { 353 LOG(ERROR) << "Could not parse version: " << argv[2]; 354 return false; 355 } 356 357 switch (version) { 358 case 2: 359 return ReadArgumentsV2(argc, argv, true); 360 case 3: 361 return ReadArgumentsV3(argc, argv); 362 363 default: 364 LOG(ERROR) << "Unsupported version " << version; 365 return false; 366 } 367 } 368 369 bool ReadArgumentsV2(int argc ATTRIBUTE_UNUSED, char** argv, bool versioned) { 370 size_t dexopt_index = versioned ? 3 : 2; 371 372 // Check for "dexopt". 373 if (argv[dexopt_index] == nullptr) { 374 LOG(ERROR) << "Missing parameters"; 375 return false; 376 } 377 if (std::string("dexopt").compare(argv[dexopt_index]) != 0) { 378 LOG(ERROR) << "Expected \"dexopt\""; 379 return false; 380 } 381 382 size_t param_index = 0; 383 for (;; ++param_index) { 384 const char* param = argv[dexopt_index + 1 + param_index]; 385 if (param == nullptr) { 386 break; 387 } 388 389 switch (param_index) { 390 case 0: 391 package_parameters_.apk_path = param; 392 break; 393 394 case 1: 395 package_parameters_.uid = atoi(param); 396 break; 397 398 case 2: 399 package_parameters_.pkgName = param; 400 break; 401 402 case 3: 403 package_parameters_.instruction_set = param; 404 break; 405 406 case 4: 407 package_parameters_.dexopt_needed = atoi(param); 408 break; 409 410 case 5: 411 package_parameters_.oat_dir = param; 412 break; 413 414 case 6: 415 package_parameters_.dexopt_flags = atoi(param); 416 break; 417 418 case 7: 419 package_parameters_.compiler_filter = param; 420 break; 421 422 case 8: 423 package_parameters_.volume_uuid = ParseNull(param); 424 break; 425 426 case 9: 427 package_parameters_.shared_libraries = ParseNull(param); 428 break; 429 430 case 10: 431 package_parameters_.se_info = ParseNull(param); 432 break; 433 434 default: 435 LOG(ERROR) << "Too many arguments, got " << param; 436 return false; 437 } 438 } 439 440 // Set downgrade to false. It is only relevant when downgrading compiler 441 // filter, which is not the case during ota. 442 package_parameters_.downgrade = false; 443 444 if (param_index != 11) { 445 LOG(ERROR) << "Not enough parameters"; 446 return false; 447 } 448 449 return true; 450 } 451 452 bool ReadArgumentsV3(int argc ATTRIBUTE_UNUSED, char** argv) { 453 size_t dexopt_index = 3; 454 455 // Check for "dexopt". 456 if (argv[dexopt_index] == nullptr) { 457 LOG(ERROR) << "Missing parameters"; 458 return false; 459 } 460 if (std::string("dexopt").compare(argv[dexopt_index]) != 0) { 461 LOG(ERROR) << "Expected \"dexopt\""; 462 return false; 463 } 464 465 size_t param_index = 0; 466 for (;; ++param_index) { 467 const char* param = argv[dexopt_index + 1 + param_index]; 468 if (param == nullptr) { 469 break; 470 } 471 472 switch (param_index) { 473 case 0: 474 package_parameters_.apk_path = param; 475 break; 476 477 case 1: 478 package_parameters_.uid = atoi(param); 479 break; 480 481 case 2: 482 package_parameters_.pkgName = param; 483 break; 484 485 case 3: 486 package_parameters_.instruction_set = param; 487 break; 488 489 case 4: 490 package_parameters_.dexopt_needed = atoi(param); 491 break; 492 493 case 5: 494 package_parameters_.oat_dir = param; 495 break; 496 497 case 6: 498 package_parameters_.dexopt_flags = atoi(param); 499 break; 500 501 case 7: 502 package_parameters_.compiler_filter = param; 503 break; 504 505 case 8: 506 package_parameters_.volume_uuid = ParseNull(param); 507 break; 508 509 case 9: 510 package_parameters_.shared_libraries = ParseNull(param); 511 break; 512 513 case 10: 514 package_parameters_.se_info = ParseNull(param); 515 break; 516 517 case 11: 518 package_parameters_.downgrade = ParseBool(param); 519 break; 520 521 default: 522 LOG(ERROR) << "Too many arguments, got " << param; 523 return false; 524 } 525 } 526 527 if (param_index != 12) { 528 LOG(ERROR) << "Not enough parameters"; 529 return false; 530 } 531 532 return true; 533 } 534 535 static int ReplaceMask(int input, int old_mask, int new_mask) { 536 return (input & old_mask) != 0 ? new_mask : 0; 537 } 538 539 bool ReadArgumentsV1(int argc ATTRIBUTE_UNUSED, char** argv) { 540 // Check for "dexopt". 541 if (argv[2] == nullptr) { 542 LOG(ERROR) << "Missing parameters"; 543 return false; 544 } 545 if (std::string("dexopt").compare(argv[2]) != 0) { 546 LOG(ERROR) << "Expected \"dexopt\""; 547 return false; 548 } 549 550 size_t param_index = 0; 551 for (;; ++param_index) { 552 const char* param = argv[3 + param_index]; 553 if (param == nullptr) { 554 break; 555 } 556 557 switch (param_index) { 558 case 0: 559 package_parameters_.apk_path = param; 560 break; 561 562 case 1: 563 package_parameters_.uid = atoi(param); 564 break; 565 566 case 2: 567 package_parameters_.pkgName = param; 568 break; 569 570 case 3: 571 package_parameters_.instruction_set = param; 572 break; 573 574 case 4: { 575 // Version 1 had: 576 // DEXOPT_DEX2OAT_NEEDED = 1 577 // DEXOPT_PATCHOAT_NEEDED = 2 578 // DEXOPT_SELF_PATCHOAT_NEEDED = 3 579 // We will simply use DEX2OAT_FROM_SCRATCH. 580 package_parameters_.dexopt_needed = DEX2OAT_FROM_SCRATCH; 581 break; 582 } 583 584 case 5: 585 package_parameters_.oat_dir = param; 586 break; 587 588 case 6: { 589 // Version 1 had: 590 constexpr int OLD_DEXOPT_PUBLIC = 1 << 1; 591 // Note: DEXOPT_SAFEMODE has been removed. 592 // constexpr int OLD_DEXOPT_SAFEMODE = 1 << 2; 593 constexpr int OLD_DEXOPT_DEBUGGABLE = 1 << 3; 594 constexpr int OLD_DEXOPT_BOOTCOMPLETE = 1 << 4; 595 constexpr int OLD_DEXOPT_PROFILE_GUIDED = 1 << 5; 596 constexpr int OLD_DEXOPT_OTA = 1 << 6; 597 int input = atoi(param); 598 package_parameters_.dexopt_flags = 599 ReplaceMask(input, OLD_DEXOPT_PUBLIC, DEXOPT_PUBLIC) | 600 ReplaceMask(input, OLD_DEXOPT_DEBUGGABLE, DEXOPT_DEBUGGABLE) | 601 ReplaceMask(input, OLD_DEXOPT_BOOTCOMPLETE, DEXOPT_BOOTCOMPLETE) | 602 ReplaceMask(input, OLD_DEXOPT_PROFILE_GUIDED, DEXOPT_PROFILE_GUIDED) | 603 ReplaceMask(input, OLD_DEXOPT_OTA, 0); 604 break; 605 } 606 607 case 7: 608 package_parameters_.compiler_filter = param; 609 break; 610 611 case 8: 612 package_parameters_.volume_uuid = ParseNull(param); 613 break; 614 615 case 9: 616 package_parameters_.shared_libraries = ParseNull(param); 617 break; 618 619 default: 620 LOG(ERROR) << "Too many arguments, got " << param; 621 return false; 622 } 623 } 624 625 if (param_index != 10) { 626 LOG(ERROR) << "Not enough parameters"; 627 return false; 628 } 629 630 // Set se_info to null. It is only relevant for secondary dex files, which we won't 631 // receive from a v1 A side. 632 package_parameters_.se_info = nullptr; 633 634 // Set downgrade to false. It is only relevant when downgrading compiler 635 // filter, which is not the case during ota. 636 package_parameters_.downgrade = false; 637 638 return true; 639 } 640 641 void PrepareEnvironment() { 642 environ_.push_back(StringPrintf("BOOTCLASSPATH=%s", boot_classpath_.c_str())); 643 environ_.push_back(StringPrintf("ANDROID_DATA=%s", GetOTADataDirectory().c_str())); 644 environ_.push_back(StringPrintf("ANDROID_ROOT=%s", android_root_.c_str())); 645 646 for (const std::string& e : environ_) { 647 putenv(const_cast<char*>(e.c_str())); 648 } 649 } 650 651 // Ensure that we have the right boot image. The first time any app is 652 // compiled, we'll try to generate it. 653 bool PrepareBootImage(bool force) const { 654 if (package_parameters_.instruction_set == nullptr) { 655 LOG(ERROR) << "Instruction set missing."; 656 return false; 657 } 658 const char* isa = package_parameters_.instruction_set; 659 660 // Check whether the file exists where expected. 661 std::string dalvik_cache = GetOTADataDirectory() + "/" + DALVIK_CACHE; 662 std::string isa_path = dalvik_cache + "/" + isa; 663 std::string art_path = isa_path + "/system@framework@boot.art"; 664 std::string oat_path = isa_path + "/system@framework@boot.oat"; 665 bool cleared = false; 666 if (access(art_path.c_str(), F_OK) == 0 && access(oat_path.c_str(), F_OK) == 0) { 667 // Files exist, assume everything is alright if not forced. Otherwise clean up. 668 if (!force) { 669 return true; 670 } 671 ClearDirectory(isa_path); 672 cleared = true; 673 } 674 675 // Reset umask in otapreopt, so that we control the the access for the files we create. 676 umask(0); 677 678 // Create the directories, if necessary. 679 if (access(dalvik_cache.c_str(), F_OK) != 0) { 680 if (!CreatePath(dalvik_cache)) { 681 PLOG(ERROR) << "Could not create dalvik-cache dir " << dalvik_cache; 682 return false; 683 } 684 } 685 if (access(isa_path.c_str(), F_OK) != 0) { 686 if (!CreatePath(isa_path)) { 687 PLOG(ERROR) << "Could not create dalvik-cache isa dir"; 688 return false; 689 } 690 } 691 692 // Prepare to create. 693 if (!cleared) { 694 ClearDirectory(isa_path); 695 } 696 697 std::string preopted_boot_art_path = StringPrintf("/system/framework/%s/boot.art", isa); 698 if (access(preopted_boot_art_path.c_str(), F_OK) == 0) { 699 return PatchoatBootImage(art_path, isa); 700 } else { 701 // No preopted boot image. Try to compile. 702 return Dex2oatBootImage(boot_classpath_, art_path, oat_path, isa); 703 } 704 } 705 706 static bool CreatePath(const std::string& path) { 707 // Create the given path. Use string processing instead of dirname, as dirname's need for 708 // a writable char buffer is painful. 709 710 // First, try to use the full path. 711 if (mkdir(path.c_str(), 0711) == 0) { 712 return true; 713 } 714 if (errno != ENOENT) { 715 PLOG(ERROR) << "Could not create path " << path; 716 return false; 717 } 718 719 // Now find the parent and try that first. 720 size_t last_slash = path.find_last_of('/'); 721 if (last_slash == std::string::npos || last_slash == 0) { 722 PLOG(ERROR) << "Could not create " << path; 723 return false; 724 } 725 726 if (!CreatePath(path.substr(0, last_slash))) { 727 return false; 728 } 729 730 if (mkdir(path.c_str(), 0711) == 0) { 731 return true; 732 } 733 PLOG(ERROR) << "Could not create " << path; 734 return false; 735 } 736 737 static void ClearDirectory(const std::string& dir) { 738 DIR* c_dir = opendir(dir.c_str()); 739 if (c_dir == nullptr) { 740 PLOG(WARNING) << "Unable to open " << dir << " to delete it's contents"; 741 return; 742 } 743 744 for (struct dirent* de = readdir(c_dir); de != nullptr; de = readdir(c_dir)) { 745 const char* name = de->d_name; 746 if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) { 747 continue; 748 } 749 // We only want to delete regular files and symbolic links. 750 std::string file = StringPrintf("%s/%s", dir.c_str(), name); 751 if (de->d_type != DT_REG && de->d_type != DT_LNK) { 752 LOG(WARNING) << "Unexpected file " 753 << file 754 << " of type " 755 << std::hex 756 << de->d_type 757 << " encountered."; 758 } else { 759 // Try to unlink the file. 760 if (unlink(file.c_str()) != 0) { 761 PLOG(ERROR) << "Unable to unlink " << file; 762 } 763 } 764 } 765 CHECK_EQ(0, closedir(c_dir)) << "Unable to close directory."; 766 } 767 768 bool PatchoatBootImage(const std::string& art_path, const char* isa) const { 769 // This needs to be kept in sync with ART, see art/runtime/gc/space/image_space.cc. 770 771 std::vector<std::string> cmd; 772 cmd.push_back("/system/bin/patchoat"); 773 774 cmd.push_back("--input-image-location=/system/framework/boot.art"); 775 cmd.push_back(StringPrintf("--output-image-file=%s", art_path.c_str())); 776 777 cmd.push_back(StringPrintf("--instruction-set=%s", isa)); 778 779 int32_t base_offset = ChooseRelocationOffsetDelta(ART_BASE_ADDRESS_MIN_DELTA, 780 ART_BASE_ADDRESS_MAX_DELTA); 781 cmd.push_back(StringPrintf("--base-offset-delta=%d", base_offset)); 782 783 std::string error_msg; 784 bool result = Exec(cmd, &error_msg); 785 if (!result) { 786 LOG(ERROR) << "Could not generate boot image: " << error_msg; 787 } 788 return result; 789 } 790 791 bool Dex2oatBootImage(const std::string& boot_cp, 792 const std::string& art_path, 793 const std::string& oat_path, 794 const char* isa) const { 795 // This needs to be kept in sync with ART, see art/runtime/gc/space/image_space.cc. 796 std::vector<std::string> cmd; 797 cmd.push_back("/system/bin/dex2oat"); 798 cmd.push_back(StringPrintf("--image=%s", art_path.c_str())); 799 for (const std::string& boot_part : Split(boot_cp, ":")) { 800 cmd.push_back(StringPrintf("--dex-file=%s", boot_part.c_str())); 801 } 802 cmd.push_back(StringPrintf("--oat-file=%s", oat_path.c_str())); 803 804 int32_t base_offset = ChooseRelocationOffsetDelta(ART_BASE_ADDRESS_MIN_DELTA, 805 ART_BASE_ADDRESS_MAX_DELTA); 806 cmd.push_back(StringPrintf("--base=0x%x", ART_BASE_ADDRESS + base_offset)); 807 808 cmd.push_back(StringPrintf("--instruction-set=%s", isa)); 809 810 // These things are pushed by AndroidRuntime, see frameworks/base/core/jni/AndroidRuntime.cpp. 811 AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-Xms", 812 "-Xms", 813 true, 814 cmd); 815 AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-Xmx", 816 "-Xmx", 817 true, 818 cmd); 819 AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-filter", 820 "--compiler-filter=", 821 false, 822 cmd); 823 cmd.push_back("--image-classes=/system/etc/preloaded-classes"); 824 // TODO: Compiled-classes. 825 const std::string* extra_opts = 826 system_properties_.GetProperty("dalvik.vm.image-dex2oat-flags"); 827 if (extra_opts != nullptr) { 828 std::vector<std::string> extra_vals = Split(*extra_opts, " "); 829 cmd.insert(cmd.end(), extra_vals.begin(), extra_vals.end()); 830 } 831 // TODO: Should we lower this? It's usually set close to max, because 832 // normally there's not much else going on at boot. 833 AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-threads", 834 "-j", 835 false, 836 cmd); 837 AddCompilerOptionFromSystemProperty( 838 StringPrintf("dalvik.vm.isa.%s.variant", isa).c_str(), 839 "--instruction-set-variant=", 840 false, 841 cmd); 842 AddCompilerOptionFromSystemProperty( 843 StringPrintf("dalvik.vm.isa.%s.features", isa).c_str(), 844 "--instruction-set-features=", 845 false, 846 cmd); 847 848 std::string error_msg; 849 bool result = Exec(cmd, &error_msg); 850 if (!result) { 851 LOG(ERROR) << "Could not generate boot image: " << error_msg; 852 } 853 return result; 854 } 855 856 static const char* ParseNull(const char* arg) { 857 return (strcmp(arg, "!") == 0) ? nullptr : arg; 858 } 859 860 bool ShouldSkipPreopt() const { 861 // There's one thing we have to be careful about: we may/will be asked to compile an app 862 // living in the system image. This may be a valid request - if the app wasn't compiled, 863 // e.g., if the system image wasn't large enough to include preopted files. However, the 864 // data we have is from the old system, so the driver (the OTA service) can't actually 865 // know. Thus, we will get requests for apps that have preopted components. To avoid 866 // duplication (we'd generate files that are not used and are *not* cleaned up), do two 867 // simple checks: 868 // 869 // 1) Does the apk_path start with the value of ANDROID_ROOT? (~in the system image) 870 // (For simplicity, assume the value of ANDROID_ROOT does not contain a symlink.) 871 // 872 // 2) If you replace the name in the apk_path with "oat," does the path exist? 873 // (=have a subdirectory for preopted files) 874 // 875 // If the answer to both is yes, skip the dexopt. 876 // 877 // Note: while one may think it's OK to call dexopt and it will fail (because APKs should 878 // be stripped), that's not true for APKs signed outside the build system (so the 879 // jar content must be exactly the same). 880 881 // (This is ugly as it's the only thing where we need to understand the contents 882 // of package_parameters_, but it beats postponing the decision or using the call- 883 // backs to do weird things.) 884 const char* apk_path = package_parameters_.apk_path; 885 CHECK(apk_path != nullptr); 886 if (StartsWith(apk_path, android_root_.c_str())) { 887 const char* last_slash = strrchr(apk_path, '/'); 888 if (last_slash != nullptr) { 889 std::string path(apk_path, last_slash - apk_path + 1); 890 CHECK(EndsWith(path, "/")); 891 path = path + "oat"; 892 if (access(path.c_str(), F_OK) == 0) { 893 return true; 894 } 895 } 896 } 897 898 // Another issue is unavailability of files in the new system. If the partition 899 // layout changes, otapreopt_chroot may not know about this. Then files from that 900 // partition will not be available and fail to build. This is problematic, as 901 // this tool will wipe the OTA artifact cache and try again (for robustness after 902 // a failed OTA with remaining cache artifacts). 903 if (access(apk_path, F_OK) != 0) { 904 LOG(WARNING) << "Skipping preopt of non-existing package " << apk_path; 905 return true; 906 } 907 908 return false; 909 } 910 911 // Run dexopt with the parameters of package_parameters_. 912 int Dexopt() { 913 return dexopt(package_parameters_.apk_path, 914 package_parameters_.uid, 915 package_parameters_.pkgName, 916 package_parameters_.instruction_set, 917 package_parameters_.dexopt_needed, 918 package_parameters_.oat_dir, 919 package_parameters_.dexopt_flags, 920 package_parameters_.compiler_filter, 921 package_parameters_.volume_uuid, 922 package_parameters_.shared_libraries, 923 package_parameters_.se_info, 924 package_parameters_.downgrade); 925 } 926 927 int RunPreopt() { 928 if (ShouldSkipPreopt()) { 929 return 0; 930 } 931 932 int dexopt_result = Dexopt(); 933 if (dexopt_result == 0) { 934 return 0; 935 } 936 937 // If the dexopt failed, we may have a stale boot image from a previous OTA run. 938 // Then regenerate and retry. 939 if (WEXITSTATUS(dexopt_result) == 940 static_cast<int>(art::dex2oat::ReturnCode::kCreateRuntime)) { 941 if (!PrepareBootImage(/* force */ true)) { 942 LOG(ERROR) << "Forced boot image creating failed. Original error return was " 943 << dexopt_result; 944 return dexopt_result; 945 } 946 947 int dexopt_result_boot_image_retry = Dexopt(); 948 if (dexopt_result_boot_image_retry == 0) { 949 return 0; 950 } 951 } 952 953 // If this was a profile-guided run, we may have profile version issues. Try to downgrade, 954 // if possible. 955 if ((package_parameters_.dexopt_flags & DEXOPT_PROFILE_GUIDED) == 0) { 956 return dexopt_result; 957 } 958 959 LOG(WARNING) << "Downgrading compiler filter in an attempt to progress compilation"; 960 package_parameters_.dexopt_flags &= ~DEXOPT_PROFILE_GUIDED; 961 return Dexopt(); 962 } 963 964 //////////////////////////////////// 965 // Helpers, mostly taken from ART // 966 //////////////////////////////////// 967 968 // Wrapper on fork/execv to run a command in a subprocess. 969 static bool Exec(const std::vector<std::string>& arg_vector, std::string* error_msg) { 970 const std::string command_line = Join(arg_vector, ' '); 971 972 CHECK_GE(arg_vector.size(), 1U) << command_line; 973 974 // Convert the args to char pointers. 975 const char* program = arg_vector[0].c_str(); 976 std::vector<char*> args; 977 for (size_t i = 0; i < arg_vector.size(); ++i) { 978 const std::string& arg = arg_vector[i]; 979 char* arg_str = const_cast<char*>(arg.c_str()); 980 CHECK(arg_str != nullptr) << i; 981 args.push_back(arg_str); 982 } 983 args.push_back(nullptr); 984 985 // Fork and exec. 986 pid_t pid = fork(); 987 if (pid == 0) { 988 // No allocation allowed between fork and exec. 989 990 // Change process groups, so we don't get reaped by ProcessManager. 991 setpgid(0, 0); 992 993 execv(program, &args[0]); 994 995 PLOG(ERROR) << "Failed to execv(" << command_line << ")"; 996 // _exit to avoid atexit handlers in child. 997 _exit(1); 998 } else { 999 if (pid == -1) { 1000 *error_msg = StringPrintf("Failed to execv(%s) because fork failed: %s", 1001 command_line.c_str(), strerror(errno)); 1002 return false; 1003 } 1004 1005 // wait for subprocess to finish 1006 int status; 1007 pid_t got_pid = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0)); 1008 if (got_pid != pid) { 1009 *error_msg = StringPrintf("Failed after fork for execv(%s) because waitpid failed: " 1010 "wanted %d, got %d: %s", 1011 command_line.c_str(), pid, got_pid, strerror(errno)); 1012 return false; 1013 } 1014 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { 1015 *error_msg = StringPrintf("Failed execv(%s) because non-0 exit status", 1016 command_line.c_str()); 1017 return false; 1018 } 1019 } 1020 return true; 1021 } 1022 1023 // Choose a random relocation offset. Taken from art/runtime/gc/image_space.cc. 1024 static int32_t ChooseRelocationOffsetDelta(int32_t min_delta, int32_t max_delta) { 1025 constexpr size_t kPageSize = PAGE_SIZE; 1026 CHECK_EQ(min_delta % kPageSize, 0u); 1027 CHECK_EQ(max_delta % kPageSize, 0u); 1028 CHECK_LT(min_delta, max_delta); 1029 1030 std::default_random_engine generator; 1031 generator.seed(GetSeed()); 1032 std::uniform_int_distribution<int32_t> distribution(min_delta, max_delta); 1033 int32_t r = distribution(generator); 1034 if (r % 2 == 0) { 1035 r = RoundUp(r, kPageSize); 1036 } else { 1037 r = RoundDown(r, kPageSize); 1038 } 1039 CHECK_LE(min_delta, r); 1040 CHECK_GE(max_delta, r); 1041 CHECK_EQ(r % kPageSize, 0u); 1042 return r; 1043 } 1044 1045 static uint64_t GetSeed() { 1046#ifdef __BIONIC__ 1047 // Bionic exposes arc4random, use it. 1048 uint64_t random_data; 1049 arc4random_buf(&random_data, sizeof(random_data)); 1050 return random_data; 1051#else 1052#error "This is only supposed to run with bionic. Otherwise, implement..." 1053#endif 1054 } 1055 1056 void AddCompilerOptionFromSystemProperty(const char* system_property, 1057 const char* prefix, 1058 bool runtime, 1059 std::vector<std::string>& out) const { 1060 const std::string* value = system_properties_.GetProperty(system_property); 1061 if (value != nullptr) { 1062 if (runtime) { 1063 out.push_back("--runtime-arg"); 1064 } 1065 if (prefix != nullptr) { 1066 out.push_back(StringPrintf("%s%s", prefix, value->c_str())); 1067 } else { 1068 out.push_back(*value); 1069 } 1070 } 1071 } 1072 1073 static constexpr const char* kBootClassPathPropertyName = "BOOTCLASSPATH"; 1074 static constexpr const char* kAndroidRootPathPropertyName = "ANDROID_ROOT"; 1075 static constexpr const char* kAndroidDataPathPropertyName = "ANDROID_DATA"; 1076 // The index of the instruction-set string inside the package parameters. Needed for 1077 // some special-casing that requires knowledge of the instruction-set. 1078 static constexpr size_t kISAIndex = 3; 1079 1080 // Stores the system properties read out of the B partition. We need to use these properties 1081 // to compile, instead of the A properties we could get from init/get_property. 1082 SystemProperties system_properties_; 1083 1084 // Some select properties that are always needed. 1085 std::string target_slot_; 1086 std::string android_root_; 1087 std::string android_data_; 1088 std::string boot_classpath_; 1089 std::string asec_mountpoint_; 1090 1091 Parameters package_parameters_; 1092 1093 // Store environment values we need to set. 1094 std::vector<std::string> environ_; 1095}; 1096 1097OTAPreoptService gOps; 1098 1099//////////////////////// 1100// Plug-in functions. // 1101//////////////////////// 1102 1103int get_property(const char *key, char *value, const char *default_value) { 1104 return gOps.GetProperty(key, value, default_value); 1105} 1106 1107// Compute the output path of 1108bool calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir, 1109 const char *apk_path, 1110 const char *instruction_set) { 1111 const char *file_name_start; 1112 const char *file_name_end; 1113 1114 file_name_start = strrchr(apk_path, '/'); 1115 if (file_name_start == nullptr) { 1116 ALOGE("apk_path '%s' has no '/'s in it\n", apk_path); 1117 return false; 1118 } 1119 file_name_end = strrchr(file_name_start, '.'); 1120 if (file_name_end == nullptr) { 1121 ALOGE("apk_path '%s' has no extension\n", apk_path); 1122 return false; 1123 } 1124 1125 // Calculate file_name 1126 file_name_start++; // Move past '/', is valid as file_name_end is valid. 1127 size_t file_name_len = file_name_end - file_name_start; 1128 std::string file_name(file_name_start, file_name_len); 1129 1130 // <apk_parent_dir>/oat/<isa>/<file_name>.odex.b 1131 snprintf(path, 1132 PKG_PATH_MAX, 1133 "%s/%s/%s.odex.%s", 1134 oat_dir, 1135 instruction_set, 1136 file_name.c_str(), 1137 gOps.GetTargetSlot().c_str()); 1138 return true; 1139} 1140 1141/* 1142 * Computes the odex file for the given apk_path and instruction_set. 1143 * /system/framework/whatever.jar -> /system/framework/oat/<isa>/whatever.odex 1144 * 1145 * Returns false if it failed to determine the odex file path. 1146 */ 1147bool calculate_odex_file_path(char path[PKG_PATH_MAX], const char *apk_path, 1148 const char *instruction_set) { 1149 const char *path_end = strrchr(apk_path, '/'); 1150 if (path_end == nullptr) { 1151 ALOGE("apk_path '%s' has no '/'s in it?!\n", apk_path); 1152 return false; 1153 } 1154 std::string path_component(apk_path, path_end - apk_path); 1155 1156 const char *name_begin = path_end + 1; 1157 const char *extension_start = strrchr(name_begin, '.'); 1158 if (extension_start == nullptr) { 1159 ALOGE("apk_path '%s' has no extension.\n", apk_path); 1160 return false; 1161 } 1162 std::string name_component(name_begin, extension_start - name_begin); 1163 1164 std::string new_path = StringPrintf("%s/oat/%s/%s.odex.%s", 1165 path_component.c_str(), 1166 instruction_set, 1167 name_component.c_str(), 1168 gOps.GetTargetSlot().c_str()); 1169 if (new_path.length() >= PKG_PATH_MAX) { 1170 LOG(ERROR) << "apk_path of " << apk_path << " is too long: " << new_path; 1171 return false; 1172 } 1173 strcpy(path, new_path.c_str()); 1174 return true; 1175} 1176 1177bool create_cache_path(char path[PKG_PATH_MAX], 1178 const char *src, 1179 const char *instruction_set) { 1180 size_t srclen = strlen(src); 1181 1182 /* demand that we are an absolute path */ 1183 if ((src == 0) || (src[0] != '/') || strstr(src,"..")) { 1184 return false; 1185 } 1186 1187 if (srclen > PKG_PATH_MAX) { // XXX: PKG_NAME_MAX? 1188 return false; 1189 } 1190 1191 std::string from_src = std::string(src + 1); 1192 std::replace(from_src.begin(), from_src.end(), '/', '@'); 1193 1194 std::string assembled_path = StringPrintf("%s/%s/%s/%s%s", 1195 gOps.GetOTADataDirectory().c_str(), 1196 DALVIK_CACHE, 1197 instruction_set, 1198 from_src.c_str(), 1199 DALVIK_CACHE_POSTFIX); 1200 1201 if (assembled_path.length() + 1 > PKG_PATH_MAX) { 1202 return false; 1203 } 1204 strcpy(path, assembled_path.c_str()); 1205 1206 return true; 1207} 1208 1209static int log_callback(int type, const char *fmt, ...) { 1210 va_list ap; 1211 int priority; 1212 1213 switch (type) { 1214 case SELINUX_WARNING: 1215 priority = ANDROID_LOG_WARN; 1216 break; 1217 case SELINUX_INFO: 1218 priority = ANDROID_LOG_INFO; 1219 break; 1220 default: 1221 priority = ANDROID_LOG_ERROR; 1222 break; 1223 } 1224 va_start(ap, fmt); 1225 LOG_PRI_VA(priority, "SELinux", fmt, ap); 1226 va_end(ap); 1227 return 0; 1228} 1229 1230static int otapreopt_main(const int argc, char *argv[]) { 1231 int selinux_enabled = (is_selinux_enabled() > 0); 1232 1233 setenv("ANDROID_LOG_TAGS", "*:v", 1); 1234 android::base::InitLogging(argv); 1235 1236 if (argc < 2) { 1237 ALOGE("Expecting parameters"); 1238 exit(1); 1239 } 1240 1241 union selinux_callback cb; 1242 cb.func_log = log_callback; 1243 selinux_set_callback(SELINUX_CB_LOG, cb); 1244 1245 if (selinux_enabled && selinux_status_open(true) < 0) { 1246 ALOGE("Could not open selinux status; exiting.\n"); 1247 exit(1); 1248 } 1249 1250 int ret = android::installd::gOps.Main(argc, argv); 1251 1252 return ret; 1253} 1254 1255} // namespace installd 1256} // namespace android 1257 1258int main(const int argc, char *argv[]) { 1259 return android::installd::otapreopt_main(argc, argv); 1260} 1261