1 /* 2 * Copyright (C) 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 #define LOG_TAG "installd" 17 18 #include <array> 19 #include <fcntl.h> 20 #include <stdlib.h> 21 #include <string.h> 22 #include <sys/capability.h> 23 #include <sys/file.h> 24 #include <sys/stat.h> 25 #include <sys/time.h> 26 #include <sys/types.h> 27 #include <sys/resource.h> 28 #include <sys/wait.h> 29 #include <unistd.h> 30 31 #include <iomanip> 32 33 #include <android-base/file.h> 34 #include <android-base/logging.h> 35 #include <android-base/properties.h> 36 #include <android-base/stringprintf.h> 37 #include <android-base/strings.h> 38 #include <android-base/unique_fd.h> 39 #include <cutils/fs.h> 40 #include <cutils/properties.h> 41 #include <cutils/sched_policy.h> 42 #include <dex2oat_return_codes.h> 43 #include <log/log.h> // TODO: Move everything to base/logging. 44 #include <openssl/sha.h> 45 #include <private/android_filesystem_config.h> 46 #include <processgroup/sched_policy.h> 47 #include <selinux/android.h> 48 #include <server_configurable_flags/get_flags.h> 49 #include <system/thread_defs.h> 50 51 #include "dexopt.h" 52 #include "dexopt_return_codes.h" 53 #include "globals.h" 54 #include "installd_deps.h" 55 #include "otapreopt_utils.h" 56 #include "utils.h" 57 58 using android::base::EndsWith; 59 using android::base::GetBoolProperty; 60 using android::base::GetProperty; 61 using android::base::ReadFdToString; 62 using android::base::ReadFully; 63 using android::base::StringPrintf; 64 using android::base::WriteFully; 65 using android::base::unique_fd; 66 67 namespace android { 68 namespace installd { 69 70 // Should minidebug info be included in compiled artifacts? Even if this value is 71 // "true," usage might still be conditional to other constraints, e.g., system 72 // property overrides. 73 static constexpr bool kEnableMinidebugInfo = true; 74 75 static constexpr const char* kMinidebugInfoSystemProperty = "dalvik.vm.dex2oat-minidebuginfo"; 76 static constexpr bool kMinidebugInfoSystemPropertyDefault = false; 77 static constexpr const char* kMinidebugDex2oatFlag = "--generate-mini-debug-info"; 78 static constexpr const char* kDisableCompactDexFlag = "--compact-dex-level=none"; 79 80 81 // Deleter using free() for use with std::unique_ptr<>. See also UniqueCPtr<> below. 82 struct FreeDelete { 83 // NOTE: Deleting a const object is valid but free() takes a non-const pointer. 84 void operator()(const void* ptr) const { 85 free(const_cast<void*>(ptr)); 86 } 87 }; 88 89 // Alias for std::unique_ptr<> that uses the C function free() to delete objects. 90 template <typename T> 91 using UniqueCPtr = std::unique_ptr<T, FreeDelete>; 92 93 static unique_fd invalid_unique_fd() { 94 return unique_fd(-1); 95 } 96 97 static bool is_debug_runtime() { 98 return android::base::GetProperty("persist.sys.dalvik.vm.lib.2", "") == "libartd.so"; 99 } 100 101 static bool is_debuggable_build() { 102 return android::base::GetBoolProperty("ro.debuggable", false); 103 } 104 105 static bool clear_profile(const std::string& profile) { 106 unique_fd ufd(open(profile.c_str(), O_WRONLY | O_NOFOLLOW | O_CLOEXEC)); 107 if (ufd.get() < 0) { 108 if (errno != ENOENT) { 109 PLOG(WARNING) << "Could not open profile " << profile; 110 return false; 111 } else { 112 // Nothing to clear. That's ok. 113 return true; 114 } 115 } 116 117 if (flock(ufd.get(), LOCK_EX | LOCK_NB) != 0) { 118 if (errno != EWOULDBLOCK) { 119 PLOG(WARNING) << "Error locking profile " << profile; 120 } 121 // This implies that the app owning this profile is running 122 // (and has acquired the lock). 123 // 124 // If we can't acquire the lock bail out since clearing is useless anyway 125 // (the app will write again to the profile). 126 // 127 // Note: 128 // This does not impact the this is not an issue for the profiling correctness. 129 // In case this is needed because of an app upgrade, profiles will still be 130 // eventually cleared by the app itself due to checksum mismatch. 131 // If this is needed because profman advised, then keeping the data around 132 // until the next run is again not an issue. 133 // 134 // If the app attempts to acquire a lock while we've held one here, 135 // it will simply skip the current write cycle. 136 return false; 137 } 138 139 bool truncated = ftruncate(ufd.get(), 0) == 0; 140 if (!truncated) { 141 PLOG(WARNING) << "Could not truncate " << profile; 142 } 143 if (flock(ufd.get(), LOCK_UN) != 0) { 144 PLOG(WARNING) << "Error unlocking profile " << profile; 145 } 146 return truncated; 147 } 148 149 // Clear the reference profile for the given location. 150 // The location is the profile name for primary apks or the dex path for secondary dex files. 151 static bool clear_reference_profile(const std::string& package_name, const std::string& location, 152 bool is_secondary_dex) { 153 return clear_profile(create_reference_profile_path(package_name, location, is_secondary_dex)); 154 } 155 156 // Clear the reference profile for the given location. 157 // The location is the profile name for primary apks or the dex path for secondary dex files. 158 static bool clear_current_profile(const std::string& package_name, const std::string& location, 159 userid_t user, bool is_secondary_dex) { 160 return clear_profile(create_current_profile_path(user, package_name, location, 161 is_secondary_dex)); 162 } 163 164 // Clear the reference profile for the primary apk of the given package. 165 // The location is the profile name for primary apks or the dex path for secondary dex files. 166 bool clear_primary_reference_profile(const std::string& package_name, 167 const std::string& location) { 168 return clear_reference_profile(package_name, location, /*is_secondary_dex*/false); 169 } 170 171 // Clear all current profile for the primary apk of the given package. 172 // The location is the profile name for primary apks or the dex path for secondary dex files. 173 bool clear_primary_current_profiles(const std::string& package_name, const std::string& location) { 174 bool success = true; 175 // For secondary dex files, we don't really need the user but we use it for sanity checks. 176 std::vector<userid_t> users = get_known_users(/*volume_uuid*/ nullptr); 177 for (auto user : users) { 178 success &= clear_current_profile(package_name, location, user, /*is_secondary_dex*/false); 179 } 180 return success; 181 } 182 183 // Clear the current profile for the primary apk of the given package and user. 184 bool clear_primary_current_profile(const std::string& package_name, const std::string& location, 185 userid_t user) { 186 return clear_current_profile(package_name, location, user, /*is_secondary_dex*/false); 187 } 188 189 static std::vector<std::string> SplitBySpaces(const std::string& str) { 190 if (str.empty()) { 191 return {}; 192 } 193 return android::base::Split(str, " "); 194 } 195 196 static const char* get_location_from_path(const char* path) { 197 static constexpr char kLocationSeparator = '/'; 198 const char *location = strrchr(path, kLocationSeparator); 199 if (location == nullptr) { 200 return path; 201 } else { 202 // Skip the separator character. 203 return location + 1; 204 } 205 } 206 207 // ExecVHelper prepares and holds pointers to parsed command line arguments so that no allocations 208 // need to be performed between the fork and exec. 209 class ExecVHelper { 210 public: 211 // Store a placeholder for the binary name. 212 ExecVHelper() : args_(1u, std::string()) {} 213 214 void PrepareArgs(const std::string& bin) { 215 CHECK(!args_.empty()); 216 CHECK(args_[0].empty()); 217 args_[0] = bin; 218 // Write char* into array. 219 for (const std::string& arg : args_) { 220 argv_.push_back(arg.c_str()); 221 } 222 argv_.push_back(nullptr); // Add null terminator. 223 } 224 225 [[ noreturn ]] 226 void Exec(int exit_code) { 227 execv(argv_[0], (char * const *)&argv_[0]); 228 PLOG(ERROR) << "execv(" << argv_[0] << ") failed"; 229 exit(exit_code); 230 } 231 232 // Add an arg if it's not empty. 233 void AddArg(const std::string& arg) { 234 if (!arg.empty()) { 235 args_.push_back(arg); 236 } 237 } 238 239 // Add a runtime arg if it's not empty. 240 void AddRuntimeArg(const std::string& arg) { 241 if (!arg.empty()) { 242 args_.push_back("--runtime-arg"); 243 args_.push_back(arg); 244 } 245 } 246 247 protected: 248 // Holder arrays for backing arg storage. 249 std::vector<std::string> args_; 250 251 // Argument poiners. 252 std::vector<const char*> argv_; 253 }; 254 255 static std::string MapPropertyToArg(const std::string& property, 256 const std::string& format, 257 const std::string& default_value = "") { 258 std::string prop = GetProperty(property, default_value); 259 if (!prop.empty()) { 260 return StringPrintf(format.c_str(), prop.c_str()); 261 } 262 return ""; 263 } 264 265 // Determines which binary we should use for execution (the debug or non-debug version). 266 // e.g. dex2oatd vs dex2oat 267 static const char* select_execution_binary(const char* binary, const char* debug_binary, 268 bool background_job_compile) { 269 return select_execution_binary( 270 binary, 271 debug_binary, 272 background_job_compile, 273 is_debug_runtime(), 274 (android::base::GetProperty("ro.build.version.codename", "") == "REL"), 275 is_debuggable_build()); 276 } 277 278 // Determines which binary we should use for execution (the debug or non-debug version). 279 // e.g. dex2oatd vs dex2oat 280 // This is convenient method which is much easier to test because it doesn't read 281 // system properties. 282 const char* select_execution_binary( 283 const char* binary, 284 const char* debug_binary, 285 bool background_job_compile, 286 bool is_debug_runtime, 287 bool is_release, 288 bool is_debuggable_build) { 289 // Do not use debug binaries for release candidates (to give more soak time). 290 bool is_debug_bg_job = background_job_compile && is_debuggable_build && !is_release; 291 292 // If the runtime was requested to use libartd.so, we'll run the debug version - assuming 293 // the file is present (it may not be on images with very little space available). 294 bool useDebug = (is_debug_runtime || is_debug_bg_job) && (access(debug_binary, X_OK) == 0); 295 296 return useDebug ? debug_binary : binary; 297 } 298 299 // Namespace for Android Runtime flags applied during boot time. 300 static const char* RUNTIME_NATIVE_BOOT_NAMESPACE = "runtime_native_boot"; 301 // Feature flag name for running the JIT in Zygote experiment, b/119800099. 302 static const char* ENABLE_APEX_IMAGE = "enable_apex_image"; 303 // Location of the apex image. 304 static const char* kApexImage = "/system/framework/apex.art"; 305 306 class RunDex2Oat : public ExecVHelper { 307 public: 308 RunDex2Oat(int zip_fd, 309 int oat_fd, 310 int input_vdex_fd, 311 int output_vdex_fd, 312 int image_fd, 313 const char* input_file_name, 314 const char* output_file_name, 315 int swap_fd, 316 const char* instruction_set, 317 const char* compiler_filter, 318 bool debuggable, 319 bool post_bootcomplete, 320 bool background_job_compile, 321 int profile_fd, 322 const char* class_loader_context, 323 const std::string& class_loader_context_fds, 324 int target_sdk_version, 325 bool enable_hidden_api_checks, 326 bool generate_compact_dex, 327 int dex_metadata_fd, 328 const char* compilation_reason) { 329 // Get the relative path to the input file. 330 const char* relative_input_file_name = get_location_from_path(input_file_name); 331 332 std::string dex2oat_Xms_arg = MapPropertyToArg("dalvik.vm.dex2oat-Xms", "-Xms%s"); 333 std::string dex2oat_Xmx_arg = MapPropertyToArg("dalvik.vm.dex2oat-Xmx", "-Xmx%s"); 334 335 const char* threads_property = post_bootcomplete 336 ? "dalvik.vm.dex2oat-threads" 337 : "dalvik.vm.boot-dex2oat-threads"; 338 std::string dex2oat_threads_arg = MapPropertyToArg(threads_property, "-j%s"); 339 340 std::string bootclasspath; 341 char* dex2oat_bootclasspath = getenv("DEX2OATBOOTCLASSPATH"); 342 if (dex2oat_bootclasspath != nullptr) { 343 bootclasspath = StringPrintf("-Xbootclasspath:%s", dex2oat_bootclasspath); 344 } 345 // If DEX2OATBOOTCLASSPATH is not in the environment, dex2oat is going to query 346 // BOOTCLASSPATH. 347 348 const std::string dex2oat_isa_features_key = 349 StringPrintf("dalvik.vm.isa.%s.features", instruction_set); 350 std::string instruction_set_features_arg = 351 MapPropertyToArg(dex2oat_isa_features_key, "--instruction-set-features=%s"); 352 353 const std::string dex2oat_isa_variant_key = 354 StringPrintf("dalvik.vm.isa.%s.variant", instruction_set); 355 std::string instruction_set_variant_arg = 356 MapPropertyToArg(dex2oat_isa_variant_key, "--instruction-set-variant=%s"); 357 358 const char* dex2oat_norelocation = "-Xnorelocate"; 359 360 const std::string dex2oat_flags = GetProperty("dalvik.vm.dex2oat-flags", ""); 361 std::vector<std::string> dex2oat_flags_args = SplitBySpaces(dex2oat_flags); 362 ALOGV("dalvik.vm.dex2oat-flags=%s\n", dex2oat_flags.c_str()); 363 364 // If we are booting without the real /data, don't spend time compiling. 365 std::string vold_decrypt = GetProperty("vold.decrypt", ""); 366 bool skip_compilation = vold_decrypt == "trigger_restart_min_framework" || 367 vold_decrypt == "1"; 368 369 std::string resolve_startup_string_arg = 370 MapPropertyToArg("persist.device_config.runtime.dex2oat_resolve_startup_strings", 371 "--resolve-startup-const-strings=%s"); 372 if (resolve_startup_string_arg.empty()) { 373 // If empty, fall back to system property. 374 resolve_startup_string_arg = 375 MapPropertyToArg("dalvik.vm.dex2oat-resolve-startup-strings", 376 "--resolve-startup-const-strings=%s"); 377 } 378 379 const std::string image_block_size_arg = 380 MapPropertyToArg("dalvik.vm.dex2oat-max-image-block-size", 381 "--max-image-block-size=%s"); 382 383 const bool generate_debug_info = GetBoolProperty("debug.generate-debug-info", false); 384 385 std::string image_format_arg; 386 if (image_fd >= 0) { 387 image_format_arg = MapPropertyToArg("dalvik.vm.appimageformat", "--image-format=%s"); 388 } 389 390 std::string dex2oat_large_app_threshold_arg = 391 MapPropertyToArg("dalvik.vm.dex2oat-very-large", "--very-large-app-threshold=%s"); 392 393 394 const char* dex2oat_bin = select_execution_binary( 395 kDex2oatPath, kDex2oatDebugPath, background_job_compile); 396 397 bool generate_minidebug_info = kEnableMinidebugInfo && 398 GetBoolProperty(kMinidebugInfoSystemProperty, kMinidebugInfoSystemPropertyDefault); 399 400 std::string boot_image; 401 std::string use_apex_image = 402 server_configurable_flags::GetServerConfigurableFlag(RUNTIME_NATIVE_BOOT_NAMESPACE, 403 ENABLE_APEX_IMAGE, 404 /*default_value=*/ ""); 405 if (use_apex_image == "true") { 406 boot_image = StringPrintf("-Ximage:%s", kApexImage); 407 } else { 408 boot_image = MapPropertyToArg("dalvik.vm.boot-image", "-Ximage:%s"); 409 } 410 411 // clang FORTIFY doesn't let us use strlen in constant array bounds, so we 412 // use arraysize instead. 413 std::string zip_fd_arg = StringPrintf("--zip-fd=%d", zip_fd); 414 std::string zip_location_arg = StringPrintf("--zip-location=%s", relative_input_file_name); 415 std::string input_vdex_fd_arg = StringPrintf("--input-vdex-fd=%d", input_vdex_fd); 416 std::string output_vdex_fd_arg = StringPrintf("--output-vdex-fd=%d", output_vdex_fd); 417 std::string oat_fd_arg = StringPrintf("--oat-fd=%d", oat_fd); 418 std::string oat_location_arg = StringPrintf("--oat-location=%s", output_file_name); 419 std::string instruction_set_arg = StringPrintf("--instruction-set=%s", instruction_set); 420 std::string dex2oat_compiler_filter_arg; 421 std::string dex2oat_swap_fd; 422 std::string dex2oat_image_fd; 423 std::string target_sdk_version_arg; 424 if (target_sdk_version != 0) { 425 target_sdk_version_arg = StringPrintf("-Xtarget-sdk-version:%d", target_sdk_version); 426 } 427 std::string class_loader_context_arg; 428 std::string class_loader_context_fds_arg; 429 if (class_loader_context != nullptr) { 430 class_loader_context_arg = StringPrintf("--class-loader-context=%s", 431 class_loader_context); 432 if (!class_loader_context_fds.empty()) { 433 class_loader_context_fds_arg = StringPrintf("--class-loader-context-fds=%s", 434 class_loader_context_fds.c_str()); 435 } 436 } 437 438 if (swap_fd >= 0) { 439 dex2oat_swap_fd = StringPrintf("--swap-fd=%d", swap_fd); 440 } 441 if (image_fd >= 0) { 442 dex2oat_image_fd = StringPrintf("--app-image-fd=%d", image_fd); 443 } 444 445 // Compute compiler filter. 446 bool have_dex2oat_relocation_skip_flag = false; 447 if (skip_compilation) { 448 dex2oat_compiler_filter_arg = "--compiler-filter=extract"; 449 have_dex2oat_relocation_skip_flag = true; 450 } else if (compiler_filter != nullptr) { 451 dex2oat_compiler_filter_arg = StringPrintf("--compiler-filter=%s", compiler_filter); 452 } 453 454 if (dex2oat_compiler_filter_arg.empty()) { 455 dex2oat_compiler_filter_arg = MapPropertyToArg("dalvik.vm.dex2oat-filter", 456 "--compiler-filter=%s"); 457 } 458 459 // Check whether all apps should be compiled debuggable. 460 if (!debuggable) { 461 debuggable = GetProperty("dalvik.vm.always_debuggable", "") == "1"; 462 } 463 std::string profile_arg; 464 if (profile_fd != -1) { 465 profile_arg = StringPrintf("--profile-file-fd=%d", profile_fd); 466 } 467 468 // Get the directory of the apk to pass as a base classpath directory. 469 std::string base_dir; 470 std::string apk_dir(input_file_name); 471 unsigned long dir_index = apk_dir.rfind('/'); 472 bool has_base_dir = dir_index != std::string::npos; 473 if (has_base_dir) { 474 apk_dir = apk_dir.substr(0, dir_index); 475 base_dir = StringPrintf("--classpath-dir=%s", apk_dir.c_str()); 476 } 477 478 std::string dex_metadata_fd_arg = "--dm-fd=" + std::to_string(dex_metadata_fd); 479 480 std::string compilation_reason_arg = compilation_reason == nullptr 481 ? "" 482 : std::string("--compilation-reason=") + compilation_reason; 483 484 ALOGV("Running %s in=%s out=%s\n", dex2oat_bin, relative_input_file_name, output_file_name); 485 486 // Disable cdex if update input vdex is true since this combination of options is not 487 // supported. 488 const bool disable_cdex = !generate_compact_dex || (input_vdex_fd == output_vdex_fd); 489 490 AddArg(zip_fd_arg); 491 AddArg(zip_location_arg); 492 AddArg(input_vdex_fd_arg); 493 AddArg(output_vdex_fd_arg); 494 AddArg(oat_fd_arg); 495 AddArg(oat_location_arg); 496 AddArg(instruction_set_arg); 497 498 AddArg(instruction_set_variant_arg); 499 AddArg(instruction_set_features_arg); 500 501 AddRuntimeArg(boot_image); 502 AddRuntimeArg(bootclasspath); 503 AddRuntimeArg(dex2oat_Xms_arg); 504 AddRuntimeArg(dex2oat_Xmx_arg); 505 506 AddArg(resolve_startup_string_arg); 507 AddArg(image_block_size_arg); 508 AddArg(dex2oat_compiler_filter_arg); 509 AddArg(dex2oat_threads_arg); 510 AddArg(dex2oat_swap_fd); 511 AddArg(dex2oat_image_fd); 512 513 if (generate_debug_info) { 514 AddArg("--generate-debug-info"); 515 } 516 if (debuggable) { 517 AddArg("--debuggable"); 518 } 519 AddArg(image_format_arg); 520 AddArg(dex2oat_large_app_threshold_arg); 521 522 if (have_dex2oat_relocation_skip_flag) { 523 AddRuntimeArg(dex2oat_norelocation); 524 } 525 AddArg(profile_arg); 526 AddArg(base_dir); 527 AddArg(class_loader_context_arg); 528 AddArg(class_loader_context_fds_arg); 529 if (generate_minidebug_info) { 530 AddArg(kMinidebugDex2oatFlag); 531 } 532 if (disable_cdex) { 533 AddArg(kDisableCompactDexFlag); 534 } 535 AddRuntimeArg(target_sdk_version_arg); 536 if (enable_hidden_api_checks) { 537 AddRuntimeArg("-Xhidden-api-policy:enabled"); 538 } 539 540 if (dex_metadata_fd > -1) { 541 AddArg(dex_metadata_fd_arg); 542 } 543 544 AddArg(compilation_reason_arg); 545 546 // Do not add args after dex2oat_flags, they should override others for debugging. 547 args_.insert(args_.end(), dex2oat_flags_args.begin(), dex2oat_flags_args.end()); 548 549 PrepareArgs(dex2oat_bin); 550 } 551 }; 552 553 /* 554 * Whether dexopt should use a swap file when compiling an APK. 555 * 556 * If kAlwaysProvideSwapFile, do this on all devices (dex2oat will make a more informed decision 557 * itself, anyways). 558 * 559 * Otherwise, read "dalvik.vm.dex2oat-swap". If the property exists, return whether it is "true". 560 * 561 * Otherwise, return true if this is a low-mem device. 562 * 563 * Otherwise, return default value. 564 */ 565 static bool kAlwaysProvideSwapFile = false; 566 static bool kDefaultProvideSwapFile = true; 567 568 static bool ShouldUseSwapFileForDexopt() { 569 if (kAlwaysProvideSwapFile) { 570 return true; 571 } 572 573 // Check the "override" property. If it exists, return value == "true". 574 std::string dex2oat_prop_buf = GetProperty("dalvik.vm.dex2oat-swap", ""); 575 if (!dex2oat_prop_buf.empty()) { 576 return dex2oat_prop_buf == "true"; 577 } 578 579 // Shortcut for default value. This is an implementation optimization for the process sketched 580 // above. If the default value is true, we can avoid to check whether this is a low-mem device, 581 // as low-mem is never returning false. The compiler will optimize this away if it can. 582 if (kDefaultProvideSwapFile) { 583 return true; 584 } 585 586 if (GetBoolProperty("ro.config.low_ram", false)) { 587 return true; 588 } 589 590 // Default value must be false here. 591 return kDefaultProvideSwapFile; 592 } 593 594 static void SetDex2OatScheduling(bool set_to_bg) { 595 if (set_to_bg) { 596 if (set_sched_policy(0, SP_BACKGROUND) < 0) { 597 PLOG(ERROR) << "set_sched_policy failed"; 598 exit(DexoptReturnCodes::kSetSchedPolicy); 599 } 600 if (setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_BACKGROUND) < 0) { 601 PLOG(ERROR) << "setpriority failed"; 602 exit(DexoptReturnCodes::kSetPriority); 603 } 604 } 605 } 606 607 static unique_fd create_profile(uid_t uid, const std::string& profile, int32_t flags) { 608 unique_fd fd(TEMP_FAILURE_RETRY(open(profile.c_str(), flags, 0600))); 609 if (fd.get() < 0) { 610 if (errno != EEXIST) { 611 PLOG(ERROR) << "Failed to create profile " << profile; 612 return invalid_unique_fd(); 613 } 614 } 615 // Profiles should belong to the app; make sure of that by giving ownership to 616 // the app uid. If we cannot do that, there's no point in returning the fd 617 // since dex2oat/profman will fail with SElinux denials. 618 if (fchown(fd.get(), uid, uid) < 0) { 619 PLOG(ERROR) << "Could not chown profile " << profile; 620 return invalid_unique_fd(); 621 } 622 return fd; 623 } 624 625 static unique_fd open_profile(uid_t uid, const std::string& profile, int32_t flags) { 626 // Do not follow symlinks when opening a profile: 627 // - primary profiles should not contain symlinks in their paths 628 // - secondary dex paths should have been already resolved and validated 629 flags |= O_NOFOLLOW; 630 631 // Check if we need to create the profile 632 // Reference profiles and snapshots are created on the fly; so they might not exist beforehand. 633 unique_fd fd; 634 if ((flags & O_CREAT) != 0) { 635 fd = create_profile(uid, profile, flags); 636 } else { 637 fd.reset(TEMP_FAILURE_RETRY(open(profile.c_str(), flags))); 638 } 639 640 if (fd.get() < 0) { 641 if (errno != ENOENT) { 642 // Profiles might be missing for various reasons. For example, in a 643 // multi-user environment, the profile directory for one user can be created 644 // after we start a merge. In this case the current profile for that user 645 // will not be found. 646 // Also, the secondary dex profiles might be deleted by the app at any time, 647 // so we can't we need to prepare if they are missing. 648 PLOG(ERROR) << "Failed to open profile " << profile; 649 } 650 return invalid_unique_fd(); 651 } 652 653 return fd; 654 } 655 656 static unique_fd open_current_profile(uid_t uid, userid_t user, const std::string& package_name, 657 const std::string& location, bool is_secondary_dex) { 658 std::string profile = create_current_profile_path(user, package_name, location, 659 is_secondary_dex); 660 return open_profile(uid, profile, O_RDONLY); 661 } 662 663 static unique_fd open_reference_profile(uid_t uid, const std::string& package_name, 664 const std::string& location, bool read_write, bool is_secondary_dex) { 665 std::string profile = create_reference_profile_path(package_name, location, is_secondary_dex); 666 return open_profile(uid, profile, read_write ? (O_CREAT | O_RDWR) : O_RDONLY); 667 } 668 669 static unique_fd open_spnashot_profile(uid_t uid, const std::string& package_name, 670 const std::string& location) { 671 std::string profile = create_snapshot_profile_path(package_name, location); 672 return open_profile(uid, profile, O_CREAT | O_RDWR | O_TRUNC); 673 } 674 675 static void open_profile_files(uid_t uid, const std::string& package_name, 676 const std::string& location, bool is_secondary_dex, 677 /*out*/ std::vector<unique_fd>* profiles_fd, /*out*/ unique_fd* reference_profile_fd) { 678 // Open the reference profile in read-write mode as profman might need to save the merge. 679 *reference_profile_fd = open_reference_profile(uid, package_name, location, 680 /*read_write*/ true, is_secondary_dex); 681 682 // For secondary dex files, we don't really need the user but we use it for sanity checks. 683 // Note: the user owning the dex file should be the current user. 684 std::vector<userid_t> users; 685 if (is_secondary_dex){ 686 users.push_back(multiuser_get_user_id(uid)); 687 } else { 688 users = get_known_users(/*volume_uuid*/ nullptr); 689 } 690 for (auto user : users) { 691 unique_fd profile_fd = open_current_profile(uid, user, package_name, location, 692 is_secondary_dex); 693 // Add to the lists only if both fds are valid. 694 if (profile_fd.get() >= 0) { 695 profiles_fd->push_back(std::move(profile_fd)); 696 } 697 } 698 } 699 700 static constexpr int PROFMAN_BIN_RETURN_CODE_COMPILE = 0; 701 static constexpr int PROFMAN_BIN_RETURN_CODE_SKIP_COMPILATION = 1; 702 static constexpr int PROFMAN_BIN_RETURN_CODE_BAD_PROFILES = 2; 703 static constexpr int PROFMAN_BIN_RETURN_CODE_ERROR_IO = 3; 704 static constexpr int PROFMAN_BIN_RETURN_CODE_ERROR_LOCKING = 4; 705 706 class RunProfman : public ExecVHelper { 707 public: 708 void SetupArgs(const std::vector<unique_fd>& profile_fds, 709 const unique_fd& reference_profile_fd, 710 const std::vector<unique_fd>& apk_fds, 711 const std::vector<std::string>& dex_locations, 712 bool copy_and_update, 713 bool store_aggregation_counters) { 714 715 // TODO(calin): Assume for now we run in the bg compile job (which is in 716 // most of the invocation). With the current data flow, is not very easy or 717 // clean to discover this in RunProfman (it will require quite a messy refactoring). 718 const char* profman_bin = select_execution_binary( 719 kProfmanPath, kProfmanDebugPath, /*background_job_compile=*/ true); 720 721 if (copy_and_update) { 722 CHECK_EQ(1u, profile_fds.size()); 723 CHECK_EQ(1u, apk_fds.size()); 724 } 725 if (reference_profile_fd != -1) { 726 AddArg("--reference-profile-file-fd=" + std::to_string(reference_profile_fd.get())); 727 } 728 729 for (const unique_fd& fd : profile_fds) { 730 AddArg("--profile-file-fd=" + std::to_string(fd.get())); 731 } 732 733 for (const unique_fd& fd : apk_fds) { 734 AddArg("--apk-fd=" + std::to_string(fd.get())); 735 } 736 737 for (const std::string& dex_location : dex_locations) { 738 AddArg("--dex-location=" + dex_location); 739 } 740 741 if (copy_and_update) { 742 AddArg("--copy-and-update-profile-key"); 743 } 744 745 if (store_aggregation_counters) { 746 AddArg("--store-aggregation-counters"); 747 } 748 749 // Do not add after dex2oat_flags, they should override others for debugging. 750 PrepareArgs(profman_bin); 751 } 752 753 void SetupMerge(const std::vector<unique_fd>& profiles_fd, 754 const unique_fd& reference_profile_fd, 755 const std::vector<unique_fd>& apk_fds = std::vector<unique_fd>(), 756 const std::vector<std::string>& dex_locations = std::vector<std::string>(), 757 bool store_aggregation_counters = false) { 758 SetupArgs(profiles_fd, 759 reference_profile_fd, 760 apk_fds, 761 dex_locations, 762 /*copy_and_update=*/false, 763 store_aggregation_counters); 764 } 765 766 void SetupCopyAndUpdate(unique_fd&& profile_fd, 767 unique_fd&& reference_profile_fd, 768 unique_fd&& apk_fd, 769 const std::string& dex_location) { 770 // The fds need to stay open longer than the scope of the function, so put them into a local 771 // variable vector. 772 profiles_fd_.push_back(std::move(profile_fd)); 773 apk_fds_.push_back(std::move(apk_fd)); 774 reference_profile_fd_ = std::move(reference_profile_fd); 775 std::vector<std::string> dex_locations = {dex_location}; 776 SetupArgs(profiles_fd_, 777 reference_profile_fd_, 778 apk_fds_, 779 dex_locations, 780 /*copy_and_update=*/true, 781 /*store_aggregation_counters=*/false); 782 } 783 784 void SetupDump(const std::vector<unique_fd>& profiles_fd, 785 const unique_fd& reference_profile_fd, 786 const std::vector<std::string>& dex_locations, 787 const std::vector<unique_fd>& apk_fds, 788 const unique_fd& output_fd) { 789 AddArg("--dump-only"); 790 AddArg(StringPrintf("--dump-output-to-fd=%d", output_fd.get())); 791 SetupArgs(profiles_fd, 792 reference_profile_fd, 793 apk_fds, 794 dex_locations, 795 /*copy_and_update=*/false, 796 /*store_aggregation_counters=*/false); 797 } 798 799 void Exec() { 800 ExecVHelper::Exec(DexoptReturnCodes::kProfmanExec); 801 } 802 803 private: 804 unique_fd reference_profile_fd_; 805 std::vector<unique_fd> profiles_fd_; 806 std::vector<unique_fd> apk_fds_; 807 }; 808 809 810 811 // Decides if profile guided compilation is needed or not based on existing profiles. 812 // The location is the package name for primary apks or the dex path for secondary dex files. 813 // Returns true if there is enough information in the current profiles that makes it 814 // worth to recompile the given location. 815 // If the return value is true all the current profiles would have been merged into 816 // the reference profiles accessible with open_reference_profile(). 817 static bool analyze_profiles(uid_t uid, const std::string& package_name, 818 const std::string& location, bool is_secondary_dex) { 819 std::vector<unique_fd> profiles_fd; 820 unique_fd reference_profile_fd; 821 open_profile_files(uid, package_name, location, is_secondary_dex, 822 &profiles_fd, &reference_profile_fd); 823 if (profiles_fd.empty() || (reference_profile_fd.get() < 0)) { 824 // Skip profile guided compilation because no profiles were found. 825 // Or if the reference profile info couldn't be opened. 826 return false; 827 } 828 829 RunProfman profman_merge; 830 profman_merge.SetupMerge(profiles_fd, reference_profile_fd); 831 pid_t pid = fork(); 832 if (pid == 0) { 833 /* child -- drop privileges before continuing */ 834 drop_capabilities(uid); 835 profman_merge.Exec(); 836 } 837 /* parent */ 838 int return_code = wait_child(pid); 839 bool need_to_compile = false; 840 bool should_clear_current_profiles = false; 841 bool should_clear_reference_profile = false; 842 if (!WIFEXITED(return_code)) { 843 LOG(WARNING) << "profman failed for location " << location << ": " << return_code; 844 } else { 845 return_code = WEXITSTATUS(return_code); 846 switch (return_code) { 847 case PROFMAN_BIN_RETURN_CODE_COMPILE: 848 need_to_compile = true; 849 should_clear_current_profiles = true; 850 should_clear_reference_profile = false; 851 break; 852 case PROFMAN_BIN_RETURN_CODE_SKIP_COMPILATION: 853 need_to_compile = false; 854 should_clear_current_profiles = false; 855 should_clear_reference_profile = false; 856 break; 857 case PROFMAN_BIN_RETURN_CODE_BAD_PROFILES: 858 LOG(WARNING) << "Bad profiles for location " << location; 859 need_to_compile = false; 860 should_clear_current_profiles = true; 861 should_clear_reference_profile = true; 862 break; 863 case PROFMAN_BIN_RETURN_CODE_ERROR_IO: // fall-through 864 case PROFMAN_BIN_RETURN_CODE_ERROR_LOCKING: 865 // Temporary IO problem (e.g. locking). Ignore but log a warning. 866 LOG(WARNING) << "IO error while reading profiles for location " << location; 867 need_to_compile = false; 868 should_clear_current_profiles = false; 869 should_clear_reference_profile = false; 870 break; 871 default: 872 // Unknown return code or error. Unlink profiles. 873 LOG(WARNING) << "Unknown error code while processing profiles for location " 874 << location << ": " << return_code; 875 need_to_compile = false; 876 should_clear_current_profiles = true; 877 should_clear_reference_profile = true; 878 break; 879 } 880 } 881 882 if (should_clear_current_profiles) { 883 if (is_secondary_dex) { 884 // For secondary dex files, the owning user is the current user. 885 clear_current_profile(package_name, location, multiuser_get_user_id(uid), 886 is_secondary_dex); 887 } else { 888 clear_primary_current_profiles(package_name, location); 889 } 890 } 891 if (should_clear_reference_profile) { 892 clear_reference_profile(package_name, location, is_secondary_dex); 893 } 894 return need_to_compile; 895 } 896 897 // Decides if profile guided compilation is needed or not based on existing profiles. 898 // The analysis is done for the primary apks of the given package. 899 // Returns true if there is enough information in the current profiles that makes it 900 // worth to recompile the package. 901 // If the return value is true all the current profiles would have been merged into 902 // the reference profiles accessible with open_reference_profile(). 903 bool analyze_primary_profiles(uid_t uid, const std::string& package_name, 904 const std::string& profile_name) { 905 return analyze_profiles(uid, package_name, profile_name, /*is_secondary_dex*/false); 906 } 907 908 bool dump_profiles(int32_t uid, const std::string& pkgname, const std::string& profile_name, 909 const std::string& code_path) { 910 std::vector<unique_fd> profile_fds; 911 unique_fd reference_profile_fd; 912 std::string out_file_name = StringPrintf("/data/misc/profman/%s-%s.txt", 913 pkgname.c_str(), profile_name.c_str()); 914 915 open_profile_files(uid, pkgname, profile_name, /*is_secondary_dex*/false, 916 &profile_fds, &reference_profile_fd); 917 918 const bool has_reference_profile = (reference_profile_fd.get() != -1); 919 const bool has_profiles = !profile_fds.empty(); 920 921 if (!has_reference_profile && !has_profiles) { 922 LOG(ERROR) << "profman dump: no profiles to dump for " << pkgname; 923 return false; 924 } 925 926 unique_fd output_fd(open(out_file_name.c_str(), 927 O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW, 0644)); 928 if (fchmod(output_fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) { 929 LOG(ERROR) << "installd cannot chmod file for dump_profile" << out_file_name; 930 return false; 931 } 932 933 std::vector<std::string> dex_locations; 934 std::vector<unique_fd> apk_fds; 935 unique_fd apk_fd(open(code_path.c_str(), O_RDONLY | O_NOFOLLOW)); 936 if (apk_fd == -1) { 937 PLOG(ERROR) << "installd cannot open " << code_path.c_str(); 938 return false; 939 } 940 dex_locations.push_back(get_location_from_path(code_path.c_str())); 941 apk_fds.push_back(std::move(apk_fd)); 942 943 944 RunProfman profman_dump; 945 profman_dump.SetupDump(profile_fds, reference_profile_fd, dex_locations, apk_fds, output_fd); 946 pid_t pid = fork(); 947 if (pid == 0) { 948 /* child -- drop privileges before continuing */ 949 drop_capabilities(uid); 950 profman_dump.Exec(); 951 } 952 /* parent */ 953 int return_code = wait_child(pid); 954 if (!WIFEXITED(return_code)) { 955 LOG(WARNING) << "profman failed for package " << pkgname << ": " 956 << return_code; 957 return false; 958 } 959 return true; 960 } 961 962 bool copy_system_profile(const std::string& system_profile, 963 uid_t packageUid, const std::string& package_name, const std::string& profile_name) { 964 unique_fd in_fd(open(system_profile.c_str(), O_RDONLY | O_NOFOLLOW | O_CLOEXEC)); 965 unique_fd out_fd(open_reference_profile(packageUid, 966 package_name, 967 profile_name, 968 /*read_write*/ true, 969 /*secondary*/ false)); 970 if (in_fd.get() < 0) { 971 PLOG(WARNING) << "Could not open profile " << system_profile; 972 return false; 973 } 974 if (out_fd.get() < 0) { 975 PLOG(WARNING) << "Could not open profile " << package_name; 976 return false; 977 } 978 979 // As a security measure we want to write the profile information with the reduced capabilities 980 // of the package user id. So we fork and drop capabilities in the child. 981 pid_t pid = fork(); 982 if (pid == 0) { 983 /* child -- drop privileges before continuing */ 984 drop_capabilities(packageUid); 985 986 if (flock(out_fd.get(), LOCK_EX | LOCK_NB) != 0) { 987 if (errno != EWOULDBLOCK) { 988 PLOG(WARNING) << "Error locking profile " << package_name; 989 } 990 // This implies that the app owning this profile is running 991 // (and has acquired the lock). 992 // 993 // The app never acquires the lock for the reference profiles of primary apks. 994 // Only dex2oat from installd will do that. Since installd is single threaded 995 // we should not see this case. Nevertheless be prepared for it. 996 PLOG(WARNING) << "Failed to flock " << package_name; 997 return false; 998 } 999 1000 bool truncated = ftruncate(out_fd.get(), 0) == 0; 1001 if (!truncated) { 1002 PLOG(WARNING) << "Could not truncate " << package_name; 1003 } 1004 1005 // Copy over data. 1006 static constexpr size_t kBufferSize = 4 * 1024; 1007 char buffer[kBufferSize]; 1008 while (true) { 1009 ssize_t bytes = read(in_fd.get(), buffer, kBufferSize); 1010 if (bytes == 0) { 1011 break; 1012 } 1013 write(out_fd.get(), buffer, bytes); 1014 } 1015 if (flock(out_fd.get(), LOCK_UN) != 0) { 1016 PLOG(WARNING) << "Error unlocking profile " << package_name; 1017 } 1018 // Use _exit since we don't want to run the global destructors in the child. 1019 // b/62597429 1020 _exit(0); 1021 } 1022 /* parent */ 1023 int return_code = wait_child(pid); 1024 return return_code == 0; 1025 } 1026 1027 static std::string replace_file_extension(const std::string& oat_path, const std::string& new_ext) { 1028 // A standard dalvik-cache entry. Replace ".dex" with `new_ext`. 1029 if (EndsWith(oat_path, ".dex")) { 1030 std::string new_path = oat_path; 1031 new_path.replace(new_path.length() - strlen(".dex"), strlen(".dex"), new_ext); 1032 CHECK(EndsWith(new_path, new_ext)); 1033 return new_path; 1034 } 1035 1036 // An odex entry. Not that this may not be an extension, e.g., in the OTA 1037 // case (where the base name will have an extension for the B artifact). 1038 size_t odex_pos = oat_path.rfind(".odex"); 1039 if (odex_pos != std::string::npos) { 1040 std::string new_path = oat_path; 1041 new_path.replace(odex_pos, strlen(".odex"), new_ext); 1042 CHECK_NE(new_path.find(new_ext), std::string::npos); 1043 return new_path; 1044 } 1045 1046 // Don't know how to handle this. 1047 return ""; 1048 } 1049 1050 // Translate the given oat path to an art (app image) path. An empty string 1051 // denotes an error. 1052 static std::string create_image_filename(const std::string& oat_path) { 1053 return replace_file_extension(oat_path, ".art"); 1054 } 1055 1056 // Translate the given oat path to a vdex path. An empty string denotes an error. 1057 static std::string create_vdex_filename(const std::string& oat_path) { 1058 return replace_file_extension(oat_path, ".vdex"); 1059 } 1060 1061 static int open_output_file(const char* file_name, bool recreate, int permissions) { 1062 int flags = O_RDWR | O_CREAT; 1063 if (recreate) { 1064 if (unlink(file_name) < 0) { 1065 if (errno != ENOENT) { 1066 PLOG(ERROR) << "open_output_file: Couldn't unlink " << file_name; 1067 } 1068 } 1069 flags |= O_EXCL; 1070 } 1071 return open(file_name, flags, permissions); 1072 } 1073 1074 static bool set_permissions_and_ownership( 1075 int fd, bool is_public, int uid, const char* path, bool is_secondary_dex) { 1076 // Primary apks are owned by the system. Secondary dex files are owned by the app. 1077 int owning_uid = is_secondary_dex ? uid : AID_SYSTEM; 1078 if (fchmod(fd, 1079 S_IRUSR|S_IWUSR|S_IRGRP | 1080 (is_public ? S_IROTH : 0)) < 0) { 1081 ALOGE("installd cannot chmod '%s' during dexopt\n", path); 1082 return false; 1083 } else if (fchown(fd, owning_uid, uid) < 0) { 1084 ALOGE("installd cannot chown '%s' during dexopt\n", path); 1085 return false; 1086 } 1087 return true; 1088 } 1089 1090 static bool IsOutputDalvikCache(const char* oat_dir) { 1091 // InstallerConnection.java (which invokes installd) transforms Java null arguments 1092 // into '!'. Play it safe by handling it both. 1093 // TODO: ensure we never get null. 1094 // TODO: pass a flag instead of inferring if the output is dalvik cache. 1095 return oat_dir == nullptr || oat_dir[0] == '!'; 1096 } 1097 1098 // Best-effort check whether we can fit the the path into our buffers. 1099 // Note: the cache path will require an additional 5 bytes for ".swap", but we'll try to run 1100 // without a swap file, if necessary. Reference profiles file also add an extra ".prof" 1101 // extension to the cache path (5 bytes). 1102 // TODO(calin): move away from char* buffers and PKG_PATH_MAX. 1103 static bool validate_dex_path_size(const std::string& dex_path) { 1104 if (dex_path.size() >= (PKG_PATH_MAX - 8)) { 1105 LOG(ERROR) << "dex_path too long: " << dex_path; 1106 return false; 1107 } 1108 return true; 1109 } 1110 1111 static bool create_oat_out_path(const char* apk_path, const char* instruction_set, 1112 const char* oat_dir, bool is_secondary_dex, /*out*/ char* out_oat_path) { 1113 if (!validate_dex_path_size(apk_path)) { 1114 return false; 1115 } 1116 1117 if (!IsOutputDalvikCache(oat_dir)) { 1118 // Oat dirs for secondary dex files are already validated. 1119 if (!is_secondary_dex && validate_apk_path(oat_dir)) { 1120 ALOGE("cannot validate apk path with oat_dir '%s'\n", oat_dir); 1121 return false; 1122 } 1123 if (!calculate_oat_file_path(out_oat_path, oat_dir, apk_path, instruction_set)) { 1124 return false; 1125 } 1126 } else { 1127 if (!create_cache_path(out_oat_path, apk_path, instruction_set)) { 1128 return false; 1129 } 1130 } 1131 return true; 1132 } 1133 1134 // Helper for fd management. This is similar to a unique_fd in that it closes the file descriptor 1135 // on destruction. It will also run the given cleanup (unless told not to) after closing. 1136 // 1137 // Usage example: 1138 // 1139 // Dex2oatFileWrapper file(open(...), 1140 // [name]() { 1141 // unlink(name.c_str()); 1142 // }); 1143 // // Note: care needs to be taken about name, as it needs to have a lifetime longer than the 1144 // wrapper if captured as a reference. 1145 // 1146 // if (file.get() == -1) { 1147 // // Error opening... 1148 // } 1149 // 1150 // ... 1151 // if (error) { 1152 // // At this point, when the Dex2oatFileWrapper is destructed, the cleanup function will run 1153 // // and delete the file (after the fd is closed). 1154 // return -1; 1155 // } 1156 // 1157 // (Success case) 1158 // file.SetCleanup(false); 1159 // // At this point, when the Dex2oatFileWrapper is destructed, the cleanup function will not run 1160 // // (leaving the file around; after the fd is closed). 1161 // 1162 class Dex2oatFileWrapper { 1163 public: 1164 Dex2oatFileWrapper() : value_(-1), cleanup_(), do_cleanup_(true), auto_close_(true) { 1165 } 1166 1167 Dex2oatFileWrapper(int value, std::function<void ()> cleanup) 1168 : value_(value), cleanup_(cleanup), do_cleanup_(true), auto_close_(true) {} 1169 1170 Dex2oatFileWrapper(Dex2oatFileWrapper&& other) { 1171 value_ = other.value_; 1172 cleanup_ = other.cleanup_; 1173 do_cleanup_ = other.do_cleanup_; 1174 auto_close_ = other.auto_close_; 1175 other.release(); 1176 } 1177 1178 Dex2oatFileWrapper& operator=(Dex2oatFileWrapper&& other) { 1179 value_ = other.value_; 1180 cleanup_ = other.cleanup_; 1181 do_cleanup_ = other.do_cleanup_; 1182 auto_close_ = other.auto_close_; 1183 other.release(); 1184 return *this; 1185 } 1186 1187 ~Dex2oatFileWrapper() { 1188 reset(-1); 1189 } 1190 1191 int get() { 1192 return value_; 1193 } 1194 1195 void SetCleanup(bool cleanup) { 1196 do_cleanup_ = cleanup; 1197 } 1198 1199 void reset(int new_value) { 1200 if (auto_close_ && value_ >= 0) { 1201 close(value_); 1202 } 1203 if (do_cleanup_ && cleanup_ != nullptr) { 1204 cleanup_(); 1205 } 1206 1207 value_ = new_value; 1208 } 1209 1210 void reset(int new_value, std::function<void ()> new_cleanup) { 1211 if (auto_close_ && value_ >= 0) { 1212 close(value_); 1213 } 1214 if (do_cleanup_ && cleanup_ != nullptr) { 1215 cleanup_(); 1216 } 1217 1218 value_ = new_value; 1219 cleanup_ = new_cleanup; 1220 } 1221 1222 void DisableAutoClose() { 1223 auto_close_ = false; 1224 } 1225 1226 private: 1227 void release() { 1228 value_ = -1; 1229 do_cleanup_ = false; 1230 cleanup_ = nullptr; 1231 } 1232 int value_; 1233 std::function<void ()> cleanup_; 1234 bool do_cleanup_; 1235 bool auto_close_; 1236 }; 1237 1238 // (re)Creates the app image if needed. 1239 Dex2oatFileWrapper maybe_open_app_image(const char* out_oat_path, 1240 bool generate_app_image, bool is_public, int uid, bool is_secondary_dex) { 1241 1242 // We don't create an image for secondary dex files. 1243 if (is_secondary_dex) { 1244 return Dex2oatFileWrapper(); 1245 } 1246 1247 const std::string image_path = create_image_filename(out_oat_path); 1248 if (image_path.empty()) { 1249 // Happens when the out_oat_path has an unknown extension. 1250 return Dex2oatFileWrapper(); 1251 } 1252 1253 // In case there is a stale image, remove it now. Ignore any error. 1254 unlink(image_path.c_str()); 1255 1256 // Not enabled, exit. 1257 if (!generate_app_image) { 1258 return Dex2oatFileWrapper(); 1259 } 1260 std::string app_image_format = GetProperty("dalvik.vm.appimageformat", ""); 1261 if (app_image_format.empty()) { 1262 return Dex2oatFileWrapper(); 1263 } 1264 // Recreate is true since we do not want to modify a mapped image. If the app is 1265 // already running and we modify the image file, it can cause crashes (b/27493510). 1266 Dex2oatFileWrapper wrapper_fd( 1267 open_output_file(image_path.c_str(), true /*recreate*/, 0600 /*permissions*/), 1268 [image_path]() { unlink(image_path.c_str()); }); 1269 if (wrapper_fd.get() < 0) { 1270 // Could not create application image file. Go on since we can compile without it. 1271 LOG(ERROR) << "installd could not create '" << image_path 1272 << "' for image file during dexopt"; 1273 // If we have a valid image file path but no image fd, explicitly erase the image file. 1274 if (unlink(image_path.c_str()) < 0) { 1275 if (errno != ENOENT) { 1276 PLOG(ERROR) << "Couldn't unlink image file " << image_path; 1277 } 1278 } 1279 } else if (!set_permissions_and_ownership( 1280 wrapper_fd.get(), is_public, uid, image_path.c_str(), is_secondary_dex)) { 1281 ALOGE("installd cannot set owner '%s' for image during dexopt\n", image_path.c_str()); 1282 wrapper_fd.reset(-1); 1283 } 1284 1285 return wrapper_fd; 1286 } 1287 1288 // Creates the dexopt swap file if necessary and return its fd. 1289 // Returns -1 if there's no need for a swap or in case of errors. 1290 unique_fd maybe_open_dexopt_swap_file(const char* out_oat_path) { 1291 if (!ShouldUseSwapFileForDexopt()) { 1292 return invalid_unique_fd(); 1293 } 1294 auto swap_file_name = std::string(out_oat_path) + ".swap"; 1295 unique_fd swap_fd(open_output_file( 1296 swap_file_name.c_str(), /*recreate*/true, /*permissions*/0600)); 1297 if (swap_fd.get() < 0) { 1298 // Could not create swap file. Optimistically go on and hope that we can compile 1299 // without it. 1300 ALOGE("installd could not create '%s' for swap during dexopt\n", swap_file_name.c_str()); 1301 } else { 1302 // Immediately unlink. We don't really want to hit flash. 1303 if (unlink(swap_file_name.c_str()) < 0) { 1304 PLOG(ERROR) << "Couldn't unlink swap file " << swap_file_name; 1305 } 1306 } 1307 return swap_fd; 1308 } 1309 1310 // Opens the reference profiles if needed. 1311 // Note that the reference profile might not exist so it's OK if the fd will be -1. 1312 Dex2oatFileWrapper maybe_open_reference_profile(const std::string& pkgname, 1313 const std::string& dex_path, const char* profile_name, bool profile_guided, 1314 bool is_public, int uid, bool is_secondary_dex) { 1315 // If we are not profile guided compilation, or we are compiling system server 1316 // do not bother to open the profiles; we won't be using them. 1317 if (!profile_guided || (pkgname[0] == '*')) { 1318 return Dex2oatFileWrapper(); 1319 } 1320 1321 // If this is a secondary dex path which is public do not open the profile. 1322 // We cannot compile public secondary dex paths with profiles. That's because 1323 // it will expose how the dex files are used by their owner. 1324 // 1325 // Note that the PackageManager is responsible to set the is_public flag for 1326 // primary apks and we do not check it here. In some cases, e.g. when 1327 // compiling with a public profile from the .dm file the PackageManager will 1328 // set is_public toghether with the profile guided compilation. 1329 if (is_secondary_dex && is_public) { 1330 return Dex2oatFileWrapper(); 1331 } 1332 1333 // Open reference profile in read only mode as dex2oat does not get write permissions. 1334 std::string location; 1335 if (is_secondary_dex) { 1336 location = dex_path; 1337 } else { 1338 if (profile_name == nullptr) { 1339 // This path is taken for system server re-compilation lunched from ZygoteInit. 1340 return Dex2oatFileWrapper(); 1341 } else { 1342 location = profile_name; 1343 } 1344 } 1345 unique_fd ufd = open_reference_profile(uid, pkgname, location, /*read_write*/false, 1346 is_secondary_dex); 1347 const auto& cleanup = [pkgname, location, is_secondary_dex]() { 1348 clear_reference_profile(pkgname, location, is_secondary_dex); 1349 }; 1350 return Dex2oatFileWrapper(ufd.release(), cleanup); 1351 } 1352 1353 // Opens the vdex files and assigns the input fd to in_vdex_wrapper_fd and the output fd to 1354 // out_vdex_wrapper_fd. Returns true for success or false in case of errors. 1355 bool open_vdex_files_for_dex2oat(const char* apk_path, const char* out_oat_path, int dexopt_needed, 1356 const char* instruction_set, bool is_public, int uid, bool is_secondary_dex, 1357 bool profile_guided, Dex2oatFileWrapper* in_vdex_wrapper_fd, 1358 Dex2oatFileWrapper* out_vdex_wrapper_fd) { 1359 CHECK(in_vdex_wrapper_fd != nullptr); 1360 CHECK(out_vdex_wrapper_fd != nullptr); 1361 // Open the existing VDEX. We do this before creating the new output VDEX, which will 1362 // unlink the old one. 1363 char in_odex_path[PKG_PATH_MAX]; 1364 int dexopt_action = abs(dexopt_needed); 1365 bool is_odex_location = dexopt_needed < 0; 1366 std::string in_vdex_path_str; 1367 1368 // Infer the name of the output VDEX. 1369 const std::string out_vdex_path_str = create_vdex_filename(out_oat_path); 1370 if (out_vdex_path_str.empty()) { 1371 return false; 1372 } 1373 1374 bool update_vdex_in_place = false; 1375 if (dexopt_action != DEX2OAT_FROM_SCRATCH) { 1376 // Open the possibly existing vdex. If none exist, we pass -1 to dex2oat for input-vdex-fd. 1377 const char* path = nullptr; 1378 if (is_odex_location) { 1379 if (calculate_odex_file_path(in_odex_path, apk_path, instruction_set)) { 1380 path = in_odex_path; 1381 } else { 1382 ALOGE("installd cannot compute input vdex location for '%s'\n", apk_path); 1383 return false; 1384 } 1385 } else { 1386 path = out_oat_path; 1387 } 1388 in_vdex_path_str = create_vdex_filename(path); 1389 if (in_vdex_path_str.empty()) { 1390 ALOGE("installd cannot compute input vdex location for '%s'\n", path); 1391 return false; 1392 } 1393 // We can update in place when all these conditions are met: 1394 // 1) The vdex location to write to is the same as the vdex location to read (vdex files 1395 // on /system typically cannot be updated in place). 1396 // 2) We dex2oat due to boot image change, because we then know the existing vdex file 1397 // cannot be currently used by a running process. 1398 // 3) We are not doing a profile guided compilation, because dexlayout requires two 1399 // different vdex files to operate. 1400 update_vdex_in_place = 1401 (in_vdex_path_str == out_vdex_path_str) && 1402 (dexopt_action == DEX2OAT_FOR_BOOT_IMAGE) && 1403 !profile_guided; 1404 if (update_vdex_in_place) { 1405 // Open the file read-write to be able to update it. 1406 in_vdex_wrapper_fd->reset(open(in_vdex_path_str.c_str(), O_RDWR, 0)); 1407 if (in_vdex_wrapper_fd->get() == -1) { 1408 // If we failed to open the file, we cannot update it in place. 1409 update_vdex_in_place = false; 1410 } 1411 } else { 1412 in_vdex_wrapper_fd->reset(open(in_vdex_path_str.c_str(), O_RDONLY, 0)); 1413 } 1414 } 1415 1416 // If we are updating the vdex in place, we do not need to recreate a vdex, 1417 // and can use the same existing one. 1418 if (update_vdex_in_place) { 1419 // We unlink the file in case the invocation of dex2oat fails, to ensure we don't 1420 // have bogus stale vdex files. 1421 out_vdex_wrapper_fd->reset( 1422 in_vdex_wrapper_fd->get(), 1423 [out_vdex_path_str]() { unlink(out_vdex_path_str.c_str()); }); 1424 // Disable auto close for the in wrapper fd (it will be done when destructing the out 1425 // wrapper). 1426 in_vdex_wrapper_fd->DisableAutoClose(); 1427 } else { 1428 out_vdex_wrapper_fd->reset( 1429 open_output_file(out_vdex_path_str.c_str(), /*recreate*/true, /*permissions*/0644), 1430 [out_vdex_path_str]() { unlink(out_vdex_path_str.c_str()); }); 1431 if (out_vdex_wrapper_fd->get() < 0) { 1432 ALOGE("installd cannot open vdex'%s' during dexopt\n", out_vdex_path_str.c_str()); 1433 return false; 1434 } 1435 } 1436 if (!set_permissions_and_ownership(out_vdex_wrapper_fd->get(), is_public, uid, 1437 out_vdex_path_str.c_str(), is_secondary_dex)) { 1438 ALOGE("installd cannot set owner '%s' for vdex during dexopt\n", out_vdex_path_str.c_str()); 1439 return false; 1440 } 1441 1442 // If we got here we successfully opened the vdex files. 1443 return true; 1444 } 1445 1446 // Opens the output oat file for the given apk. 1447 // If successful it stores the output path into out_oat_path and returns true. 1448 Dex2oatFileWrapper open_oat_out_file(const char* apk_path, const char* oat_dir, 1449 bool is_public, int uid, const char* instruction_set, bool is_secondary_dex, 1450 char* out_oat_path) { 1451 if (!create_oat_out_path(apk_path, instruction_set, oat_dir, is_secondary_dex, out_oat_path)) { 1452 return Dex2oatFileWrapper(); 1453 } 1454 const std::string out_oat_path_str(out_oat_path); 1455 Dex2oatFileWrapper wrapper_fd( 1456 open_output_file(out_oat_path, /*recreate*/true, /*permissions*/0644), 1457 [out_oat_path_str]() { unlink(out_oat_path_str.c_str()); }); 1458 if (wrapper_fd.get() < 0) { 1459 PLOG(ERROR) << "installd cannot open output during dexopt" << out_oat_path; 1460 } else if (!set_permissions_and_ownership( 1461 wrapper_fd.get(), is_public, uid, out_oat_path, is_secondary_dex)) { 1462 ALOGE("installd cannot set owner '%s' for output during dexopt\n", out_oat_path); 1463 wrapper_fd.reset(-1); 1464 } 1465 return wrapper_fd; 1466 } 1467 1468 // Creates RDONLY fds for oat and vdex files, if exist. 1469 // Returns false if it fails to create oat out path for the given apk path. 1470 // Note that the method returns true even if the files could not be opened. 1471 bool maybe_open_oat_and_vdex_file(const std::string& apk_path, 1472 const std::string& oat_dir, 1473 const std::string& instruction_set, 1474 bool is_secondary_dex, 1475 unique_fd* oat_file_fd, 1476 unique_fd* vdex_file_fd) { 1477 char oat_path[PKG_PATH_MAX]; 1478 if (!create_oat_out_path(apk_path.c_str(), 1479 instruction_set.c_str(), 1480 oat_dir.c_str(), 1481 is_secondary_dex, 1482 oat_path)) { 1483 LOG(ERROR) << "Could not create oat out path for " 1484 << apk_path << " with oat dir " << oat_dir; 1485 return false; 1486 } 1487 oat_file_fd->reset(open(oat_path, O_RDONLY)); 1488 if (oat_file_fd->get() < 0) { 1489 PLOG(INFO) << "installd cannot open oat file during dexopt" << oat_path; 1490 } 1491 1492 std::string vdex_filename = create_vdex_filename(oat_path); 1493 vdex_file_fd->reset(open(vdex_filename.c_str(), O_RDONLY)); 1494 if (vdex_file_fd->get() < 0) { 1495 PLOG(INFO) << "installd cannot open vdex file during dexopt" << vdex_filename; 1496 } 1497 1498 return true; 1499 } 1500 1501 // Updates the access times of out_oat_path based on those from apk_path. 1502 void update_out_oat_access_times(const char* apk_path, const char* out_oat_path) { 1503 struct stat input_stat; 1504 memset(&input_stat, 0, sizeof(input_stat)); 1505 if (stat(apk_path, &input_stat) != 0) { 1506 PLOG(ERROR) << "Could not stat " << apk_path << " during dexopt"; 1507 return; 1508 } 1509 1510 struct utimbuf ut; 1511 ut.actime = input_stat.st_atime; 1512 ut.modtime = input_stat.st_mtime; 1513 if (utime(out_oat_path, &ut) != 0) { 1514 PLOG(WARNING) << "Could not update access times for " << apk_path << " during dexopt"; 1515 } 1516 } 1517 1518 // Runs (execv) dexoptanalyzer on the given arguments. 1519 // The analyzer will check if the dex_file needs to be (re)compiled to match the compiler_filter. 1520 // If this is for a profile guided compilation, profile_was_updated will tell whether or not 1521 // the profile has changed. 1522 class RunDexoptAnalyzer : public ExecVHelper { 1523 public: 1524 RunDexoptAnalyzer(const std::string& dex_file, 1525 int vdex_fd, 1526 int oat_fd, 1527 int zip_fd, 1528 const std::string& instruction_set, 1529 const std::string& compiler_filter, 1530 bool profile_was_updated, 1531 bool downgrade, 1532 const char* class_loader_context, 1533 const std::string& class_loader_context_fds) { 1534 CHECK_GE(zip_fd, 0); 1535 1536 // We always run the analyzer in the background job. 1537 const char* dexoptanalyzer_bin = select_execution_binary( 1538 kDexoptanalyzerPath, kDexoptanalyzerDebugPath, /*background_job_compile=*/ true); 1539 1540 std::string dex_file_arg = "--dex-file=" + dex_file; 1541 std::string oat_fd_arg = "--oat-fd=" + std::to_string(oat_fd); 1542 std::string vdex_fd_arg = "--vdex-fd=" + std::to_string(vdex_fd); 1543 std::string zip_fd_arg = "--zip-fd=" + std::to_string(zip_fd); 1544 std::string isa_arg = "--isa=" + instruction_set; 1545 std::string compiler_filter_arg = "--compiler-filter=" + compiler_filter; 1546 const char* assume_profile_changed = "--assume-profile-changed"; 1547 const char* downgrade_flag = "--downgrade"; 1548 std::string class_loader_context_arg = "--class-loader-context="; 1549 if (class_loader_context != nullptr) { 1550 class_loader_context_arg += class_loader_context; 1551 } 1552 std::string class_loader_context_fds_arg = "--class-loader-context-fds="; 1553 if (!class_loader_context_fds.empty()) { 1554 class_loader_context_fds_arg += class_loader_context_fds; 1555 } 1556 1557 // program name, dex file, isa, filter 1558 AddArg(dex_file_arg); 1559 AddArg(isa_arg); 1560 AddArg(compiler_filter_arg); 1561 if (oat_fd >= 0) { 1562 AddArg(oat_fd_arg); 1563 } 1564 if (vdex_fd >= 0) { 1565 AddArg(vdex_fd_arg); 1566 } 1567 AddArg(zip_fd_arg); 1568 if (profile_was_updated) { 1569 AddArg(assume_profile_changed); 1570 } 1571 if (downgrade) { 1572 AddArg(downgrade_flag); 1573 } 1574 if (class_loader_context != nullptr) { 1575 AddArg(class_loader_context_arg); 1576 if (!class_loader_context_fds.empty()) { 1577 AddArg(class_loader_context_fds_arg); 1578 } 1579 } 1580 1581 PrepareArgs(dexoptanalyzer_bin); 1582 } 1583 1584 // Dexoptanalyzer mode which flattens the given class loader context and 1585 // prints a list of its dex files in that flattened order. 1586 RunDexoptAnalyzer(const char* class_loader_context) { 1587 CHECK(class_loader_context != nullptr); 1588 1589 // We always run the analyzer in the background job. 1590 const char* dexoptanalyzer_bin = select_execution_binary( 1591 kDexoptanalyzerPath, kDexoptanalyzerDebugPath, /*background_job_compile=*/ true); 1592 1593 AddArg("--flatten-class-loader-context"); 1594 AddArg(std::string("--class-loader-context=") + class_loader_context); 1595 PrepareArgs(dexoptanalyzer_bin); 1596 } 1597 }; 1598 1599 // Prepares the oat dir for the secondary dex files. 1600 static bool prepare_secondary_dex_oat_dir(const std::string& dex_path, int uid, 1601 const char* instruction_set) { 1602 unsigned long dirIndex = dex_path.rfind('/'); 1603 if (dirIndex == std::string::npos) { 1604 LOG(ERROR ) << "Unexpected dir structure for secondary dex " << dex_path; 1605 return false; 1606 } 1607 std::string dex_dir = dex_path.substr(0, dirIndex); 1608 1609 // Create oat file output directory. 1610 mode_t oat_dir_mode = S_IRWXU | S_IRWXG | S_IXOTH; 1611 if (prepare_app_cache_dir(dex_dir, "oat", oat_dir_mode, uid, uid) != 0) { 1612 LOG(ERROR) << "Could not prepare oat dir for secondary dex: " << dex_path; 1613 return false; 1614 } 1615 1616 char oat_dir[PKG_PATH_MAX]; 1617 snprintf(oat_dir, PKG_PATH_MAX, "%s/oat", dex_dir.c_str()); 1618 1619 if (prepare_app_cache_dir(oat_dir, instruction_set, oat_dir_mode, uid, uid) != 0) { 1620 LOG(ERROR) << "Could not prepare oat/isa dir for secondary dex: " << dex_path; 1621 return false; 1622 } 1623 1624 return true; 1625 } 1626 1627 // Return codes for identifying the reason why dexoptanalyzer was not invoked when processing 1628 // secondary dex files. This return codes are returned by the child process created for 1629 // analyzing secondary dex files in process_secondary_dex_dexopt. 1630 1631 enum DexoptAnalyzerSkipCodes { 1632 // The dexoptanalyzer was not invoked because of validation or IO errors. 1633 // Specific errors are encoded in the name. 1634 kSecondaryDexDexoptAnalyzerSkippedValidatePath = 200, 1635 kSecondaryDexDexoptAnalyzerSkippedOpenZip = 201, 1636 kSecondaryDexDexoptAnalyzerSkippedPrepareDir = 202, 1637 kSecondaryDexDexoptAnalyzerSkippedOpenOutput = 203, 1638 kSecondaryDexDexoptAnalyzerSkippedFailExec = 204, 1639 // The dexoptanalyzer was not invoked because the dex file does not exist anymore. 1640 kSecondaryDexDexoptAnalyzerSkippedNoFile = 205, 1641 }; 1642 1643 // Verifies the result of analyzing secondary dex files from process_secondary_dex_dexopt. 1644 // If the result is valid returns true and sets dexopt_needed_out to a valid value. 1645 // Returns false for errors or unexpected result values. 1646 // The result is expected to be either one of SECONDARY_DEX_* codes or a valid exit code 1647 // of dexoptanalyzer. 1648 static bool process_secondary_dexoptanalyzer_result(const std::string& dex_path, int result, 1649 int* dexopt_needed_out, std::string* error_msg) { 1650 // The result values are defined in dexoptanalyzer. 1651 switch (result) { 1652 case 0: // dexoptanalyzer: no_dexopt_needed 1653 *dexopt_needed_out = NO_DEXOPT_NEEDED; return true; 1654 case 1: // dexoptanalyzer: dex2oat_from_scratch 1655 *dexopt_needed_out = DEX2OAT_FROM_SCRATCH; return true; 1656 case 4: // dexoptanalyzer: dex2oat_for_bootimage_odex 1657 *dexopt_needed_out = -DEX2OAT_FOR_BOOT_IMAGE; return true; 1658 case 5: // dexoptanalyzer: dex2oat_for_filter_odex 1659 *dexopt_needed_out = -DEX2OAT_FOR_FILTER; return true; 1660 case 2: // dexoptanalyzer: dex2oat_for_bootimage_oat 1661 case 3: // dexoptanalyzer: dex2oat_for_filter_oat 1662 *error_msg = StringPrintf("Dexoptanalyzer return the status of an oat file." 1663 " Expected odex file status for secondary dex %s" 1664 " : dexoptanalyzer result=%d", 1665 dex_path.c_str(), 1666 result); 1667 return false; 1668 } 1669 1670 // Use a second switch for enum switch-case analysis. 1671 switch (static_cast<DexoptAnalyzerSkipCodes>(result)) { 1672 case kSecondaryDexDexoptAnalyzerSkippedNoFile: 1673 // If the file does not exist there's no need for dexopt. 1674 *dexopt_needed_out = NO_DEXOPT_NEEDED; 1675 return true; 1676 1677 case kSecondaryDexDexoptAnalyzerSkippedValidatePath: 1678 *error_msg = "Dexoptanalyzer path validation failed"; 1679 return false; 1680 case kSecondaryDexDexoptAnalyzerSkippedOpenZip: 1681 *error_msg = "Dexoptanalyzer open zip failed"; 1682 return false; 1683 case kSecondaryDexDexoptAnalyzerSkippedPrepareDir: 1684 *error_msg = "Dexoptanalyzer dir preparation failed"; 1685 return false; 1686 case kSecondaryDexDexoptAnalyzerSkippedOpenOutput: 1687 *error_msg = "Dexoptanalyzer open output failed"; 1688 return false; 1689 case kSecondaryDexDexoptAnalyzerSkippedFailExec: 1690 *error_msg = "Dexoptanalyzer failed to execute"; 1691 return false; 1692 } 1693 1694 *error_msg = StringPrintf("Unexpected result from analyzing secondary dex %s result=%d", 1695 dex_path.c_str(), 1696 result); 1697 return false; 1698 } 1699 1700 enum SecondaryDexAccess { 1701 kSecondaryDexAccessReadOk = 0, 1702 kSecondaryDexAccessDoesNotExist = 1, 1703 kSecondaryDexAccessPermissionError = 2, 1704 kSecondaryDexAccessIOError = 3 1705 }; 1706 1707 static SecondaryDexAccess check_secondary_dex_access(const std::string& dex_path) { 1708 // Check if the path exists and can be read. If not, there's nothing to do. 1709 if (access(dex_path.c_str(), R_OK) == 0) { 1710 return kSecondaryDexAccessReadOk; 1711 } else { 1712 if (errno == ENOENT) { 1713 LOG(INFO) << "Secondary dex does not exist: " << dex_path; 1714 return kSecondaryDexAccessDoesNotExist; 1715 } else { 1716 PLOG(ERROR) << "Could not access secondary dex " << dex_path; 1717 return errno == EACCES 1718 ? kSecondaryDexAccessPermissionError 1719 : kSecondaryDexAccessIOError; 1720 } 1721 } 1722 } 1723 1724 static bool is_file_public(const std::string& filename) { 1725 struct stat file_stat; 1726 if (stat(filename.c_str(), &file_stat) == 0) { 1727 return (file_stat.st_mode & S_IROTH) != 0; 1728 } 1729 return false; 1730 } 1731 1732 // Create the oat file structure for the secondary dex 'dex_path' and assign 1733 // the individual path component to the 'out_' parameters. 1734 static bool create_secondary_dex_oat_layout(const std::string& dex_path, const std::string& isa, 1735 char* out_oat_dir, char* out_oat_isa_dir, char* out_oat_path, std::string* error_msg) { 1736 size_t dirIndex = dex_path.rfind('/'); 1737 if (dirIndex == std::string::npos) { 1738 *error_msg = std::string("Unexpected dir structure for dex file ").append(dex_path); 1739 return false; 1740 } 1741 // TODO(calin): we have similar computations in at lest 3 other places 1742 // (InstalldNativeService, otapropt and dexopt). Unify them and get rid of snprintf by 1743 // using string append. 1744 std::string apk_dir = dex_path.substr(0, dirIndex); 1745 snprintf(out_oat_dir, PKG_PATH_MAX, "%s/oat", apk_dir.c_str()); 1746 snprintf(out_oat_isa_dir, PKG_PATH_MAX, "%s/%s", out_oat_dir, isa.c_str()); 1747 1748 if (!create_oat_out_path(dex_path.c_str(), isa.c_str(), out_oat_dir, 1749 /*is_secondary_dex*/true, out_oat_path)) { 1750 *error_msg = std::string("Could not create oat path for secondary dex ").append(dex_path); 1751 return false; 1752 } 1753 return true; 1754 } 1755 1756 // Validate that the dexopt_flags contain a valid storage flag and convert that to an installd 1757 // recognized storage flags (FLAG_STORAGE_CE or FLAG_STORAGE_DE). 1758 static bool validate_dexopt_storage_flags(int dexopt_flags, 1759 int* out_storage_flag, 1760 std::string* error_msg) { 1761 if ((dexopt_flags & DEXOPT_STORAGE_CE) != 0) { 1762 *out_storage_flag = FLAG_STORAGE_CE; 1763 if ((dexopt_flags & DEXOPT_STORAGE_DE) != 0) { 1764 *error_msg = "Ambiguous secondary dex storage flag. Both, CE and DE, flags are set"; 1765 return false; 1766 } 1767 } else if ((dexopt_flags & DEXOPT_STORAGE_DE) != 0) { 1768 *out_storage_flag = FLAG_STORAGE_DE; 1769 } else { 1770 *error_msg = "Secondary dex storage flag must be set"; 1771 return false; 1772 } 1773 return true; 1774 } 1775 1776 static bool get_class_loader_context_dex_paths(const char* class_loader_context, int uid, 1777 /* out */ std::vector<std::string>* context_dex_paths) { 1778 if (class_loader_context == nullptr) { 1779 return true; 1780 } 1781 1782 LOG(DEBUG) << "Getting dex paths for context " << class_loader_context; 1783 1784 // Pipe to get the hash result back from our child process. 1785 unique_fd pipe_read, pipe_write; 1786 if (!Pipe(&pipe_read, &pipe_write)) { 1787 PLOG(ERROR) << "Failed to create pipe"; 1788 return false; 1789 } 1790 1791 pid_t pid = fork(); 1792 if (pid == 0) { 1793 // child -- drop privileges before continuing. 1794 drop_capabilities(uid); 1795 1796 // Route stdout to `pipe_write` 1797 while ((dup2(pipe_write, STDOUT_FILENO) == -1) && (errno == EINTR)) {} 1798 pipe_write.reset(); 1799 pipe_read.reset(); 1800 1801 RunDexoptAnalyzer run_dexopt_analyzer(class_loader_context); 1802 run_dexopt_analyzer.Exec(kSecondaryDexDexoptAnalyzerSkippedFailExec); 1803 } 1804 1805 /* parent */ 1806 pipe_write.reset(); 1807 1808 std::string str_dex_paths; 1809 if (!ReadFdToString(pipe_read, &str_dex_paths)) { 1810 PLOG(ERROR) << "Failed to read from pipe"; 1811 return false; 1812 } 1813 pipe_read.reset(); 1814 1815 int return_code = wait_child(pid); 1816 if (!WIFEXITED(return_code)) { 1817 PLOG(ERROR) << "Error waiting for child dexoptanalyzer process"; 1818 return false; 1819 } 1820 1821 constexpr int kFlattenClassLoaderContextSuccess = 50; 1822 return_code = WEXITSTATUS(return_code); 1823 if (return_code != kFlattenClassLoaderContextSuccess) { 1824 LOG(ERROR) << "Dexoptanalyzer could not flatten class loader context, code=" << return_code; 1825 return false; 1826 } 1827 1828 if (!str_dex_paths.empty()) { 1829 *context_dex_paths = android::base::Split(str_dex_paths, ":"); 1830 } 1831 return true; 1832 } 1833 1834 static int open_dex_paths(const std::vector<std::string>& dex_paths, 1835 /* out */ std::vector<unique_fd>* zip_fds, /* out */ std::string* error_msg) { 1836 for (const std::string& dex_path : dex_paths) { 1837 zip_fds->emplace_back(open(dex_path.c_str(), O_RDONLY)); 1838 if (zip_fds->back().get() < 0) { 1839 *error_msg = StringPrintf( 1840 "installd cannot open '%s' for input during dexopt", dex_path.c_str()); 1841 if (errno == ENOENT) { 1842 return kSecondaryDexDexoptAnalyzerSkippedNoFile; 1843 } else { 1844 return kSecondaryDexDexoptAnalyzerSkippedOpenZip; 1845 } 1846 } 1847 } 1848 return 0; 1849 } 1850 1851 static std::string join_fds(const std::vector<unique_fd>& fds) { 1852 std::stringstream ss; 1853 bool is_first = true; 1854 for (const unique_fd& fd : fds) { 1855 if (is_first) { 1856 is_first = false; 1857 } else { 1858 ss << ":"; 1859 } 1860 ss << fd.get(); 1861 } 1862 return ss.str(); 1863 } 1864 1865 // Processes the dex_path as a secondary dex files and return true if the path dex file should 1866 // be compiled. Returns false for errors (logged) or true if the secondary dex path was process 1867 // successfully. 1868 // When returning true, the output parameters will be: 1869 // - is_public_out: whether or not the oat file should not be made public 1870 // - dexopt_needed_out: valid OatFileAsssitant::DexOptNeeded 1871 // - oat_dir_out: the oat dir path where the oat file should be stored 1872 static bool process_secondary_dex_dexopt(const std::string& dex_path, const char* pkgname, 1873 int dexopt_flags, const char* volume_uuid, int uid, const char* instruction_set, 1874 const char* compiler_filter, bool* is_public_out, int* dexopt_needed_out, 1875 std::string* oat_dir_out, bool downgrade, const char* class_loader_context, 1876 const std::vector<std::string>& context_dex_paths, /* out */ std::string* error_msg) { 1877 LOG(DEBUG) << "Processing secondary dex path " << dex_path; 1878 int storage_flag; 1879 if (!validate_dexopt_storage_flags(dexopt_flags, &storage_flag, error_msg)) { 1880 LOG(ERROR) << *error_msg; 1881 return false; 1882 } 1883 // Compute the oat dir as it's not easy to extract it from the child computation. 1884 char oat_path[PKG_PATH_MAX]; 1885 char oat_dir[PKG_PATH_MAX]; 1886 char oat_isa_dir[PKG_PATH_MAX]; 1887 if (!create_secondary_dex_oat_layout( 1888 dex_path, instruction_set, oat_dir, oat_isa_dir, oat_path, error_msg)) { 1889 LOG(ERROR) << "Could not create secondary odex layout: " << *error_msg; 1890 return false; 1891 } 1892 oat_dir_out->assign(oat_dir); 1893 1894 pid_t pid = fork(); 1895 if (pid == 0) { 1896 // child -- drop privileges before continuing. 1897 drop_capabilities(uid); 1898 1899 // Validate the path structure. 1900 if (!validate_secondary_dex_path(pkgname, dex_path, volume_uuid, uid, storage_flag)) { 1901 LOG(ERROR) << "Could not validate secondary dex path " << dex_path; 1902 _exit(kSecondaryDexDexoptAnalyzerSkippedValidatePath); 1903 } 1904 1905 // Open the dex file. 1906 unique_fd zip_fd; 1907 zip_fd.reset(open(dex_path.c_str(), O_RDONLY)); 1908 if (zip_fd.get() < 0) { 1909 if (errno == ENOENT) { 1910 _exit(kSecondaryDexDexoptAnalyzerSkippedNoFile); 1911 } else { 1912 _exit(kSecondaryDexDexoptAnalyzerSkippedOpenZip); 1913 } 1914 } 1915 1916 // Open class loader context dex files. 1917 std::vector<unique_fd> context_zip_fds; 1918 int open_dex_paths_rc = open_dex_paths(context_dex_paths, &context_zip_fds, error_msg); 1919 if (open_dex_paths_rc != 0) { 1920 _exit(open_dex_paths_rc); 1921 } 1922 1923 // Prepare the oat directories. 1924 if (!prepare_secondary_dex_oat_dir(dex_path, uid, instruction_set)) { 1925 _exit(kSecondaryDexDexoptAnalyzerSkippedPrepareDir); 1926 } 1927 1928 // Open the vdex/oat files if any. 1929 unique_fd oat_file_fd; 1930 unique_fd vdex_file_fd; 1931 if (!maybe_open_oat_and_vdex_file(dex_path, 1932 *oat_dir_out, 1933 instruction_set, 1934 true /* is_secondary_dex */, 1935 &oat_file_fd, 1936 &vdex_file_fd)) { 1937 _exit(kSecondaryDexDexoptAnalyzerSkippedOpenOutput); 1938 } 1939 1940 // Analyze profiles. 1941 bool profile_was_updated = analyze_profiles(uid, pkgname, dex_path, 1942 /*is_secondary_dex*/true); 1943 1944 // Run dexoptanalyzer to get dexopt_needed code. This is not expected to return. 1945 // Note that we do not do it before the fork since opening the files is required to happen 1946 // after forking. 1947 RunDexoptAnalyzer run_dexopt_analyzer(dex_path, 1948 vdex_file_fd.get(), 1949 oat_file_fd.get(), 1950 zip_fd.get(), 1951 instruction_set, 1952 compiler_filter, profile_was_updated, 1953 downgrade, 1954 class_loader_context, 1955 join_fds(context_zip_fds)); 1956 run_dexopt_analyzer.Exec(kSecondaryDexDexoptAnalyzerSkippedFailExec); 1957 } 1958 1959 /* parent */ 1960 int result = wait_child(pid); 1961 if (!WIFEXITED(result)) { 1962 *error_msg = StringPrintf("dexoptanalyzer failed for path %s: 0x%04x", 1963 dex_path.c_str(), 1964 result); 1965 LOG(ERROR) << *error_msg; 1966 return false; 1967 } 1968 result = WEXITSTATUS(result); 1969 // Check that we successfully executed dexoptanalyzer. 1970 bool success = process_secondary_dexoptanalyzer_result(dex_path, 1971 result, 1972 dexopt_needed_out, 1973 error_msg); 1974 if (!success) { 1975 LOG(ERROR) << *error_msg; 1976 } 1977 1978 LOG(DEBUG) << "Processed secondary dex file " << dex_path << " result=" << result; 1979 1980 // Run dexopt only if needed or forced. 1981 // Note that dexoptanalyzer is executed even if force compilation is enabled (because it 1982 // makes the code simpler; force compilation is only needed during tests). 1983 if (success && 1984 (result != kSecondaryDexDexoptAnalyzerSkippedNoFile) && 1985 ((dexopt_flags & DEXOPT_FORCE) != 0)) { 1986 *dexopt_needed_out = DEX2OAT_FROM_SCRATCH; 1987 } 1988 1989 // Check if we should make the oat file public. 1990 // Note that if the dex file is not public the compiled code cannot be made public. 1991 // It is ok to check this flag outside in the parent process. 1992 *is_public_out = ((dexopt_flags & DEXOPT_PUBLIC) != 0) && is_file_public(dex_path); 1993 1994 return success; 1995 } 1996 1997 static std::string format_dexopt_error(int status, const char* dex_path) { 1998 if (WIFEXITED(status)) { 1999 int int_code = WEXITSTATUS(status); 2000 const char* code_name = get_return_code_name(static_cast<DexoptReturnCodes>(int_code)); 2001 if (code_name != nullptr) { 2002 return StringPrintf("Dex2oat invocation for %s failed: %s", dex_path, code_name); 2003 } 2004 } 2005 return StringPrintf("Dex2oat invocation for %s failed with 0x%04x", dex_path, status); 2006 } 2007 2008 int dexopt(const char* dex_path, uid_t uid, const char* pkgname, const char* instruction_set, 2009 int dexopt_needed, const char* oat_dir, int dexopt_flags, const char* compiler_filter, 2010 const char* volume_uuid, const char* class_loader_context, const char* se_info, 2011 bool downgrade, int target_sdk_version, const char* profile_name, 2012 const char* dex_metadata_path, const char* compilation_reason, std::string* error_msg) { 2013 CHECK(pkgname != nullptr); 2014 CHECK(pkgname[0] != 0); 2015 CHECK(error_msg != nullptr); 2016 CHECK_EQ(dexopt_flags & ~DEXOPT_MASK, 0) 2017 << "dexopt flags contains unknown fields: " << dexopt_flags; 2018 2019 if (!validate_dex_path_size(dex_path)) { 2020 *error_msg = StringPrintf("Failed to validate %s", dex_path); 2021 return -1; 2022 } 2023 2024 if (class_loader_context != nullptr && strlen(class_loader_context) > PKG_PATH_MAX) { 2025 *error_msg = StringPrintf("Class loader context exceeds the allowed size: %s", 2026 class_loader_context); 2027 LOG(ERROR) << *error_msg; 2028 return -1; 2029 } 2030 2031 bool is_public = (dexopt_flags & DEXOPT_PUBLIC) != 0; 2032 bool debuggable = (dexopt_flags & DEXOPT_DEBUGGABLE) != 0; 2033 bool boot_complete = (dexopt_flags & DEXOPT_BOOTCOMPLETE) != 0; 2034 bool profile_guided = (dexopt_flags & DEXOPT_PROFILE_GUIDED) != 0; 2035 bool is_secondary_dex = (dexopt_flags & DEXOPT_SECONDARY_DEX) != 0; 2036 bool background_job_compile = (dexopt_flags & DEXOPT_IDLE_BACKGROUND_JOB) != 0; 2037 bool enable_hidden_api_checks = (dexopt_flags & DEXOPT_ENABLE_HIDDEN_API_CHECKS) != 0; 2038 bool generate_compact_dex = (dexopt_flags & DEXOPT_GENERATE_COMPACT_DEX) != 0; 2039 bool generate_app_image = (dexopt_flags & DEXOPT_GENERATE_APP_IMAGE) != 0; 2040 2041 // Check if we're dealing with a secondary dex file and if we need to compile it. 2042 std::string oat_dir_str; 2043 std::vector<std::string> context_dex_paths; 2044 if (is_secondary_dex) { 2045 if (!get_class_loader_context_dex_paths(class_loader_context, uid, &context_dex_paths)) { 2046 *error_msg = "Failed acquiring context dex paths"; 2047 return -1; // We had an error, logged in the process method. 2048 } 2049 2050 if (process_secondary_dex_dexopt(dex_path, pkgname, dexopt_flags, volume_uuid, uid, 2051 instruction_set, compiler_filter, &is_public, &dexopt_needed, &oat_dir_str, 2052 downgrade, class_loader_context, context_dex_paths, error_msg)) { 2053 oat_dir = oat_dir_str.c_str(); 2054 if (dexopt_needed == NO_DEXOPT_NEEDED) { 2055 return 0; // Nothing to do, report success. 2056 } 2057 } else { 2058 if (error_msg->empty()) { // TODO: Make this a CHECK. 2059 *error_msg = "Failed processing secondary."; 2060 } 2061 return -1; // We had an error, logged in the process method. 2062 } 2063 } else { 2064 // Currently these flags are only used for secondary dex files. 2065 // Verify that they are not set for primary apks. 2066 CHECK((dexopt_flags & DEXOPT_STORAGE_CE) == 0); 2067 CHECK((dexopt_flags & DEXOPT_STORAGE_DE) == 0); 2068 } 2069 2070 // Open the input file. 2071 unique_fd input_fd(open(dex_path, O_RDONLY, 0)); 2072 if (input_fd.get() < 0) { 2073 *error_msg = StringPrintf("installd cannot open '%s' for input during dexopt", dex_path); 2074 LOG(ERROR) << *error_msg; 2075 return -1; 2076 } 2077 2078 // Open class loader context dex files. 2079 std::vector<unique_fd> context_input_fds; 2080 if (open_dex_paths(context_dex_paths, &context_input_fds, error_msg) != 0) { 2081 LOG(ERROR) << *error_msg; 2082 return -1; 2083 } 2084 2085 // Create the output OAT file. 2086 char out_oat_path[PKG_PATH_MAX]; 2087 Dex2oatFileWrapper out_oat_fd = open_oat_out_file(dex_path, oat_dir, is_public, uid, 2088 instruction_set, is_secondary_dex, out_oat_path); 2089 if (out_oat_fd.get() < 0) { 2090 *error_msg = "Could not open out oat file."; 2091 return -1; 2092 } 2093 2094 // Open vdex files. 2095 Dex2oatFileWrapper in_vdex_fd; 2096 Dex2oatFileWrapper out_vdex_fd; 2097 if (!open_vdex_files_for_dex2oat(dex_path, out_oat_path, dexopt_needed, instruction_set, 2098 is_public, uid, is_secondary_dex, profile_guided, &in_vdex_fd, &out_vdex_fd)) { 2099 *error_msg = "Could not open vdex files."; 2100 return -1; 2101 } 2102 2103 // Ensure that the oat dir and the compiler artifacts of secondary dex files have the correct 2104 // selinux context (we generate them on the fly during the dexopt invocation and they don't 2105 // fully inherit their parent context). 2106 // Note that for primary apk the oat files are created before, in a separate installd 2107 // call which also does the restorecon. TODO(calin): unify the paths. 2108 if (is_secondary_dex) { 2109 if (selinux_android_restorecon_pkgdir(oat_dir, se_info, uid, 2110 SELINUX_ANDROID_RESTORECON_RECURSE)) { 2111 *error_msg = std::string("Failed to restorecon ").append(oat_dir); 2112 LOG(ERROR) << *error_msg; 2113 return -1; 2114 } 2115 } 2116 2117 // Create a swap file if necessary. 2118 unique_fd swap_fd = maybe_open_dexopt_swap_file(out_oat_path); 2119 2120 // Create the app image file if needed. 2121 Dex2oatFileWrapper image_fd = maybe_open_app_image( 2122 out_oat_path, generate_app_image, is_public, uid, is_secondary_dex); 2123 2124 // Open the reference profile if needed. 2125 Dex2oatFileWrapper reference_profile_fd = maybe_open_reference_profile( 2126 pkgname, dex_path, profile_name, profile_guided, is_public, uid, is_secondary_dex); 2127 2128 unique_fd dex_metadata_fd; 2129 if (dex_metadata_path != nullptr) { 2130 dex_metadata_fd.reset(TEMP_FAILURE_RETRY(open(dex_metadata_path, O_RDONLY | O_NOFOLLOW))); 2131 if (dex_metadata_fd.get() < 0) { 2132 PLOG(ERROR) << "Failed to open dex metadata file " << dex_metadata_path; 2133 } 2134 } 2135 2136 LOG(VERBOSE) << "DexInv: --- BEGIN '" << dex_path << "' ---"; 2137 2138 RunDex2Oat runner(input_fd.get(), 2139 out_oat_fd.get(), 2140 in_vdex_fd.get(), 2141 out_vdex_fd.get(), 2142 image_fd.get(), 2143 dex_path, 2144 out_oat_path, 2145 swap_fd.get(), 2146 instruction_set, 2147 compiler_filter, 2148 debuggable, 2149 boot_complete, 2150 background_job_compile, 2151 reference_profile_fd.get(), 2152 class_loader_context, 2153 join_fds(context_input_fds), 2154 target_sdk_version, 2155 enable_hidden_api_checks, 2156 generate_compact_dex, 2157 dex_metadata_fd.get(), 2158 compilation_reason); 2159 2160 pid_t pid = fork(); 2161 if (pid == 0) { 2162 /* child -- drop privileges before continuing */ 2163 drop_capabilities(uid); 2164 2165 SetDex2OatScheduling(boot_complete); 2166 if (flock(out_oat_fd.get(), LOCK_EX | LOCK_NB) != 0) { 2167 PLOG(ERROR) << "flock(" << out_oat_path << ") failed"; 2168 _exit(DexoptReturnCodes::kFlock); 2169 } 2170 2171 runner.Exec(DexoptReturnCodes::kDex2oatExec); 2172 } else { 2173 int res = wait_child(pid); 2174 if (res == 0) { 2175 LOG(VERBOSE) << "DexInv: --- END '" << dex_path << "' (success) ---"; 2176 } else { 2177 LOG(VERBOSE) << "DexInv: --- END '" << dex_path << "' --- status=0x" 2178 << std::hex << std::setw(4) << res << ", process failed"; 2179 *error_msg = format_dexopt_error(res, dex_path); 2180 return res; 2181 } 2182 } 2183 2184 update_out_oat_access_times(dex_path, out_oat_path); 2185 2186 // We've been successful, don't delete output. 2187 out_oat_fd.SetCleanup(false); 2188 out_vdex_fd.SetCleanup(false); 2189 image_fd.SetCleanup(false); 2190 reference_profile_fd.SetCleanup(false); 2191 2192 return 0; 2193 } 2194 2195 // Try to remove the given directory. Log an error if the directory exists 2196 // and is empty but could not be removed. 2197 static bool rmdir_if_empty(const char* dir) { 2198 if (rmdir(dir) == 0) { 2199 return true; 2200 } 2201 if (errno == ENOENT || errno == ENOTEMPTY) { 2202 return true; 2203 } 2204 PLOG(ERROR) << "Failed to remove dir: " << dir; 2205 return false; 2206 } 2207 2208 // Try to unlink the given file. Log an error if the file exists and could not 2209 // be unlinked. 2210 static bool unlink_if_exists(const std::string& file) { 2211 if (unlink(file.c_str()) == 0) { 2212 return true; 2213 } 2214 if (errno == ENOENT) { 2215 return true; 2216 2217 } 2218 PLOG(ERROR) << "Could not unlink: " << file; 2219 return false; 2220 } 2221 2222 enum ReconcileSecondaryDexResult { 2223 kReconcileSecondaryDexExists = 0, 2224 kReconcileSecondaryDexCleanedUp = 1, 2225 kReconcileSecondaryDexValidationError = 2, 2226 kReconcileSecondaryDexCleanUpError = 3, 2227 kReconcileSecondaryDexAccessIOError = 4, 2228 }; 2229 2230 // Reconcile the secondary dex 'dex_path' and its generated oat files. 2231 // Return true if all the parameters are valid and the secondary dex file was 2232 // processed successfully (i.e. the dex_path either exists, or if not, its corresponding 2233 // oat/vdex/art files where deleted successfully). In this case, out_secondary_dex_exists 2234 // will be true if the secondary dex file still exists. If the secondary dex file does not exist, 2235 // the method cleans up any previously generated compiler artifacts (oat, vdex, art). 2236 // Return false if there were errors during processing. In this case 2237 // out_secondary_dex_exists will be set to false. 2238 bool reconcile_secondary_dex_file(const std::string& dex_path, 2239 const std::string& pkgname, int uid, const std::vector<std::string>& isas, 2240 const std::unique_ptr<std::string>& volume_uuid, int storage_flag, 2241 /*out*/bool* out_secondary_dex_exists) { 2242 *out_secondary_dex_exists = false; // start by assuming the file does not exist. 2243 if (isas.size() == 0) { 2244 LOG(ERROR) << "reconcile_secondary_dex_file called with empty isas vector"; 2245 return false; 2246 } 2247 2248 if (storage_flag != FLAG_STORAGE_CE && storage_flag != FLAG_STORAGE_DE) { 2249 LOG(ERROR) << "reconcile_secondary_dex_file called with invalid storage_flag: " 2250 << storage_flag; 2251 return false; 2252 } 2253 2254 // As a security measure we want to unlink art artifacts with the reduced capabilities 2255 // of the package user id. So we fork and drop capabilities in the child. 2256 pid_t pid = fork(); 2257 if (pid == 0) { 2258 /* child -- drop privileges before continuing */ 2259 drop_capabilities(uid); 2260 2261 const char* volume_uuid_cstr = volume_uuid == nullptr ? nullptr : volume_uuid->c_str(); 2262 if (!validate_secondary_dex_path(pkgname, dex_path, volume_uuid_cstr, 2263 uid, storage_flag)) { 2264 LOG(ERROR) << "Could not validate secondary dex path " << dex_path; 2265 _exit(kReconcileSecondaryDexValidationError); 2266 } 2267 2268 SecondaryDexAccess access_check = check_secondary_dex_access(dex_path); 2269 switch (access_check) { 2270 case kSecondaryDexAccessDoesNotExist: 2271 // File does not exist. Proceed with cleaning. 2272 break; 2273 case kSecondaryDexAccessReadOk: _exit(kReconcileSecondaryDexExists); 2274 case kSecondaryDexAccessIOError: _exit(kReconcileSecondaryDexAccessIOError); 2275 case kSecondaryDexAccessPermissionError: _exit(kReconcileSecondaryDexValidationError); 2276 default: 2277 LOG(ERROR) << "Unexpected result from check_secondary_dex_access: " << access_check; 2278 _exit(kReconcileSecondaryDexValidationError); 2279 } 2280 2281 // The secondary dex does not exist anymore or it's. Clear any generated files. 2282 char oat_path[PKG_PATH_MAX]; 2283 char oat_dir[PKG_PATH_MAX]; 2284 char oat_isa_dir[PKG_PATH_MAX]; 2285 bool result = true; 2286 for (size_t i = 0; i < isas.size(); i++) { 2287 std::string error_msg; 2288 if (!create_secondary_dex_oat_layout( 2289 dex_path,isas[i], oat_dir, oat_isa_dir, oat_path, &error_msg)) { 2290 LOG(ERROR) << error_msg; 2291 _exit(kReconcileSecondaryDexValidationError); 2292 } 2293 2294 // Delete oat/vdex/art files. 2295 result = unlink_if_exists(oat_path) && result; 2296 result = unlink_if_exists(create_vdex_filename(oat_path)) && result; 2297 result = unlink_if_exists(create_image_filename(oat_path)) && result; 2298 2299 // Delete profiles. 2300 std::string current_profile = create_current_profile_path( 2301 multiuser_get_user_id(uid), pkgname, dex_path, /*is_secondary*/true); 2302 std::string reference_profile = create_reference_profile_path( 2303 pkgname, dex_path, /*is_secondary*/true); 2304 result = unlink_if_exists(current_profile) && result; 2305 result = unlink_if_exists(reference_profile) && result; 2306 2307 // We upgraded once the location of current profile for secondary dex files. 2308 // Check for any previous left-overs and remove them as well. 2309 std::string old_current_profile = dex_path + ".prof"; 2310 result = unlink_if_exists(old_current_profile); 2311 2312 // Try removing the directories as well, they might be empty. 2313 result = rmdir_if_empty(oat_isa_dir) && result; 2314 result = rmdir_if_empty(oat_dir) && result; 2315 } 2316 if (!result) { 2317 PLOG(ERROR) << "Failed to clean secondary dex artifacts for location " << dex_path; 2318 } 2319 _exit(result ? kReconcileSecondaryDexCleanedUp : kReconcileSecondaryDexAccessIOError); 2320 } 2321 2322 int return_code = wait_child(pid); 2323 if (!WIFEXITED(return_code)) { 2324 LOG(WARNING) << "reconcile dex failed for location " << dex_path << ": " << return_code; 2325 } else { 2326 return_code = WEXITSTATUS(return_code); 2327 } 2328 2329 LOG(DEBUG) << "Reconcile secondary dex path " << dex_path << " result=" << return_code; 2330 2331 switch (return_code) { 2332 case kReconcileSecondaryDexCleanedUp: 2333 case kReconcileSecondaryDexValidationError: 2334 // If we couldn't validate assume the dex file does not exist. 2335 // This will purge the entry from the PM records. 2336 *out_secondary_dex_exists = false; 2337 return true; 2338 case kReconcileSecondaryDexExists: 2339 *out_secondary_dex_exists = true; 2340 return true; 2341 case kReconcileSecondaryDexAccessIOError: 2342 // We had an access IO error. 2343 // Return false so that we can try again. 2344 // The value of out_secondary_dex_exists does not matter in this case and by convention 2345 // is set to false. 2346 *out_secondary_dex_exists = false; 2347 return false; 2348 default: 2349 LOG(ERROR) << "Unexpected code from reconcile_secondary_dex_file: " << return_code; 2350 *out_secondary_dex_exists = false; 2351 return false; 2352 } 2353 } 2354 2355 // Compute and return the hash (SHA-256) of the secondary dex file at dex_path. 2356 // Returns true if all parameters are valid and the hash successfully computed and stored in 2357 // out_secondary_dex_hash. 2358 // Also returns true with an empty hash if the file does not currently exist or is not accessible to 2359 // the app. 2360 // For any other errors (e.g. if any of the parameters are invalid) returns false. 2361 bool hash_secondary_dex_file(const std::string& dex_path, const std::string& pkgname, int uid, 2362 const std::unique_ptr<std::string>& volume_uuid, int storage_flag, 2363 std::vector<uint8_t>* out_secondary_dex_hash) { 2364 out_secondary_dex_hash->clear(); 2365 2366 const char* volume_uuid_cstr = volume_uuid == nullptr ? nullptr : volume_uuid->c_str(); 2367 2368 if (storage_flag != FLAG_STORAGE_CE && storage_flag != FLAG_STORAGE_DE) { 2369 LOG(ERROR) << "hash_secondary_dex_file called with invalid storage_flag: " 2370 << storage_flag; 2371 return false; 2372 } 2373 2374 // Pipe to get the hash result back from our child process. 2375 unique_fd pipe_read, pipe_write; 2376 if (!Pipe(&pipe_read, &pipe_write)) { 2377 PLOG(ERROR) << "Failed to create pipe"; 2378 return false; 2379 } 2380 2381 // Fork so that actual access to the files is done in the app's own UID, to ensure we only 2382 // access data the app itself can access. 2383 pid_t pid = fork(); 2384 if (pid == 0) { 2385 // child -- drop privileges before continuing 2386 drop_capabilities(uid); 2387 pipe_read.reset(); 2388 2389 if (!validate_secondary_dex_path(pkgname, dex_path, volume_uuid_cstr, uid, storage_flag)) { 2390 LOG(ERROR) << "Could not validate secondary dex path " << dex_path; 2391 _exit(DexoptReturnCodes::kHashValidatePath); 2392 } 2393 2394 unique_fd fd(TEMP_FAILURE_RETRY(open(dex_path.c_str(), O_RDONLY | O_CLOEXEC | O_NOFOLLOW))); 2395 if (fd == -1) { 2396 if (errno == EACCES || errno == ENOENT) { 2397 // Not treated as an error. 2398 _exit(0); 2399 } 2400 PLOG(ERROR) << "Failed to open secondary dex " << dex_path; 2401 _exit(DexoptReturnCodes::kHashOpenPath); 2402 } 2403 2404 SHA256_CTX ctx; 2405 SHA256_Init(&ctx); 2406 2407 std::vector<uint8_t> buffer(65536); 2408 while (true) { 2409 ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd, buffer.data(), buffer.size())); 2410 if (bytes_read == 0) { 2411 break; 2412 } else if (bytes_read == -1) { 2413 PLOG(ERROR) << "Failed to read secondary dex " << dex_path; 2414 _exit(DexoptReturnCodes::kHashReadDex); 2415 } 2416 2417 SHA256_Update(&ctx, buffer.data(), bytes_read); 2418 } 2419 2420 std::array<uint8_t, SHA256_DIGEST_LENGTH> hash; 2421 SHA256_Final(hash.data(), &ctx); 2422 if (!WriteFully(pipe_write, hash.data(), hash.size())) { 2423 _exit(DexoptReturnCodes::kHashWrite); 2424 } 2425 2426 _exit(0); 2427 } 2428 2429 // parent 2430 pipe_write.reset(); 2431 2432 out_secondary_dex_hash->resize(SHA256_DIGEST_LENGTH); 2433 if (!ReadFully(pipe_read, out_secondary_dex_hash->data(), out_secondary_dex_hash->size())) { 2434 out_secondary_dex_hash->clear(); 2435 } 2436 return wait_child(pid) == 0; 2437 } 2438 2439 // Helper for move_ab, so that we can have common failure-case cleanup. 2440 static bool unlink_and_rename(const char* from, const char* to) { 2441 // Check whether "from" exists, and if so whether it's regular. If it is, unlink. Otherwise, 2442 // return a failure. 2443 struct stat s; 2444 if (stat(to, &s) == 0) { 2445 if (!S_ISREG(s.st_mode)) { 2446 LOG(ERROR) << from << " is not a regular file to replace for A/B."; 2447 return false; 2448 } 2449 if (unlink(to) != 0) { 2450 LOG(ERROR) << "Could not unlink " << to << " to move A/B."; 2451 return false; 2452 } 2453 } else { 2454 // This may be a permission problem. We could investigate the error code, but we'll just 2455 // let the rename failure do the work for us. 2456 } 2457 2458 // Try to rename "to" to "from." 2459 if (rename(from, to) != 0) { 2460 PLOG(ERROR) << "Could not rename " << from << " to " << to; 2461 return false; 2462 } 2463 return true; 2464 } 2465 2466 // Move/rename a B artifact (from) to an A artifact (to). 2467 static bool move_ab_path(const std::string& b_path, const std::string& a_path) { 2468 // Check whether B exists. 2469 { 2470 struct stat s; 2471 if (stat(b_path.c_str(), &s) != 0) { 2472 // Silently ignore for now. The service calling this isn't smart enough to understand 2473 // lack of artifacts at the moment. 2474 return false; 2475 } 2476 if (!S_ISREG(s.st_mode)) { 2477 LOG(ERROR) << "A/B artifact " << b_path << " is not a regular file."; 2478 // Try to unlink, but swallow errors. 2479 unlink(b_path.c_str()); 2480 return false; 2481 } 2482 } 2483 2484 // Rename B to A. 2485 if (!unlink_and_rename(b_path.c_str(), a_path.c_str())) { 2486 // Delete the b_path so we don't try again (or fail earlier). 2487 if (unlink(b_path.c_str()) != 0) { 2488 PLOG(ERROR) << "Could not unlink " << b_path; 2489 } 2490 2491 return false; 2492 } 2493 2494 return true; 2495 } 2496 2497 bool move_ab(const char* apk_path, const char* instruction_set, const char* oat_dir) { 2498 // Get the current slot suffix. No suffix, no A/B. 2499 const std::string slot_suffix = GetProperty("ro.boot.slot_suffix", ""); 2500 if (slot_suffix.empty()) { 2501 return false; 2502 } 2503 2504 if (!ValidateTargetSlotSuffix(slot_suffix)) { 2505 LOG(ERROR) << "Target slot suffix not legal: " << slot_suffix; 2506 return false; 2507 } 2508 2509 // Validate other inputs. 2510 if (validate_apk_path(apk_path) != 0) { 2511 LOG(ERROR) << "Invalid apk_path: " << apk_path; 2512 return false; 2513 } 2514 if (validate_apk_path(oat_dir) != 0) { 2515 LOG(ERROR) << "Invalid oat_dir: " << oat_dir; 2516 return false; 2517 } 2518 2519 char a_path[PKG_PATH_MAX]; 2520 if (!calculate_oat_file_path(a_path, oat_dir, apk_path, instruction_set)) { 2521 return false; 2522 } 2523 const std::string a_vdex_path = create_vdex_filename(a_path); 2524 const std::string a_image_path = create_image_filename(a_path); 2525 2526 // B path = A path + slot suffix. 2527 const std::string b_path = StringPrintf("%s.%s", a_path, slot_suffix.c_str()); 2528 const std::string b_vdex_path = StringPrintf("%s.%s", a_vdex_path.c_str(), slot_suffix.c_str()); 2529 const std::string b_image_path = StringPrintf("%s.%s", 2530 a_image_path.c_str(), 2531 slot_suffix.c_str()); 2532 2533 bool success = true; 2534 if (move_ab_path(b_path, a_path)) { 2535 if (move_ab_path(b_vdex_path, a_vdex_path)) { 2536 // Note: we can live without an app image. As such, ignore failure to move the image file. 2537 // If we decide to require the app image, or the app image being moved correctly, 2538 // then change accordingly. 2539 constexpr bool kIgnoreAppImageFailure = true; 2540 2541 if (!a_image_path.empty()) { 2542 if (!move_ab_path(b_image_path, a_image_path)) { 2543 unlink(a_image_path.c_str()); 2544 if (!kIgnoreAppImageFailure) { 2545 success = false; 2546 } 2547 } 2548 } 2549 } else { 2550 // Cleanup: delete B image, ignore errors. 2551 unlink(b_image_path.c_str()); 2552 success = false; 2553 } 2554 } else { 2555 // Cleanup: delete B image, ignore errors. 2556 unlink(b_vdex_path.c_str()); 2557 unlink(b_image_path.c_str()); 2558 success = false; 2559 } 2560 return success; 2561 } 2562 2563 bool delete_odex(const char* apk_path, const char* instruction_set, const char* oat_dir) { 2564 // Delete the oat/odex file. 2565 char out_path[PKG_PATH_MAX]; 2566 if (!create_oat_out_path(apk_path, instruction_set, oat_dir, 2567 /*is_secondary_dex*/false, out_path)) { 2568 return false; 2569 } 2570 2571 // In case of a permission failure report the issue. Otherwise just print a warning. 2572 auto unlink_and_check = [](const char* path) -> bool { 2573 int result = unlink(path); 2574 if (result != 0) { 2575 if (errno == EACCES || errno == EPERM) { 2576 PLOG(ERROR) << "Could not unlink " << path; 2577 return false; 2578 } 2579 PLOG(WARNING) << "Could not unlink " << path; 2580 } 2581 return true; 2582 }; 2583 2584 // Delete the oat/odex file. 2585 bool return_value_oat = unlink_and_check(out_path); 2586 2587 // Derive and delete the app image. 2588 bool return_value_art = unlink_and_check(create_image_filename(out_path).c_str()); 2589 2590 // Derive and delete the vdex file. 2591 bool return_value_vdex = unlink_and_check(create_vdex_filename(out_path).c_str()); 2592 2593 // Report success. 2594 return return_value_oat && return_value_art && return_value_vdex; 2595 } 2596 2597 static bool is_absolute_path(const std::string& path) { 2598 if (path.find('/') != 0 || path.find("..") != std::string::npos) { 2599 LOG(ERROR) << "Invalid absolute path " << path; 2600 return false; 2601 } else { 2602 return true; 2603 } 2604 } 2605 2606 static bool is_valid_instruction_set(const std::string& instruction_set) { 2607 // TODO: add explicit whitelisting of instruction sets 2608 if (instruction_set.find('/') != std::string::npos) { 2609 LOG(ERROR) << "Invalid instruction set " << instruction_set; 2610 return false; 2611 } else { 2612 return true; 2613 } 2614 } 2615 2616 bool calculate_oat_file_path_default(char path[PKG_PATH_MAX], const char *oat_dir, 2617 const char *apk_path, const char *instruction_set) { 2618 std::string oat_dir_ = oat_dir; 2619 std::string apk_path_ = apk_path; 2620 std::string instruction_set_ = instruction_set; 2621 2622 if (!is_absolute_path(oat_dir_)) return false; 2623 if (!is_absolute_path(apk_path_)) return false; 2624 if (!is_valid_instruction_set(instruction_set_)) return false; 2625 2626 std::string::size_type end = apk_path_.rfind('.'); 2627 std::string::size_type start = apk_path_.rfind('/', end); 2628 if (end == std::string::npos || start == std::string::npos) { 2629 LOG(ERROR) << "Invalid apk_path " << apk_path_; 2630 return false; 2631 } 2632 2633 std::string res_ = oat_dir_ + '/' + instruction_set + '/' 2634 + apk_path_.substr(start + 1, end - start - 1) + ".odex"; 2635 const char* res = res_.c_str(); 2636 if (strlen(res) >= PKG_PATH_MAX) { 2637 LOG(ERROR) << "Result too large"; 2638 return false; 2639 } else { 2640 strlcpy(path, res, PKG_PATH_MAX); 2641 return true; 2642 } 2643 } 2644 2645 bool calculate_odex_file_path_default(char path[PKG_PATH_MAX], const char *apk_path, 2646 const char *instruction_set) { 2647 std::string apk_path_ = apk_path; 2648 std::string instruction_set_ = instruction_set; 2649 2650 if (!is_absolute_path(apk_path_)) return false; 2651 if (!is_valid_instruction_set(instruction_set_)) return false; 2652 2653 std::string::size_type end = apk_path_.rfind('.'); 2654 std::string::size_type start = apk_path_.rfind('/', end); 2655 if (end == std::string::npos || start == std::string::npos) { 2656 LOG(ERROR) << "Invalid apk_path " << apk_path_; 2657 return false; 2658 } 2659 2660 std::string oat_dir = apk_path_.substr(0, start + 1) + "oat"; 2661 return calculate_oat_file_path_default(path, oat_dir.c_str(), apk_path, instruction_set); 2662 } 2663 2664 bool create_cache_path_default(char path[PKG_PATH_MAX], const char *src, 2665 const char *instruction_set) { 2666 std::string src_ = src; 2667 std::string instruction_set_ = instruction_set; 2668 2669 if (!is_absolute_path(src_)) return false; 2670 if (!is_valid_instruction_set(instruction_set_)) return false; 2671 2672 for (auto it = src_.begin() + 1; it < src_.end(); ++it) { 2673 if (*it == '/') { 2674 *it = '@'; 2675 } 2676 } 2677 2678 std::string res_ = android_data_dir + DALVIK_CACHE + '/' + instruction_set_ + src_ 2679 + DALVIK_CACHE_POSTFIX; 2680 const char* res = res_.c_str(); 2681 if (strlen(res) >= PKG_PATH_MAX) { 2682 LOG(ERROR) << "Result too large"; 2683 return false; 2684 } else { 2685 strlcpy(path, res, PKG_PATH_MAX); 2686 return true; 2687 } 2688 } 2689 2690 bool open_classpath_files(const std::string& classpath, std::vector<unique_fd>* apk_fds, 2691 std::vector<std::string>* dex_locations) { 2692 std::vector<std::string> classpaths_elems = base::Split(classpath, ":"); 2693 for (const std::string& elem : classpaths_elems) { 2694 unique_fd fd(TEMP_FAILURE_RETRY(open(elem.c_str(), O_RDONLY))); 2695 if (fd < 0) { 2696 PLOG(ERROR) << "Could not open classpath elem " << elem; 2697 return false; 2698 } else { 2699 apk_fds->push_back(std::move(fd)); 2700 dex_locations->push_back(elem); 2701 } 2702 } 2703 return true; 2704 } 2705 2706 static bool create_app_profile_snapshot(int32_t app_id, 2707 const std::string& package_name, 2708 const std::string& profile_name, 2709 const std::string& classpath) { 2710 int app_shared_gid = multiuser_get_shared_gid(/*user_id*/ 0, app_id); 2711 2712 unique_fd snapshot_fd = open_spnashot_profile(AID_SYSTEM, package_name, profile_name); 2713 if (snapshot_fd < 0) { 2714 return false; 2715 } 2716 2717 std::vector<unique_fd> profiles_fd; 2718 unique_fd reference_profile_fd; 2719 open_profile_files(app_shared_gid, package_name, profile_name, /*is_secondary_dex*/ false, 2720 &profiles_fd, &reference_profile_fd); 2721 if (profiles_fd.empty() || (reference_profile_fd.get() < 0)) { 2722 return false; 2723 } 2724 2725 profiles_fd.push_back(std::move(reference_profile_fd)); 2726 2727 // Open the class paths elements. These will be used to filter out profile data that does 2728 // not belong to the classpath during merge. 2729 std::vector<unique_fd> apk_fds; 2730 std::vector<std::string> dex_locations; 2731 if (!open_classpath_files(classpath, &apk_fds, &dex_locations)) { 2732 return false; 2733 } 2734 2735 RunProfman args; 2736 args.SetupMerge(profiles_fd, snapshot_fd, apk_fds, dex_locations); 2737 pid_t pid = fork(); 2738 if (pid == 0) { 2739 /* child -- drop privileges before continuing */ 2740 drop_capabilities(app_shared_gid); 2741 args.Exec(); 2742 } 2743 2744 /* parent */ 2745 int return_code = wait_child(pid); 2746 if (!WIFEXITED(return_code)) { 2747 LOG(WARNING) << "profman failed for " << package_name << ":" << profile_name; 2748 return false; 2749 } 2750 2751 return true; 2752 } 2753 2754 static bool create_boot_image_profile_snapshot(const std::string& package_name, 2755 const std::string& profile_name, 2756 const std::string& classpath) { 2757 // The reference profile directory for the android package might not be prepared. Do it now. 2758 const std::string ref_profile_dir = 2759 create_primary_reference_profile_package_dir_path(package_name); 2760 if (fs_prepare_dir(ref_profile_dir.c_str(), 0770, AID_SYSTEM, AID_SYSTEM) != 0) { 2761 PLOG(ERROR) << "Failed to prepare " << ref_profile_dir; 2762 return false; 2763 } 2764 2765 // Return false for empty class path since it may otherwise return true below if profiles is 2766 // empty. 2767 if (classpath.empty()) { 2768 PLOG(ERROR) << "Class path is empty"; 2769 return false; 2770 } 2771 2772 // Open and create the snapshot profile. 2773 unique_fd snapshot_fd = open_spnashot_profile(AID_SYSTEM, package_name, profile_name); 2774 2775 // Collect all non empty profiles. 2776 // The collection will traverse all applications profiles and find the non empty files. 2777 // This has the potential of inspecting a large number of files and directories (depending 2778 // on the number of applications and users). So there is a slight increase in the chance 2779 // to get get occasionally I/O errors (e.g. for opening the file). When that happens do not 2780 // fail the snapshot and aggregate whatever profile we could open. 2781 // 2782 // The profile snapshot is a best effort based on available data it's ok if some data 2783 // from some apps is missing. It will be counter productive for the snapshot to fail 2784 // because we could not open or read some of the files. 2785 std::vector<std::string> profiles; 2786 if (!collect_profiles(&profiles)) { 2787 LOG(WARNING) << "There were errors while collecting the profiles for the boot image."; 2788 } 2789 2790 // If we have no profiles return early. 2791 if (profiles.empty()) { 2792 return true; 2793 } 2794 2795 // Open the classpath elements. These will be used to filter out profile data that does 2796 // not belong to the classpath during merge. 2797 std::vector<unique_fd> apk_fds; 2798 std::vector<std::string> dex_locations; 2799 if (!open_classpath_files(classpath, &apk_fds, &dex_locations)) { 2800 return false; 2801 } 2802 2803 // If we could not open any files from the classpath return an error. 2804 if (apk_fds.empty()) { 2805 LOG(ERROR) << "Could not open any of the classpath elements."; 2806 return false; 2807 } 2808 2809 // Aggregate the profiles in batches of kAggregationBatchSize. 2810 // We do this to avoid opening a huge a amount of files. 2811 static constexpr size_t kAggregationBatchSize = 10; 2812 2813 std::vector<unique_fd> profiles_fd; 2814 for (size_t i = 0; i < profiles.size(); ) { 2815 for (size_t k = 0; k < kAggregationBatchSize && i < profiles.size(); k++, i++) { 2816 unique_fd fd = open_profile(AID_SYSTEM, profiles[i], O_RDONLY); 2817 if (fd.get() >= 0) { 2818 profiles_fd.push_back(std::move(fd)); 2819 } 2820 } 2821 RunProfman args; 2822 args.SetupMerge(profiles_fd, 2823 snapshot_fd, 2824 apk_fds, 2825 dex_locations, 2826 /*store_aggregation_counters=*/true); 2827 pid_t pid = fork(); 2828 if (pid == 0) { 2829 /* child -- drop privileges before continuing */ 2830 drop_capabilities(AID_SYSTEM); 2831 2832 // The introduction of new access flags into boot jars causes them to 2833 // fail dex file verification. 2834 args.Exec(); 2835 } 2836 2837 /* parent */ 2838 int return_code = wait_child(pid); 2839 if (!WIFEXITED(return_code)) { 2840 PLOG(WARNING) << "profman failed for " << package_name << ":" << profile_name; 2841 return false; 2842 } 2843 return true; 2844 } 2845 return true; 2846 } 2847 2848 bool create_profile_snapshot(int32_t app_id, const std::string& package_name, 2849 const std::string& profile_name, const std::string& classpath) { 2850 if (app_id == -1) { 2851 return create_boot_image_profile_snapshot(package_name, profile_name, classpath); 2852 } else { 2853 return create_app_profile_snapshot(app_id, package_name, profile_name, classpath); 2854 } 2855 } 2856 2857 bool prepare_app_profile(const std::string& package_name, 2858 userid_t user_id, 2859 appid_t app_id, 2860 const std::string& profile_name, 2861 const std::string& code_path, 2862 const std::unique_ptr<std::string>& dex_metadata) { 2863 // Prepare the current profile. 2864 std::string cur_profile = create_current_profile_path(user_id, package_name, profile_name, 2865 /*is_secondary_dex*/ false); 2866 uid_t uid = multiuser_get_uid(user_id, app_id); 2867 if (fs_prepare_file_strict(cur_profile.c_str(), 0600, uid, uid) != 0) { 2868 PLOG(ERROR) << "Failed to prepare " << cur_profile; 2869 return false; 2870 } 2871 2872 // Check if we need to install the profile from the dex metadata. 2873 if (dex_metadata == nullptr) { 2874 return true; 2875 } 2876 2877 // We have a dex metdata. Merge the profile into the reference profile. 2878 unique_fd ref_profile_fd = open_reference_profile(uid, package_name, profile_name, 2879 /*read_write*/ true, /*is_secondary_dex*/ false); 2880 unique_fd dex_metadata_fd(TEMP_FAILURE_RETRY( 2881 open(dex_metadata->c_str(), O_RDONLY | O_NOFOLLOW))); 2882 unique_fd apk_fd(TEMP_FAILURE_RETRY(open(code_path.c_str(), O_RDONLY | O_NOFOLLOW))); 2883 if (apk_fd < 0) { 2884 PLOG(ERROR) << "Could not open code path " << code_path; 2885 return false; 2886 } 2887 2888 RunProfman args; 2889 args.SetupCopyAndUpdate(std::move(dex_metadata_fd), 2890 std::move(ref_profile_fd), 2891 std::move(apk_fd), 2892 code_path); 2893 pid_t pid = fork(); 2894 if (pid == 0) { 2895 /* child -- drop privileges before continuing */ 2896 gid_t app_shared_gid = multiuser_get_shared_gid(user_id, app_id); 2897 drop_capabilities(app_shared_gid); 2898 2899 // The copy and update takes ownership over the fds. 2900 args.Exec(); 2901 } 2902 2903 /* parent */ 2904 int return_code = wait_child(pid); 2905 if (!WIFEXITED(return_code)) { 2906 PLOG(WARNING) << "profman failed for " << package_name << ":" << profile_name; 2907 return false; 2908 } 2909 return true; 2910 } 2911 2912 } // namespace installd 2913 } // namespace android 2914