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 <random> 20 #include <regex> 21 #include <selinux/android.h> 22 #include <selinux/avc.h> 23 #include <stdlib.h> 24 #include <string.h> 25 #include <sys/capability.h> 26 #include <sys/prctl.h> 27 #include <sys/stat.h> 28 #include <sys/wait.h> 29 30 #include <android-base/logging.h> 31 #include <android-base/macros.h> 32 #include <android-base/stringprintf.h> 33 #include <android-base/strings.h> 34 #include <cutils/fs.h> 35 #include <cutils/log.h> 36 #include <cutils/properties.h> 37 #include <private/android_filesystem_config.h> 38 39 #include <commands.h> 40 #include <file_parsing.h> 41 #include <globals.h> 42 #include <installd_deps.h> // Need to fill in requirements of commands. 43 #include <otapreopt_utils.h> 44 #include <system_properties.h> 45 #include <utils.h> 46 47 #ifndef LOG_TAG 48 #define LOG_TAG "otapreopt" 49 #endif 50 51 #define BUFFER_MAX 1024 /* input buffer for commands */ 52 #define TOKEN_MAX 16 /* max number of arguments in buffer */ 53 #define REPLY_MAX 256 /* largest reply allowed */ 54 55 using android::base::EndsWith; 56 using android::base::Join; 57 using android::base::Split; 58 using android::base::StartsWith; 59 using android::base::StringPrintf; 60 61 namespace android { 62 namespace installd { 63 64 template<typename T> 65 static constexpr T RoundDown(T x, typename std::decay<T>::type n) { 66 return DCHECK_CONSTEXPR(IsPowerOfTwo(n), , T(0))(x & -n); 67 } 68 69 template<typename T> 70 static constexpr T RoundUp(T x, typename std::remove_reference<T>::type n) { 71 return RoundDown(x + n - 1, n); 72 } 73 74 class OTAPreoptService { 75 public: 76 // Main driver. Performs the following steps. 77 // 78 // 1) Parse options (read system properties etc from B partition). 79 // 80 // 2) Read in package data. 81 // 82 // 3) Prepare environment variables. 83 // 84 // 4) Prepare(compile) boot image, if necessary. 85 // 86 // 5) Run update. 87 int Main(int argc, char** argv) { 88 if (!ReadArguments(argc, argv)) { 89 LOG(ERROR) << "Failed reading command line."; 90 return 1; 91 } 92 93 if (!ReadSystemProperties()) { 94 LOG(ERROR)<< "Failed reading system properties."; 95 return 2; 96 } 97 98 if (!ReadEnvironment()) { 99 LOG(ERROR) << "Failed reading environment properties."; 100 return 3; 101 } 102 103 if (!CheckAndInitializeInstalldGlobals()) { 104 LOG(ERROR) << "Failed initializing globals."; 105 return 4; 106 } 107 108 PrepareEnvironment(); 109 110 if (!PrepareBootImage(/* force */ false)) { 111 LOG(ERROR) << "Failed preparing boot image."; 112 return 5; 113 } 114 115 int dexopt_retcode = RunPreopt(); 116 117 return dexopt_retcode; 118 } 119 120 int GetProperty(const char* key, char* value, const char* default_value) const { 121 const std::string* prop_value = system_properties_.GetProperty(key); 122 if (prop_value == nullptr) { 123 if (default_value == nullptr) { 124 return 0; 125 } 126 // Copy in the default value. 127 strncpy(value, default_value, kPropertyValueMax - 1); 128 value[kPropertyValueMax - 1] = 0; 129 return strlen(default_value);// TODO: Need to truncate? 130 } 131 size_t size = std::min(kPropertyValueMax - 1, prop_value->length()); 132 strncpy(value, prop_value->data(), size); 133 value[size] = 0; 134 return static_cast<int>(size); 135 } 136 137 std::string GetOTADataDirectory() const { 138 return StringPrintf("%s/%s", GetOtaDirectoryPrefix().c_str(), target_slot_.c_str()); 139 } 140 141 const std::string& GetTargetSlot() const { 142 return target_slot_; 143 } 144 145 private: 146 147 bool ReadSystemProperties() { 148 static constexpr const char* kPropertyFiles[] = { 149 "/default.prop", "/system/build.prop" 150 }; 151 152 for (size_t i = 0; i < arraysize(kPropertyFiles); ++i) { 153 if (!system_properties_.Load(kPropertyFiles[i])) { 154 return false; 155 } 156 } 157 158 return true; 159 } 160 161 bool ReadEnvironment() { 162 // Parse the environment variables from init.environ.rc, which have the form 163 // export NAME VALUE 164 // For simplicity, don't respect string quotation. The values we are interested in can be 165 // encoded without them. 166 std::regex export_regex("\\s*export\\s+(\\S+)\\s+(\\S+)"); 167 bool parse_result = ParseFile("/init.environ.rc", [&](const std::string& line) { 168 std::smatch export_match; 169 if (!std::regex_match(line, export_match, export_regex)) { 170 return true; 171 } 172 173 if (export_match.size() != 3) { 174 return true; 175 } 176 177 std::string name = export_match[1].str(); 178 std::string value = export_match[2].str(); 179 180 system_properties_.SetProperty(name, value); 181 182 return true; 183 }); 184 if (!parse_result) { 185 return false; 186 } 187 188 if (system_properties_.GetProperty(kAndroidDataPathPropertyName) == nullptr) { 189 return false; 190 } 191 android_data_ = *system_properties_.GetProperty(kAndroidDataPathPropertyName); 192 193 if (system_properties_.GetProperty(kAndroidRootPathPropertyName) == nullptr) { 194 return false; 195 } 196 android_root_ = *system_properties_.GetProperty(kAndroidRootPathPropertyName); 197 198 if (system_properties_.GetProperty(kBootClassPathPropertyName) == nullptr) { 199 return false; 200 } 201 boot_classpath_ = *system_properties_.GetProperty(kBootClassPathPropertyName); 202 203 if (system_properties_.GetProperty(ASEC_MOUNTPOINT_ENV_NAME) == nullptr) { 204 return false; 205 } 206 asec_mountpoint_ = *system_properties_.GetProperty(ASEC_MOUNTPOINT_ENV_NAME); 207 208 return true; 209 } 210 211 const std::string& GetAndroidData() const { 212 return android_data_; 213 } 214 215 const std::string& GetAndroidRoot() const { 216 return android_root_; 217 } 218 219 const std::string GetOtaDirectoryPrefix() const { 220 return GetAndroidData() + "/ota"; 221 } 222 223 bool CheckAndInitializeInstalldGlobals() { 224 // init_globals_from_data_and_root requires "ASEC_MOUNTPOINT" in the environment. We 225 // do not use any datapath that includes this, but we'll still have to set it. 226 CHECK(system_properties_.GetProperty(ASEC_MOUNTPOINT_ENV_NAME) != nullptr); 227 int result = setenv(ASEC_MOUNTPOINT_ENV_NAME, asec_mountpoint_.c_str(), 0); 228 if (result != 0) { 229 LOG(ERROR) << "Could not set ASEC_MOUNTPOINT environment variable"; 230 return false; 231 } 232 233 if (!init_globals_from_data_and_root(GetAndroidData().c_str(), GetAndroidRoot().c_str())) { 234 LOG(ERROR) << "Could not initialize globals; exiting."; 235 return false; 236 } 237 238 // This is different from the normal installd. We only do the base 239 // directory, the rest will be created on demand when each app is compiled. 240 if (access(GetOtaDirectoryPrefix().c_str(), R_OK) < 0) { 241 LOG(ERROR) << "Could not access " << GetOtaDirectoryPrefix(); 242 return false; 243 } 244 245 return true; 246 } 247 248 bool ReadArguments(int argc ATTRIBUTE_UNUSED, char** argv) { 249 // Expected command line: 250 // target-slot dexopt {DEXOPT_PARAMETERS} 251 // The DEXOPT_PARAMETERS are passed on to dexopt(), so we expect DEXOPT_PARAM_COUNT 252 // of them. We store them in package_parameters_ (size checks are done when 253 // parsing the special parameters and when copying into package_parameters_. 254 255 static_assert(DEXOPT_PARAM_COUNT == ARRAY_SIZE(package_parameters_), 256 "Unexpected dexopt param count"); 257 258 const char* target_slot_arg = argv[1]; 259 if (target_slot_arg == nullptr) { 260 LOG(ERROR) << "Missing parameters"; 261 return false; 262 } 263 // Sanitize value. Only allow (a-zA-Z0-9_)+. 264 target_slot_ = target_slot_arg; 265 if (!ValidateTargetSlotSuffix(target_slot_)) { 266 LOG(ERROR) << "Target slot suffix not legal: " << target_slot_; 267 return false; 268 } 269 270 // Check for "dexopt" next. 271 if (argv[2] == nullptr) { 272 LOG(ERROR) << "Missing parameters"; 273 return false; 274 } 275 if (std::string("dexopt").compare(argv[2]) != 0) { 276 LOG(ERROR) << "Second parameter not dexopt: " << argv[2]; 277 return false; 278 } 279 280 // Copy the rest into package_parameters_, but be careful about over- and underflow. 281 size_t index = 0; 282 while (index < DEXOPT_PARAM_COUNT && 283 argv[index + 3] != nullptr) { 284 package_parameters_[index] = argv[index + 3]; 285 index++; 286 } 287 if (index != ARRAY_SIZE(package_parameters_) || argv[index + 3] != nullptr) { 288 LOG(ERROR) << "Wrong number of parameters"; 289 return false; 290 } 291 292 return true; 293 } 294 295 void PrepareEnvironment() { 296 environ_.push_back(StringPrintf("BOOTCLASSPATH=%s", boot_classpath_.c_str())); 297 environ_.push_back(StringPrintf("ANDROID_DATA=%s", GetOTADataDirectory().c_str())); 298 environ_.push_back(StringPrintf("ANDROID_ROOT=%s", android_root_.c_str())); 299 300 for (const std::string& e : environ_) { 301 putenv(const_cast<char*>(e.c_str())); 302 } 303 } 304 305 // Ensure that we have the right boot image. The first time any app is 306 // compiled, we'll try to generate it. 307 bool PrepareBootImage(bool force) const { 308 if (package_parameters_[kISAIndex] == nullptr) { 309 LOG(ERROR) << "Instruction set missing."; 310 return false; 311 } 312 const char* isa = package_parameters_[kISAIndex]; 313 314 // Check whether the file exists where expected. 315 std::string dalvik_cache = GetOTADataDirectory() + "/" + DALVIK_CACHE; 316 std::string isa_path = dalvik_cache + "/" + isa; 317 std::string art_path = isa_path + "/system@framework (at) boot.art"; 318 std::string oat_path = isa_path + "/system@framework (at) boot.oat"; 319 bool cleared = false; 320 if (access(art_path.c_str(), F_OK) == 0 && access(oat_path.c_str(), F_OK) == 0) { 321 // Files exist, assume everything is alright if not forced. Otherwise clean up. 322 if (!force) { 323 return true; 324 } 325 ClearDirectory(isa_path); 326 cleared = true; 327 } 328 329 // Reset umask in otapreopt, so that we control the the access for the files we create. 330 umask(0); 331 332 // Create the directories, if necessary. 333 if (access(dalvik_cache.c_str(), F_OK) != 0) { 334 if (!CreatePath(dalvik_cache)) { 335 PLOG(ERROR) << "Could not create dalvik-cache dir " << dalvik_cache; 336 return false; 337 } 338 } 339 if (access(isa_path.c_str(), F_OK) != 0) { 340 if (!CreatePath(isa_path)) { 341 PLOG(ERROR) << "Could not create dalvik-cache isa dir"; 342 return false; 343 } 344 } 345 346 // Prepare to create. 347 if (!cleared) { 348 ClearDirectory(isa_path); 349 } 350 351 std::string preopted_boot_art_path = StringPrintf("/system/framework/%s/boot.art", isa); 352 if (access(preopted_boot_art_path.c_str(), F_OK) == 0) { 353 return PatchoatBootImage(art_path, isa); 354 } else { 355 // No preopted boot image. Try to compile. 356 return Dex2oatBootImage(boot_classpath_, art_path, oat_path, isa); 357 } 358 } 359 360 static bool CreatePath(const std::string& path) { 361 // Create the given path. Use string processing instead of dirname, as dirname's need for 362 // a writable char buffer is painful. 363 364 // First, try to use the full path. 365 if (mkdir(path.c_str(), 0711) == 0) { 366 return true; 367 } 368 if (errno != ENOENT) { 369 PLOG(ERROR) << "Could not create path " << path; 370 return false; 371 } 372 373 // Now find the parent and try that first. 374 size_t last_slash = path.find_last_of('/'); 375 if (last_slash == std::string::npos || last_slash == 0) { 376 PLOG(ERROR) << "Could not create " << path; 377 return false; 378 } 379 380 if (!CreatePath(path.substr(0, last_slash))) { 381 return false; 382 } 383 384 if (mkdir(path.c_str(), 0711) == 0) { 385 return true; 386 } 387 PLOG(ERROR) << "Could not create " << path; 388 return false; 389 } 390 391 static void ClearDirectory(const std::string& dir) { 392 DIR* c_dir = opendir(dir.c_str()); 393 if (c_dir == nullptr) { 394 PLOG(WARNING) << "Unable to open " << dir << " to delete it's contents"; 395 return; 396 } 397 398 for (struct dirent* de = readdir(c_dir); de != nullptr; de = readdir(c_dir)) { 399 const char* name = de->d_name; 400 if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) { 401 continue; 402 } 403 // We only want to delete regular files and symbolic links. 404 std::string file = StringPrintf("%s/%s", dir.c_str(), name); 405 if (de->d_type != DT_REG && de->d_type != DT_LNK) { 406 LOG(WARNING) << "Unexpected file " 407 << file 408 << " of type " 409 << std::hex 410 << de->d_type 411 << " encountered."; 412 } else { 413 // Try to unlink the file. 414 if (unlink(file.c_str()) != 0) { 415 PLOG(ERROR) << "Unable to unlink " << file; 416 } 417 } 418 } 419 CHECK_EQ(0, closedir(c_dir)) << "Unable to close directory."; 420 } 421 422 bool PatchoatBootImage(const std::string& art_path, const char* isa) const { 423 // This needs to be kept in sync with ART, see art/runtime/gc/space/image_space.cc. 424 425 std::vector<std::string> cmd; 426 cmd.push_back("/system/bin/patchoat"); 427 428 cmd.push_back("--input-image-location=/system/framework/boot.art"); 429 cmd.push_back(StringPrintf("--output-image-file=%s", art_path.c_str())); 430 431 cmd.push_back(StringPrintf("--instruction-set=%s", isa)); 432 433 int32_t base_offset = ChooseRelocationOffsetDelta(ART_BASE_ADDRESS_MIN_DELTA, 434 ART_BASE_ADDRESS_MAX_DELTA); 435 cmd.push_back(StringPrintf("--base-offset-delta=%d", base_offset)); 436 437 std::string error_msg; 438 bool result = Exec(cmd, &error_msg); 439 if (!result) { 440 LOG(ERROR) << "Could not generate boot image: " << error_msg; 441 } 442 return result; 443 } 444 445 bool Dex2oatBootImage(const std::string& boot_cp, 446 const std::string& art_path, 447 const std::string& oat_path, 448 const char* isa) const { 449 // This needs to be kept in sync with ART, see art/runtime/gc/space/image_space.cc. 450 std::vector<std::string> cmd; 451 cmd.push_back("/system/bin/dex2oat"); 452 cmd.push_back(StringPrintf("--image=%s", art_path.c_str())); 453 for (const std::string& boot_part : Split(boot_cp, ":")) { 454 cmd.push_back(StringPrintf("--dex-file=%s", boot_part.c_str())); 455 } 456 cmd.push_back(StringPrintf("--oat-file=%s", oat_path.c_str())); 457 458 int32_t base_offset = ChooseRelocationOffsetDelta(ART_BASE_ADDRESS_MIN_DELTA, 459 ART_BASE_ADDRESS_MAX_DELTA); 460 cmd.push_back(StringPrintf("--base=0x%x", ART_BASE_ADDRESS + base_offset)); 461 462 cmd.push_back(StringPrintf("--instruction-set=%s", isa)); 463 464 // These things are pushed by AndroidRuntime, see frameworks/base/core/jni/AndroidRuntime.cpp. 465 AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-Xms", 466 "-Xms", 467 true, 468 cmd); 469 AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-Xmx", 470 "-Xmx", 471 true, 472 cmd); 473 AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-filter", 474 "--compiler-filter=", 475 false, 476 cmd); 477 cmd.push_back("--image-classes=/system/etc/preloaded-classes"); 478 // TODO: Compiled-classes. 479 const std::string* extra_opts = 480 system_properties_.GetProperty("dalvik.vm.image-dex2oat-flags"); 481 if (extra_opts != nullptr) { 482 std::vector<std::string> extra_vals = Split(*extra_opts, " "); 483 cmd.insert(cmd.end(), extra_vals.begin(), extra_vals.end()); 484 } 485 // TODO: Should we lower this? It's usually set close to max, because 486 // normally there's not much else going on at boot. 487 AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-threads", 488 "-j", 489 false, 490 cmd); 491 AddCompilerOptionFromSystemProperty( 492 StringPrintf("dalvik.vm.isa.%s.variant", isa).c_str(), 493 "--instruction-set-variant=", 494 false, 495 cmd); 496 AddCompilerOptionFromSystemProperty( 497 StringPrintf("dalvik.vm.isa.%s.features", isa).c_str(), 498 "--instruction-set-features=", 499 false, 500 cmd); 501 502 std::string error_msg; 503 bool result = Exec(cmd, &error_msg); 504 if (!result) { 505 LOG(ERROR) << "Could not generate boot image: " << error_msg; 506 } 507 return result; 508 } 509 510 static const char* ParseNull(const char* arg) { 511 return (strcmp(arg, "!") == 0) ? nullptr : arg; 512 } 513 514 bool ShouldSkipPreopt() const { 515 // There's one thing we have to be careful about: we may/will be asked to compile an app 516 // living in the system image. This may be a valid request - if the app wasn't compiled, 517 // e.g., if the system image wasn't large enough to include preopted files. However, the 518 // data we have is from the old system, so the driver (the OTA service) can't actually 519 // know. Thus, we will get requests for apps that have preopted components. To avoid 520 // duplication (we'd generate files that are not used and are *not* cleaned up), do two 521 // simple checks: 522 // 523 // 1) Does the apk_path start with the value of ANDROID_ROOT? (~in the system image) 524 // (For simplicity, assume the value of ANDROID_ROOT does not contain a symlink.) 525 // 526 // 2) If you replace the name in the apk_path with "oat," does the path exist? 527 // (=have a subdirectory for preopted files) 528 // 529 // If the answer to both is yes, skip the dexopt. 530 // 531 // Note: while one may think it's OK to call dexopt and it will fail (because APKs should 532 // be stripped), that's not true for APKs signed outside the build system (so the 533 // jar content must be exactly the same). 534 535 // (This is ugly as it's the only thing where we need to understand the contents 536 // of package_parameters_, but it beats postponing the decision or using the call- 537 // backs to do weird things.) 538 constexpr size_t kApkPathIndex = 0; 539 CHECK_GT(DEXOPT_PARAM_COUNT, kApkPathIndex); 540 CHECK(package_parameters_[kApkPathIndex] != nullptr); 541 if (StartsWith(package_parameters_[kApkPathIndex], android_root_.c_str())) { 542 const char* last_slash = strrchr(package_parameters_[kApkPathIndex], '/'); 543 if (last_slash != nullptr) { 544 std::string path(package_parameters_[kApkPathIndex], 545 last_slash - package_parameters_[kApkPathIndex] + 1); 546 CHECK(EndsWith(path, "/")); 547 path = path + "oat"; 548 if (access(path.c_str(), F_OK) == 0) { 549 return true; 550 } 551 } 552 } 553 554 // Another issue is unavailability of files in the new system. If the partition 555 // layout changes, otapreopt_chroot may not know about this. Then files from that 556 // partition will not be available and fail to build. This is problematic, as 557 // this tool will wipe the OTA artifact cache and try again (for robustness after 558 // a failed OTA with remaining cache artifacts). 559 if (access(package_parameters_[kApkPathIndex], F_OK) != 0) { 560 LOG(WARNING) << "Skipping preopt of non-existing package " 561 << package_parameters_[kApkPathIndex]; 562 return true; 563 } 564 565 return false; 566 } 567 568 int RunPreopt() { 569 if (ShouldSkipPreopt()) { 570 return 0; 571 } 572 573 int dexopt_result = dexopt(package_parameters_); 574 if (dexopt_result == 0) { 575 return 0; 576 } 577 578 // If the dexopt failed, we may have a stale boot image from a previous OTA run. 579 // Try to delete and retry. 580 581 if (!PrepareBootImage(/* force */ true)) { 582 LOG(ERROR) << "Forced boot image creating failed. Original error return was " 583 << dexopt_result; 584 return dexopt_result; 585 } 586 587 LOG(WARNING) << "Original dexopt failed, re-trying after boot image was regenerated."; 588 return dexopt(package_parameters_); 589 } 590 591 //////////////////////////////////// 592 // Helpers, mostly taken from ART // 593 //////////////////////////////////// 594 595 // Wrapper on fork/execv to run a command in a subprocess. 596 static bool Exec(const std::vector<std::string>& arg_vector, std::string* error_msg) { 597 const std::string command_line = Join(arg_vector, ' '); 598 599 CHECK_GE(arg_vector.size(), 1U) << command_line; 600 601 // Convert the args to char pointers. 602 const char* program = arg_vector[0].c_str(); 603 std::vector<char*> args; 604 for (size_t i = 0; i < arg_vector.size(); ++i) { 605 const std::string& arg = arg_vector[i]; 606 char* arg_str = const_cast<char*>(arg.c_str()); 607 CHECK(arg_str != nullptr) << i; 608 args.push_back(arg_str); 609 } 610 args.push_back(nullptr); 611 612 // Fork and exec. 613 pid_t pid = fork(); 614 if (pid == 0) { 615 // No allocation allowed between fork and exec. 616 617 // Change process groups, so we don't get reaped by ProcessManager. 618 setpgid(0, 0); 619 620 execv(program, &args[0]); 621 622 PLOG(ERROR) << "Failed to execv(" << command_line << ")"; 623 // _exit to avoid atexit handlers in child. 624 _exit(1); 625 } else { 626 if (pid == -1) { 627 *error_msg = StringPrintf("Failed to execv(%s) because fork failed: %s", 628 command_line.c_str(), strerror(errno)); 629 return false; 630 } 631 632 // wait for subprocess to finish 633 int status; 634 pid_t got_pid = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0)); 635 if (got_pid != pid) { 636 *error_msg = StringPrintf("Failed after fork for execv(%s) because waitpid failed: " 637 "wanted %d, got %d: %s", 638 command_line.c_str(), pid, got_pid, strerror(errno)); 639 return false; 640 } 641 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { 642 *error_msg = StringPrintf("Failed execv(%s) because non-0 exit status", 643 command_line.c_str()); 644 return false; 645 } 646 } 647 return true; 648 } 649 650 // Choose a random relocation offset. Taken from art/runtime/gc/image_space.cc. 651 static int32_t ChooseRelocationOffsetDelta(int32_t min_delta, int32_t max_delta) { 652 constexpr size_t kPageSize = PAGE_SIZE; 653 CHECK_EQ(min_delta % kPageSize, 0u); 654 CHECK_EQ(max_delta % kPageSize, 0u); 655 CHECK_LT(min_delta, max_delta); 656 657 std::default_random_engine generator; 658 generator.seed(GetSeed()); 659 std::uniform_int_distribution<int32_t> distribution(min_delta, max_delta); 660 int32_t r = distribution(generator); 661 if (r % 2 == 0) { 662 r = RoundUp(r, kPageSize); 663 } else { 664 r = RoundDown(r, kPageSize); 665 } 666 CHECK_LE(min_delta, r); 667 CHECK_GE(max_delta, r); 668 CHECK_EQ(r % kPageSize, 0u); 669 return r; 670 } 671 672 static uint64_t GetSeed() { 673 #ifdef __BIONIC__ 674 // Bionic exposes arc4random, use it. 675 uint64_t random_data; 676 arc4random_buf(&random_data, sizeof(random_data)); 677 return random_data; 678 #else 679 #error "This is only supposed to run with bionic. Otherwise, implement..." 680 #endif 681 } 682 683 void AddCompilerOptionFromSystemProperty(const char* system_property, 684 const char* prefix, 685 bool runtime, 686 std::vector<std::string>& out) const { 687 const std::string* value = system_properties_.GetProperty(system_property); 688 if (value != nullptr) { 689 if (runtime) { 690 out.push_back("--runtime-arg"); 691 } 692 if (prefix != nullptr) { 693 out.push_back(StringPrintf("%s%s", prefix, value->c_str())); 694 } else { 695 out.push_back(*value); 696 } 697 } 698 } 699 700 static constexpr const char* kBootClassPathPropertyName = "BOOTCLASSPATH"; 701 static constexpr const char* kAndroidRootPathPropertyName = "ANDROID_ROOT"; 702 static constexpr const char* kAndroidDataPathPropertyName = "ANDROID_DATA"; 703 // The index of the instruction-set string inside the package parameters. Needed for 704 // some special-casing that requires knowledge of the instruction-set. 705 static constexpr size_t kISAIndex = 3; 706 707 // Stores the system properties read out of the B partition. We need to use these properties 708 // to compile, instead of the A properties we could get from init/get_property. 709 SystemProperties system_properties_; 710 711 // Some select properties that are always needed. 712 std::string target_slot_; 713 std::string android_root_; 714 std::string android_data_; 715 std::string boot_classpath_; 716 std::string asec_mountpoint_; 717 718 const char* package_parameters_[DEXOPT_PARAM_COUNT]; 719 720 // Store environment values we need to set. 721 std::vector<std::string> environ_; 722 }; 723 724 OTAPreoptService gOps; 725 726 //////////////////////// 727 // Plug-in functions. // 728 //////////////////////// 729 730 int get_property(const char *key, char *value, const char *default_value) { 731 return gOps.GetProperty(key, value, default_value); 732 } 733 734 // Compute the output path of 735 bool calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir, 736 const char *apk_path, 737 const char *instruction_set) { 738 const char *file_name_start; 739 const char *file_name_end; 740 741 file_name_start = strrchr(apk_path, '/'); 742 if (file_name_start == nullptr) { 743 ALOGE("apk_path '%s' has no '/'s in it\n", apk_path); 744 return false; 745 } 746 file_name_end = strrchr(file_name_start, '.'); 747 if (file_name_end == nullptr) { 748 ALOGE("apk_path '%s' has no extension\n", apk_path); 749 return false; 750 } 751 752 // Calculate file_name 753 file_name_start++; // Move past '/', is valid as file_name_end is valid. 754 size_t file_name_len = file_name_end - file_name_start; 755 std::string file_name(file_name_start, file_name_len); 756 757 // <apk_parent_dir>/oat/<isa>/<file_name>.odex.b 758 snprintf(path, 759 PKG_PATH_MAX, 760 "%s/%s/%s.odex.%s", 761 oat_dir, 762 instruction_set, 763 file_name.c_str(), 764 gOps.GetTargetSlot().c_str()); 765 return true; 766 } 767 768 /* 769 * Computes the odex file for the given apk_path and instruction_set. 770 * /system/framework/whatever.jar -> /system/framework/oat/<isa>/whatever.odex 771 * 772 * Returns false if it failed to determine the odex file path. 773 */ 774 bool calculate_odex_file_path(char path[PKG_PATH_MAX], const char *apk_path, 775 const char *instruction_set) { 776 const char *path_end = strrchr(apk_path, '/'); 777 if (path_end == nullptr) { 778 ALOGE("apk_path '%s' has no '/'s in it?!\n", apk_path); 779 return false; 780 } 781 std::string path_component(apk_path, path_end - apk_path); 782 783 const char *name_begin = path_end + 1; 784 const char *extension_start = strrchr(name_begin, '.'); 785 if (extension_start == nullptr) { 786 ALOGE("apk_path '%s' has no extension.\n", apk_path); 787 return false; 788 } 789 std::string name_component(name_begin, extension_start - name_begin); 790 791 std::string new_path = StringPrintf("%s/oat/%s/%s.odex.%s", 792 path_component.c_str(), 793 instruction_set, 794 name_component.c_str(), 795 gOps.GetTargetSlot().c_str()); 796 if (new_path.length() >= PKG_PATH_MAX) { 797 LOG(ERROR) << "apk_path of " << apk_path << " is too long: " << new_path; 798 return false; 799 } 800 strcpy(path, new_path.c_str()); 801 return true; 802 } 803 804 bool create_cache_path(char path[PKG_PATH_MAX], 805 const char *src, 806 const char *instruction_set) { 807 size_t srclen = strlen(src); 808 809 /* demand that we are an absolute path */ 810 if ((src == 0) || (src[0] != '/') || strstr(src,"..")) { 811 return false; 812 } 813 814 if (srclen > PKG_PATH_MAX) { // XXX: PKG_NAME_MAX? 815 return false; 816 } 817 818 std::string from_src = std::string(src + 1); 819 std::replace(from_src.begin(), from_src.end(), '/', '@'); 820 821 std::string assembled_path = StringPrintf("%s/%s/%s/%s%s", 822 gOps.GetOTADataDirectory().c_str(), 823 DALVIK_CACHE, 824 instruction_set, 825 from_src.c_str(), 826 DALVIK_CACHE_POSTFIX2); 827 828 if (assembled_path.length() + 1 > PKG_PATH_MAX) { 829 return false; 830 } 831 strcpy(path, assembled_path.c_str()); 832 833 return true; 834 } 835 836 static int log_callback(int type, const char *fmt, ...) { 837 va_list ap; 838 int priority; 839 840 switch (type) { 841 case SELINUX_WARNING: 842 priority = ANDROID_LOG_WARN; 843 break; 844 case SELINUX_INFO: 845 priority = ANDROID_LOG_INFO; 846 break; 847 default: 848 priority = ANDROID_LOG_ERROR; 849 break; 850 } 851 va_start(ap, fmt); 852 LOG_PRI_VA(priority, "SELinux", fmt, ap); 853 va_end(ap); 854 return 0; 855 } 856 857 static int otapreopt_main(const int argc, char *argv[]) { 858 int selinux_enabled = (is_selinux_enabled() > 0); 859 860 setenv("ANDROID_LOG_TAGS", "*:v", 1); 861 android::base::InitLogging(argv); 862 863 if (argc < 2) { 864 ALOGE("Expecting parameters"); 865 exit(1); 866 } 867 868 union selinux_callback cb; 869 cb.func_log = log_callback; 870 selinux_set_callback(SELINUX_CB_LOG, cb); 871 872 if (selinux_enabled && selinux_status_open(true) < 0) { 873 ALOGE("Could not open selinux status; exiting.\n"); 874 exit(1); 875 } 876 877 int ret = android::installd::gOps.Main(argc, argv); 878 879 return ret; 880 } 881 882 } // namespace installd 883 } // namespace android 884 885 int main(const int argc, char *argv[]) { 886 return android::installd::otapreopt_main(argc, argv); 887 } 888