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