dexopt.cpp revision 9014ca88a9412cb1a1168ae842f30f8783ea1e3d
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 "installed" 17 18#include <fcntl.h> 19#include <stdlib.h> 20#include <string.h> 21#include <sys/capability.h> 22#include <sys/file.h> 23#include <sys/stat.h> 24#include <sys/time.h> 25#include <sys/types.h> 26#include <sys/resource.h> 27#include <sys/wait.h> 28#include <unistd.h> 29 30#include <android-base/logging.h> 31#include <android-base/stringprintf.h> 32#include <android-base/strings.h> 33#include <android-base/unique_fd.h> 34#include <cutils/fs.h> 35#include <cutils/properties.h> 36#include <cutils/sched_policy.h> 37#include <log/log.h> // TODO: Move everything to base/logging. 38#include <private/android_filesystem_config.h> 39#include <selinux/android.h> 40#include <system/thread_defs.h> 41 42#include "dexopt.h" 43#include "installd_deps.h" 44#include "otapreopt_utils.h" 45#include "utils.h" 46 47using android::base::StringPrintf; 48using android::base::EndsWith; 49using android::base::unique_fd; 50 51namespace android { 52namespace installd { 53 54// Deleter using free() for use with std::unique_ptr<>. See also UniqueCPtr<> below. 55struct FreeDelete { 56 // NOTE: Deleting a const object is valid but free() takes a non-const pointer. 57 void operator()(const void* ptr) const { 58 free(const_cast<void*>(ptr)); 59 } 60}; 61 62// Alias for std::unique_ptr<> that uses the C function free() to delete objects. 63template <typename T> 64using UniqueCPtr = std::unique_ptr<T, FreeDelete>; 65 66static unique_fd invalid_unique_fd() { 67 return unique_fd(-1); 68} 69 70static bool clear_profile(const std::string& profile) { 71 unique_fd ufd(open(profile.c_str(), O_WRONLY | O_NOFOLLOW | O_CLOEXEC)); 72 if (ufd.get() < 0) { 73 if (errno != ENOENT) { 74 PLOG(WARNING) << "Could not open profile " << profile; 75 return false; 76 } else { 77 // Nothing to clear. That's ok. 78 return true; 79 } 80 } 81 82 if (flock(ufd.get(), LOCK_EX | LOCK_NB) != 0) { 83 if (errno != EWOULDBLOCK) { 84 PLOG(WARNING) << "Error locking profile " << profile; 85 } 86 // This implies that the app owning this profile is running 87 // (and has acquired the lock). 88 // 89 // If we can't acquire the lock bail out since clearing is useless anyway 90 // (the app will write again to the profile). 91 // 92 // Note: 93 // This does not impact the this is not an issue for the profiling correctness. 94 // In case this is needed because of an app upgrade, profiles will still be 95 // eventually cleared by the app itself due to checksum mismatch. 96 // If this is needed because profman advised, then keeping the data around 97 // until the next run is again not an issue. 98 // 99 // If the app attempts to acquire a lock while we've held one here, 100 // it will simply skip the current write cycle. 101 return false; 102 } 103 104 bool truncated = ftruncate(ufd.get(), 0) == 0; 105 if (!truncated) { 106 PLOG(WARNING) << "Could not truncate " << profile; 107 } 108 if (flock(ufd.get(), LOCK_UN) != 0) { 109 PLOG(WARNING) << "Error unlocking profile " << profile; 110 } 111 return truncated; 112} 113 114// Clear the reference profile for the given location. 115// The location is the package name for primary apks or the dex path for secondary dex files. 116static bool clear_reference_profile(const std::string& location, bool is_secondary_dex) { 117 return clear_profile(create_reference_profile_path(location, is_secondary_dex)); 118} 119 120// Clear the reference profile for the given location. 121// The location is the package name for primary apks or the dex path for secondary dex files. 122static bool clear_current_profile(const std::string& pkgname, userid_t user, 123 bool is_secondary_dex) { 124 return clear_profile(create_current_profile_path(user, pkgname, is_secondary_dex)); 125} 126 127// Clear the reference profile for the primary apk of the given package. 128bool clear_primary_reference_profile(const std::string& pkgname) { 129 return clear_reference_profile(pkgname, /*is_secondary_dex*/false); 130} 131 132// Clear all current profile for the primary apk of the given package. 133bool clear_primary_current_profiles(const std::string& pkgname) { 134 bool success = true; 135 // For secondary dex files, we don't really need the user but we use it for sanity checks. 136 std::vector<userid_t> users = get_known_users(/*volume_uuid*/ nullptr); 137 for (auto user : users) { 138 success &= clear_current_profile(pkgname, user, /*is_secondary_dex*/false); 139 } 140 return success; 141} 142 143// Clear the current profile for the primary apk of the given package and user. 144bool clear_primary_current_profile(const std::string& pkgname, userid_t user) { 145 return clear_current_profile(pkgname, user, /*is_secondary_dex*/false); 146} 147 148static int split_count(const char *str) 149{ 150 char *ctx; 151 int count = 0; 152 char buf[kPropertyValueMax]; 153 154 strncpy(buf, str, sizeof(buf)); 155 char *pBuf = buf; 156 157 while(strtok_r(pBuf, " ", &ctx) != NULL) { 158 count++; 159 pBuf = NULL; 160 } 161 162 return count; 163} 164 165static int split(char *buf, const char **argv) 166{ 167 char *ctx; 168 int count = 0; 169 char *tok; 170 char *pBuf = buf; 171 172 while((tok = strtok_r(pBuf, " ", &ctx)) != NULL) { 173 argv[count++] = tok; 174 pBuf = NULL; 175 } 176 177 return count; 178} 179 180static const char* get_location_from_path(const char* path) { 181 static constexpr char kLocationSeparator = '/'; 182 const char *location = strrchr(path, kLocationSeparator); 183 if (location == NULL) { 184 return path; 185 } else { 186 // Skip the separator character. 187 return location + 1; 188 } 189} 190 191static void run_dex2oat(int zip_fd, int oat_fd, int input_vdex_fd, int output_vdex_fd, int image_fd, 192 const char* input_file_name, const char* output_file_name, int swap_fd, 193 const char* instruction_set, const char* compiler_filter, bool vm_safe_mode, 194 bool debuggable, bool post_bootcomplete, int profile_fd, const char* shared_libraries) { 195 static const unsigned int MAX_INSTRUCTION_SET_LEN = 7; 196 197 if (strlen(instruction_set) >= MAX_INSTRUCTION_SET_LEN) { 198 ALOGE("Instruction set %s longer than max length of %d", 199 instruction_set, MAX_INSTRUCTION_SET_LEN); 200 return; 201 } 202 203 // Get the relative path to the input file. 204 const char* relative_input_file_name = get_location_from_path(input_file_name); 205 206 char dex2oat_Xms_flag[kPropertyValueMax]; 207 bool have_dex2oat_Xms_flag = get_property("dalvik.vm.dex2oat-Xms", dex2oat_Xms_flag, NULL) > 0; 208 209 char dex2oat_Xmx_flag[kPropertyValueMax]; 210 bool have_dex2oat_Xmx_flag = get_property("dalvik.vm.dex2oat-Xmx", dex2oat_Xmx_flag, NULL) > 0; 211 212 char dex2oat_threads_buf[kPropertyValueMax]; 213 bool have_dex2oat_threads_flag = get_property(post_bootcomplete 214 ? "dalvik.vm.dex2oat-threads" 215 : "dalvik.vm.boot-dex2oat-threads", 216 dex2oat_threads_buf, 217 NULL) > 0; 218 char dex2oat_threads_arg[kPropertyValueMax + 2]; 219 if (have_dex2oat_threads_flag) { 220 sprintf(dex2oat_threads_arg, "-j%s", dex2oat_threads_buf); 221 } 222 223 char dex2oat_isa_features_key[kPropertyKeyMax]; 224 sprintf(dex2oat_isa_features_key, "dalvik.vm.isa.%s.features", instruction_set); 225 char dex2oat_isa_features[kPropertyValueMax]; 226 bool have_dex2oat_isa_features = get_property(dex2oat_isa_features_key, 227 dex2oat_isa_features, NULL) > 0; 228 229 char dex2oat_isa_variant_key[kPropertyKeyMax]; 230 sprintf(dex2oat_isa_variant_key, "dalvik.vm.isa.%s.variant", instruction_set); 231 char dex2oat_isa_variant[kPropertyValueMax]; 232 bool have_dex2oat_isa_variant = get_property(dex2oat_isa_variant_key, 233 dex2oat_isa_variant, NULL) > 0; 234 235 const char *dex2oat_norelocation = "-Xnorelocate"; 236 bool have_dex2oat_relocation_skip_flag = false; 237 238 char dex2oat_flags[kPropertyValueMax]; 239 int dex2oat_flags_count = get_property("dalvik.vm.dex2oat-flags", 240 dex2oat_flags, NULL) <= 0 ? 0 : split_count(dex2oat_flags); 241 ALOGV("dalvik.vm.dex2oat-flags=%s\n", dex2oat_flags); 242 243 // If we booting without the real /data, don't spend time compiling. 244 char vold_decrypt[kPropertyValueMax]; 245 bool have_vold_decrypt = get_property("vold.decrypt", vold_decrypt, "") > 0; 246 bool skip_compilation = (have_vold_decrypt && 247 (strcmp(vold_decrypt, "trigger_restart_min_framework") == 0 || 248 (strcmp(vold_decrypt, "1") == 0))); 249 250 bool generate_debug_info = property_get_bool("debug.generate-debug-info", false); 251 252 char app_image_format[kPropertyValueMax]; 253 char image_format_arg[strlen("--image-format=") + kPropertyValueMax]; 254 bool have_app_image_format = 255 image_fd >= 0 && get_property("dalvik.vm.appimageformat", app_image_format, NULL) > 0; 256 if (have_app_image_format) { 257 sprintf(image_format_arg, "--image-format=%s", app_image_format); 258 } 259 260 char dex2oat_large_app_threshold[kPropertyValueMax]; 261 bool have_dex2oat_large_app_threshold = 262 get_property("dalvik.vm.dex2oat-very-large", dex2oat_large_app_threshold, NULL) > 0; 263 char dex2oat_large_app_threshold_arg[strlen("--very-large-app-threshold=") + kPropertyValueMax]; 264 if (have_dex2oat_large_app_threshold) { 265 sprintf(dex2oat_large_app_threshold_arg, 266 "--very-large-app-threshold=%s", 267 dex2oat_large_app_threshold); 268 } 269 270 static const char* DEX2OAT_BIN = "/system/bin/dex2oat"; 271 272 static const char* RUNTIME_ARG = "--runtime-arg"; 273 274 static const int MAX_INT_LEN = 12; // '-'+10dig+'\0' -OR- 0x+8dig 275 276 // clang FORTIFY doesn't let us use strlen in constant array bounds, so we 277 // use arraysize instead. 278 char zip_fd_arg[arraysize("--zip-fd=") + MAX_INT_LEN]; 279 char zip_location_arg[arraysize("--zip-location=") + PKG_PATH_MAX]; 280 char input_vdex_fd_arg[arraysize("--input-vdex-fd=") + MAX_INT_LEN]; 281 char output_vdex_fd_arg[arraysize("--output-vdex-fd=") + MAX_INT_LEN]; 282 char oat_fd_arg[arraysize("--oat-fd=") + MAX_INT_LEN]; 283 char oat_location_arg[arraysize("--oat-location=") + PKG_PATH_MAX]; 284 char instruction_set_arg[arraysize("--instruction-set=") + MAX_INSTRUCTION_SET_LEN]; 285 char instruction_set_variant_arg[arraysize("--instruction-set-variant=") + kPropertyValueMax]; 286 char instruction_set_features_arg[arraysize("--instruction-set-features=") + kPropertyValueMax]; 287 char dex2oat_Xms_arg[arraysize("-Xms") + kPropertyValueMax]; 288 char dex2oat_Xmx_arg[arraysize("-Xmx") + kPropertyValueMax]; 289 char dex2oat_compiler_filter_arg[arraysize("--compiler-filter=") + kPropertyValueMax]; 290 bool have_dex2oat_swap_fd = false; 291 char dex2oat_swap_fd[arraysize("--swap-fd=") + MAX_INT_LEN]; 292 bool have_dex2oat_image_fd = false; 293 char dex2oat_image_fd[arraysize("--app-image-fd=") + MAX_INT_LEN]; 294 295 sprintf(zip_fd_arg, "--zip-fd=%d", zip_fd); 296 sprintf(zip_location_arg, "--zip-location=%s", relative_input_file_name); 297 sprintf(input_vdex_fd_arg, "--input-vdex-fd=%d", input_vdex_fd); 298 sprintf(output_vdex_fd_arg, "--output-vdex-fd=%d", output_vdex_fd); 299 sprintf(oat_fd_arg, "--oat-fd=%d", oat_fd); 300 sprintf(oat_location_arg, "--oat-location=%s", output_file_name); 301 sprintf(instruction_set_arg, "--instruction-set=%s", instruction_set); 302 sprintf(instruction_set_variant_arg, "--instruction-set-variant=%s", dex2oat_isa_variant); 303 sprintf(instruction_set_features_arg, "--instruction-set-features=%s", dex2oat_isa_features); 304 if (swap_fd >= 0) { 305 have_dex2oat_swap_fd = true; 306 sprintf(dex2oat_swap_fd, "--swap-fd=%d", swap_fd); 307 } 308 if (image_fd >= 0) { 309 have_dex2oat_image_fd = true; 310 sprintf(dex2oat_image_fd, "--app-image-fd=%d", image_fd); 311 } 312 313 if (have_dex2oat_Xms_flag) { 314 sprintf(dex2oat_Xms_arg, "-Xms%s", dex2oat_Xms_flag); 315 } 316 if (have_dex2oat_Xmx_flag) { 317 sprintf(dex2oat_Xmx_arg, "-Xmx%s", dex2oat_Xmx_flag); 318 } 319 320 // Compute compiler filter. 321 322 bool have_dex2oat_compiler_filter_flag; 323 if (skip_compilation) { 324 strcpy(dex2oat_compiler_filter_arg, "--compiler-filter=extract"); 325 have_dex2oat_compiler_filter_flag = true; 326 have_dex2oat_relocation_skip_flag = true; 327 } else if (vm_safe_mode) { 328 strcpy(dex2oat_compiler_filter_arg, "--compiler-filter=quicken"); 329 have_dex2oat_compiler_filter_flag = true; 330 } else if (compiler_filter != nullptr && 331 strlen(compiler_filter) + strlen("--compiler-filter=") < 332 arraysize(dex2oat_compiler_filter_arg)) { 333 sprintf(dex2oat_compiler_filter_arg, "--compiler-filter=%s", compiler_filter); 334 have_dex2oat_compiler_filter_flag = true; 335 } else { 336 char dex2oat_compiler_filter_flag[kPropertyValueMax]; 337 have_dex2oat_compiler_filter_flag = get_property("dalvik.vm.dex2oat-filter", 338 dex2oat_compiler_filter_flag, NULL) > 0; 339 if (have_dex2oat_compiler_filter_flag) { 340 sprintf(dex2oat_compiler_filter_arg, 341 "--compiler-filter=%s", 342 dex2oat_compiler_filter_flag); 343 } 344 } 345 346 // Check whether all apps should be compiled debuggable. 347 if (!debuggable) { 348 char prop_buf[kPropertyValueMax]; 349 debuggable = 350 (get_property("dalvik.vm.always_debuggable", prop_buf, "0") > 0) && 351 (prop_buf[0] == '1'); 352 } 353 char profile_arg[strlen("--profile-file-fd=") + MAX_INT_LEN]; 354 if (profile_fd != -1) { 355 sprintf(profile_arg, "--profile-file-fd=%d", profile_fd); 356 } 357 358 // Get the directory of the apk to pass as a base classpath directory. 359 char base_dir[arraysize("--classpath-dir=") + PKG_PATH_MAX]; 360 std::string apk_dir(input_file_name); 361 unsigned long dir_index = apk_dir.rfind('/'); 362 bool has_base_dir = dir_index != std::string::npos; 363 if (has_base_dir) { 364 apk_dir = apk_dir.substr(0, dir_index); 365 sprintf(base_dir, "--classpath-dir=%s", apk_dir.c_str()); 366 } 367 368 369 ALOGV("Running %s in=%s out=%s\n", DEX2OAT_BIN, relative_input_file_name, output_file_name); 370 371 const char* argv[9 // program name, mandatory arguments and the final NULL 372 + (have_dex2oat_isa_variant ? 1 : 0) 373 + (have_dex2oat_isa_features ? 1 : 0) 374 + (have_dex2oat_Xms_flag ? 2 : 0) 375 + (have_dex2oat_Xmx_flag ? 2 : 0) 376 + (have_dex2oat_compiler_filter_flag ? 1 : 0) 377 + (have_dex2oat_threads_flag ? 1 : 0) 378 + (have_dex2oat_swap_fd ? 1 : 0) 379 + (have_dex2oat_image_fd ? 1 : 0) 380 + (have_dex2oat_relocation_skip_flag ? 2 : 0) 381 + (generate_debug_info ? 1 : 0) 382 + (debuggable ? 1 : 0) 383 + (have_app_image_format ? 1 : 0) 384 + dex2oat_flags_count 385 + (profile_fd == -1 ? 0 : 1) 386 + (shared_libraries != nullptr ? 4 : 0) 387 + (has_base_dir ? 1 : 0) 388 + (have_dex2oat_large_app_threshold ? 1 : 0)]; 389 int i = 0; 390 argv[i++] = DEX2OAT_BIN; 391 argv[i++] = zip_fd_arg; 392 argv[i++] = zip_location_arg; 393 argv[i++] = input_vdex_fd_arg; 394 argv[i++] = output_vdex_fd_arg; 395 argv[i++] = oat_fd_arg; 396 argv[i++] = oat_location_arg; 397 argv[i++] = instruction_set_arg; 398 if (have_dex2oat_isa_variant) { 399 argv[i++] = instruction_set_variant_arg; 400 } 401 if (have_dex2oat_isa_features) { 402 argv[i++] = instruction_set_features_arg; 403 } 404 if (have_dex2oat_Xms_flag) { 405 argv[i++] = RUNTIME_ARG; 406 argv[i++] = dex2oat_Xms_arg; 407 } 408 if (have_dex2oat_Xmx_flag) { 409 argv[i++] = RUNTIME_ARG; 410 argv[i++] = dex2oat_Xmx_arg; 411 } 412 if (have_dex2oat_compiler_filter_flag) { 413 argv[i++] = dex2oat_compiler_filter_arg; 414 } 415 if (have_dex2oat_threads_flag) { 416 argv[i++] = dex2oat_threads_arg; 417 } 418 if (have_dex2oat_swap_fd) { 419 argv[i++] = dex2oat_swap_fd; 420 } 421 if (have_dex2oat_image_fd) { 422 argv[i++] = dex2oat_image_fd; 423 } 424 if (generate_debug_info) { 425 argv[i++] = "--generate-debug-info"; 426 } 427 if (debuggable) { 428 argv[i++] = "--debuggable"; 429 } 430 if (have_app_image_format) { 431 argv[i++] = image_format_arg; 432 } 433 if (have_dex2oat_large_app_threshold) { 434 argv[i++] = dex2oat_large_app_threshold_arg; 435 } 436 if (dex2oat_flags_count) { 437 i += split(dex2oat_flags, argv + i); 438 } 439 if (have_dex2oat_relocation_skip_flag) { 440 argv[i++] = RUNTIME_ARG; 441 argv[i++] = dex2oat_norelocation; 442 } 443 if (profile_fd != -1) { 444 argv[i++] = profile_arg; 445 } 446 if (shared_libraries != nullptr) { 447 argv[i++] = RUNTIME_ARG; 448 argv[i++] = "-classpath"; 449 argv[i++] = RUNTIME_ARG; 450 argv[i++] = shared_libraries; 451 } 452 if (has_base_dir) { 453 argv[i++] = base_dir; 454 } 455 // Do not add after dex2oat_flags, they should override others for debugging. 456 argv[i] = NULL; 457 458 execv(DEX2OAT_BIN, (char * const *)argv); 459 ALOGE("execv(%s) failed: %s\n", DEX2OAT_BIN, strerror(errno)); 460} 461 462/* 463 * Whether dexopt should use a swap file when compiling an APK. 464 * 465 * If kAlwaysProvideSwapFile, do this on all devices (dex2oat will make a more informed decision 466 * itself, anyways). 467 * 468 * Otherwise, read "dalvik.vm.dex2oat-swap". If the property exists, return whether it is "true". 469 * 470 * Otherwise, return true if this is a low-mem device. 471 * 472 * Otherwise, return default value. 473 */ 474static bool kAlwaysProvideSwapFile = false; 475static bool kDefaultProvideSwapFile = true; 476 477static bool ShouldUseSwapFileForDexopt() { 478 if (kAlwaysProvideSwapFile) { 479 return true; 480 } 481 482 // Check the "override" property. If it exists, return value == "true". 483 char dex2oat_prop_buf[kPropertyValueMax]; 484 if (get_property("dalvik.vm.dex2oat-swap", dex2oat_prop_buf, "") > 0) { 485 if (strcmp(dex2oat_prop_buf, "true") == 0) { 486 return true; 487 } else { 488 return false; 489 } 490 } 491 492 // Shortcut for default value. This is an implementation optimization for the process sketched 493 // above. If the default value is true, we can avoid to check whether this is a low-mem device, 494 // as low-mem is never returning false. The compiler will optimize this away if it can. 495 if (kDefaultProvideSwapFile) { 496 return true; 497 } 498 499 bool is_low_mem = property_get_bool("ro.config.low_ram", false); 500 if (is_low_mem) { 501 return true; 502 } 503 504 // Default value must be false here. 505 return kDefaultProvideSwapFile; 506} 507 508static void SetDex2OatScheduling(bool set_to_bg) { 509 if (set_to_bg) { 510 if (set_sched_policy(0, SP_BACKGROUND) < 0) { 511 ALOGE("set_sched_policy failed: %s\n", strerror(errno)); 512 exit(70); 513 } 514 if (setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_BACKGROUND) < 0) { 515 ALOGE("setpriority failed: %s\n", strerror(errno)); 516 exit(71); 517 } 518 } 519} 520 521static bool create_profile(int uid, const std::string& profile) { 522 unique_fd fd(TEMP_FAILURE_RETRY(open(profile.c_str(), O_CREAT | O_NOFOLLOW, 0600))); 523 if (fd.get() < 0) { 524 if (errno == EEXIST) { 525 return true; 526 } else { 527 PLOG(ERROR) << "Failed to create profile " << profile; 528 return false; 529 } 530 } 531 // Profiles should belong to the app; make sure of that by giving ownership to 532 // the app uid. If we cannot do that, there's no point in returning the fd 533 // since dex2oat/profman will fail with SElinux denials. 534 if (fchown(fd.get(), uid, uid) < 0) { 535 PLOG(ERROR) << "Could not chwon profile " << profile; 536 return false; 537 } 538 return true; 539} 540 541static unique_fd open_profile(int uid, const std::string& profile, bool read_write) { 542 // Check if we need to open the profile for a read-write operation. If so, we 543 // might need to create the profile since the file might not be there. Reference 544 // profiles are created on the fly so they might not exist beforehand. 545 if (read_write) { 546 if (!create_profile(uid, profile)) { 547 return invalid_unique_fd(); 548 } 549 } 550 int flags = read_write ? O_RDWR : O_RDONLY; 551 // Do not follow symlinks when opening a profile: 552 // - primary profiles should not contain symlinks in their paths 553 // - secondary dex paths should have been already resolved and validated 554 flags |= O_NOFOLLOW; 555 556 unique_fd fd(TEMP_FAILURE_RETRY(open(profile.c_str(), flags))); 557 if (fd.get() < 0) { 558 if (errno != ENOENT) { 559 // Profiles might be missing for various reasons. For example, in a 560 // multi-user environment, the profile directory for one user can be created 561 // after we start a merge. In this case the current profile for that user 562 // will not be found. 563 // Also, the secondary dex profiles might be deleted by the app at any time, 564 // so we can't we need to prepare if they are missing. 565 PLOG(ERROR) << "Failed to open profile " << profile; 566 } 567 return invalid_unique_fd(); 568 } 569 570 return fd; 571} 572 573static unique_fd open_current_profile(uid_t uid, userid_t user, const std::string& location, 574 bool is_secondary_dex) { 575 std::string profile = create_current_profile_path(user, location, is_secondary_dex); 576 return open_profile(uid, profile, /*read_write*/false); 577} 578 579static unique_fd open_reference_profile(uid_t uid, const std::string& location, bool read_write, 580 bool is_secondary_dex) { 581 std::string profile = create_reference_profile_path(location, is_secondary_dex); 582 return open_profile(uid, profile, read_write); 583} 584 585static void open_profile_files(uid_t uid, const std::string& location, bool is_secondary_dex, 586 /*out*/ std::vector<unique_fd>* profiles_fd, /*out*/ unique_fd* reference_profile_fd) { 587 // Open the reference profile in read-write mode as profman might need to save the merge. 588 *reference_profile_fd = open_reference_profile(uid, location, /*read_write*/ true, 589 is_secondary_dex); 590 591 // For secondary dex files, we don't really need the user but we use it for sanity checks. 592 // Note: the user owning the dex file should be the current user. 593 std::vector<userid_t> users; 594 if (is_secondary_dex){ 595 users.push_back(multiuser_get_user_id(uid)); 596 } else { 597 users = get_known_users(/*volume_uuid*/ nullptr); 598 } 599 for (auto user : users) { 600 unique_fd profile_fd = open_current_profile(uid, user, location, is_secondary_dex); 601 // Add to the lists only if both fds are valid. 602 if (profile_fd.get() >= 0) { 603 profiles_fd->push_back(std::move(profile_fd)); 604 } 605 } 606} 607 608static void drop_capabilities(uid_t uid) { 609 if (setgid(uid) != 0) { 610 ALOGE("setgid(%d) failed in installd during dexopt\n", uid); 611 exit(64); 612 } 613 if (setuid(uid) != 0) { 614 ALOGE("setuid(%d) failed in installd during dexopt\n", uid); 615 exit(65); 616 } 617 // drop capabilities 618 struct __user_cap_header_struct capheader; 619 struct __user_cap_data_struct capdata[2]; 620 memset(&capheader, 0, sizeof(capheader)); 621 memset(&capdata, 0, sizeof(capdata)); 622 capheader.version = _LINUX_CAPABILITY_VERSION_3; 623 if (capset(&capheader, &capdata[0]) < 0) { 624 ALOGE("capset failed: %s\n", strerror(errno)); 625 exit(66); 626 } 627} 628 629static constexpr int PROFMAN_BIN_RETURN_CODE_COMPILE = 0; 630static constexpr int PROFMAN_BIN_RETURN_CODE_SKIP_COMPILATION = 1; 631static constexpr int PROFMAN_BIN_RETURN_CODE_BAD_PROFILES = 2; 632static constexpr int PROFMAN_BIN_RETURN_CODE_ERROR_IO = 3; 633static constexpr int PROFMAN_BIN_RETURN_CODE_ERROR_LOCKING = 4; 634 635static void run_profman_merge(const std::vector<unique_fd>& profiles_fd, 636 const unique_fd& reference_profile_fd) { 637 static const size_t MAX_INT_LEN = 32; 638 static const char* PROFMAN_BIN = "/system/bin/profman"; 639 640 std::vector<std::string> profile_args(profiles_fd.size()); 641 char profile_buf[strlen("--profile-file-fd=") + MAX_INT_LEN]; 642 for (size_t k = 0; k < profiles_fd.size(); k++) { 643 sprintf(profile_buf, "--profile-file-fd=%d", profiles_fd[k].get()); 644 profile_args[k].assign(profile_buf); 645 } 646 char reference_profile_arg[strlen("--reference-profile-file-fd=") + MAX_INT_LEN]; 647 sprintf(reference_profile_arg, "--reference-profile-file-fd=%d", reference_profile_fd.get()); 648 649 // program name, reference profile fd, the final NULL and the profile fds 650 const char* argv[3 + profiles_fd.size()]; 651 int i = 0; 652 argv[i++] = PROFMAN_BIN; 653 argv[i++] = reference_profile_arg; 654 for (size_t k = 0; k < profile_args.size(); k++) { 655 argv[i++] = profile_args[k].c_str(); 656 } 657 // Do not add after dex2oat_flags, they should override others for debugging. 658 argv[i] = NULL; 659 660 execv(PROFMAN_BIN, (char * const *)argv); 661 ALOGE("execv(%s) failed: %s\n", PROFMAN_BIN, strerror(errno)); 662 exit(68); /* only get here on exec failure */ 663} 664 665// Decides if profile guided compilation is needed or not based on existing profiles. 666// The location is the package name for primary apks or the dex path for secondary dex files. 667// Returns true if there is enough information in the current profiles that makes it 668// worth to recompile the given location. 669// If the return value is true all the current profiles would have been merged into 670// the reference profiles accessible with open_reference_profile(). 671static bool analyze_profiles(uid_t uid, const std::string& location, bool is_secondary_dex) { 672 std::vector<unique_fd> profiles_fd; 673 unique_fd reference_profile_fd; 674 open_profile_files(uid, location, is_secondary_dex, &profiles_fd, &reference_profile_fd); 675 if (profiles_fd.empty() || (reference_profile_fd.get() < 0)) { 676 // Skip profile guided compilation because no profiles were found. 677 // Or if the reference profile info couldn't be opened. 678 return false; 679 } 680 681 pid_t pid = fork(); 682 if (pid == 0) { 683 /* child -- drop privileges before continuing */ 684 drop_capabilities(uid); 685 run_profman_merge(profiles_fd, reference_profile_fd); 686 exit(68); /* only get here on exec failure */ 687 } 688 /* parent */ 689 int return_code = wait_child(pid); 690 bool need_to_compile = false; 691 bool should_clear_current_profiles = false; 692 bool should_clear_reference_profile = false; 693 if (!WIFEXITED(return_code)) { 694 LOG(WARNING) << "profman failed for location " << location << ": " << return_code; 695 } else { 696 return_code = WEXITSTATUS(return_code); 697 switch (return_code) { 698 case PROFMAN_BIN_RETURN_CODE_COMPILE: 699 need_to_compile = true; 700 should_clear_current_profiles = true; 701 should_clear_reference_profile = false; 702 break; 703 case PROFMAN_BIN_RETURN_CODE_SKIP_COMPILATION: 704 need_to_compile = false; 705 should_clear_current_profiles = false; 706 should_clear_reference_profile = false; 707 break; 708 case PROFMAN_BIN_RETURN_CODE_BAD_PROFILES: 709 LOG(WARNING) << "Bad profiles for location " << location; 710 need_to_compile = false; 711 should_clear_current_profiles = true; 712 should_clear_reference_profile = true; 713 break; 714 case PROFMAN_BIN_RETURN_CODE_ERROR_IO: // fall-through 715 case PROFMAN_BIN_RETURN_CODE_ERROR_LOCKING: 716 // Temporary IO problem (e.g. locking). Ignore but log a warning. 717 LOG(WARNING) << "IO error while reading profiles for location " << location; 718 need_to_compile = false; 719 should_clear_current_profiles = false; 720 should_clear_reference_profile = false; 721 break; 722 default: 723 // Unknown return code or error. Unlink profiles. 724 LOG(WARNING) << "Unknown error code while processing profiles for location " 725 << location << ": " << return_code; 726 need_to_compile = false; 727 should_clear_current_profiles = true; 728 should_clear_reference_profile = true; 729 break; 730 } 731 } 732 733 if (should_clear_current_profiles) { 734 if (is_secondary_dex) { 735 // For secondary dex files, the owning user is the current user. 736 clear_current_profile(location, multiuser_get_user_id(uid), is_secondary_dex); 737 } else { 738 clear_primary_current_profiles(location); 739 } 740 } 741 if (should_clear_reference_profile) { 742 clear_reference_profile(location, is_secondary_dex); 743 } 744 return need_to_compile; 745} 746 747// Decides if profile guided compilation is needed or not based on existing profiles. 748// The analysis is done for the primary apks of the given package. 749// Returns true if there is enough information in the current profiles that makes it 750// worth to recompile the package. 751// If the return value is true all the current profiles would have been merged into 752// the reference profiles accessible with open_reference_profile(). 753bool analyze_primary_profiles(uid_t uid, const std::string& pkgname) { 754 return analyze_profiles(uid, pkgname, /*is_secondary_dex*/false); 755} 756 757static void run_profman_dump(const std::vector<unique_fd>& profile_fds, 758 const unique_fd& reference_profile_fd, 759 const std::vector<std::string>& dex_locations, 760 const std::vector<unique_fd>& apk_fds, 761 const unique_fd& output_fd) { 762 std::vector<std::string> profman_args; 763 static const char* PROFMAN_BIN = "/system/bin/profman"; 764 profman_args.push_back(PROFMAN_BIN); 765 profman_args.push_back("--dump-only"); 766 profman_args.push_back(StringPrintf("--dump-output-to-fd=%d", output_fd.get())); 767 if (reference_profile_fd != -1) { 768 profman_args.push_back(StringPrintf("--reference-profile-file-fd=%d", 769 reference_profile_fd.get())); 770 } 771 for (size_t i = 0; i < profile_fds.size(); i++) { 772 profman_args.push_back(StringPrintf("--profile-file-fd=%d", profile_fds[i].get())); 773 } 774 for (const std::string& dex_location : dex_locations) { 775 profman_args.push_back(StringPrintf("--dex-location=%s", dex_location.c_str())); 776 } 777 for (size_t i = 0; i < apk_fds.size(); i++) { 778 profman_args.push_back(StringPrintf("--apk-fd=%d", apk_fds[i].get())); 779 } 780 const char **argv = new const char*[profman_args.size() + 1]; 781 size_t i = 0; 782 for (const std::string& profman_arg : profman_args) { 783 argv[i++] = profman_arg.c_str(); 784 } 785 argv[i] = NULL; 786 787 execv(PROFMAN_BIN, (char * const *)argv); 788 ALOGE("execv(%s) failed: %s\n", PROFMAN_BIN, strerror(errno)); 789 exit(68); /* only get here on exec failure */ 790} 791 792bool dump_profiles(int32_t uid, const std::string& pkgname, const char* code_paths) { 793 std::vector<unique_fd> profile_fds; 794 unique_fd reference_profile_fd; 795 std::string out_file_name = StringPrintf("/data/misc/profman/%s.txt", pkgname.c_str()); 796 797 open_profile_files(uid, pkgname, /*is_secondary_dex*/false, 798 &profile_fds, &reference_profile_fd); 799 800 const bool has_reference_profile = (reference_profile_fd.get() != -1); 801 const bool has_profiles = !profile_fds.empty(); 802 803 if (!has_reference_profile && !has_profiles) { 804 LOG(ERROR) << "profman dump: no profiles to dump for " << pkgname; 805 return false; 806 } 807 808 unique_fd output_fd(open(out_file_name.c_str(), 809 O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW, 0644)); 810 if (fchmod(output_fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) { 811 ALOGE("installd cannot chmod '%s' dump_profile\n", out_file_name.c_str()); 812 return false; 813 } 814 std::vector<std::string> code_full_paths = base::Split(code_paths, ";"); 815 std::vector<std::string> dex_locations; 816 std::vector<unique_fd> apk_fds; 817 for (const std::string& code_full_path : code_full_paths) { 818 const char* full_path = code_full_path.c_str(); 819 unique_fd apk_fd(open(full_path, O_RDONLY | O_NOFOLLOW)); 820 if (apk_fd == -1) { 821 ALOGE("installd cannot open '%s'\n", full_path); 822 return false; 823 } 824 dex_locations.push_back(get_location_from_path(full_path)); 825 apk_fds.push_back(std::move(apk_fd)); 826 } 827 828 pid_t pid = fork(); 829 if (pid == 0) { 830 /* child -- drop privileges before continuing */ 831 drop_capabilities(uid); 832 run_profman_dump(profile_fds, reference_profile_fd, dex_locations, 833 apk_fds, output_fd); 834 exit(68); /* only get here on exec failure */ 835 } 836 /* parent */ 837 int return_code = wait_child(pid); 838 if (!WIFEXITED(return_code)) { 839 LOG(WARNING) << "profman failed for package " << pkgname << ": " 840 << return_code; 841 return false; 842 } 843 return true; 844} 845 846static std::string replace_file_extension(const std::string& oat_path, const std::string& new_ext) { 847 // A standard dalvik-cache entry. Replace ".dex" with `new_ext`. 848 if (EndsWith(oat_path, ".dex")) { 849 std::string new_path = oat_path; 850 new_path.replace(new_path.length() - strlen(".dex"), strlen(".dex"), new_ext); 851 CHECK(EndsWith(new_path, new_ext.c_str())); 852 return new_path; 853 } 854 855 // An odex entry. Not that this may not be an extension, e.g., in the OTA 856 // case (where the base name will have an extension for the B artifact). 857 size_t odex_pos = oat_path.rfind(".odex"); 858 if (odex_pos != std::string::npos) { 859 std::string new_path = oat_path; 860 new_path.replace(odex_pos, strlen(".odex"), new_ext); 861 CHECK_NE(new_path.find(new_ext), std::string::npos); 862 return new_path; 863 } 864 865 // Don't know how to handle this. 866 return ""; 867} 868 869// Translate the given oat path to an art (app image) path. An empty string 870// denotes an error. 871static std::string create_image_filename(const std::string& oat_path) { 872 return replace_file_extension(oat_path, ".art"); 873} 874 875// Translate the given oat path to a vdex path. An empty string denotes an error. 876static std::string create_vdex_filename(const std::string& oat_path) { 877 return replace_file_extension(oat_path, ".vdex"); 878} 879 880static bool add_extension_to_file_name(char* file_name, const char* extension) { 881 if (strlen(file_name) + strlen(extension) + 1 > PKG_PATH_MAX) { 882 return false; 883 } 884 strcat(file_name, extension); 885 return true; 886} 887 888static int open_output_file(const char* file_name, bool recreate, int permissions) { 889 int flags = O_RDWR | O_CREAT; 890 if (recreate) { 891 if (unlink(file_name) < 0) { 892 if (errno != ENOENT) { 893 PLOG(ERROR) << "open_output_file: Couldn't unlink " << file_name; 894 } 895 } 896 flags |= O_EXCL; 897 } 898 return open(file_name, flags, permissions); 899} 900 901static bool set_permissions_and_ownership( 902 int fd, bool is_public, int uid, const char* path, bool is_secondary_dex) { 903 // Primary apks are owned by the system. Secondary dex files are owned by the app. 904 int owning_uid = is_secondary_dex ? uid : AID_SYSTEM; 905 if (fchmod(fd, 906 S_IRUSR|S_IWUSR|S_IRGRP | 907 (is_public ? S_IROTH : 0)) < 0) { 908 ALOGE("installd cannot chmod '%s' during dexopt\n", path); 909 return false; 910 } else if (fchown(fd, owning_uid, uid) < 0) { 911 ALOGE("installd cannot chown '%s' during dexopt\n", path); 912 return false; 913 } 914 return true; 915} 916 917static bool IsOutputDalvikCache(const char* oat_dir) { 918 // InstallerConnection.java (which invokes installd) transforms Java null arguments 919 // into '!'. Play it safe by handling it both. 920 // TODO: ensure we never get null. 921 // TODO: pass a flag instead of inferring if the output is dalvik cache. 922 return oat_dir == nullptr || oat_dir[0] == '!'; 923} 924 925static bool create_oat_out_path(const char* apk_path, const char* instruction_set, 926 const char* oat_dir, bool is_secondary_dex, /*out*/ char* out_oat_path) { 927 // Early best-effort check whether we can fit the the path into our buffers. 928 // Note: the cache path will require an additional 5 bytes for ".swap", but we'll try to run 929 // without a swap file, if necessary. Reference profiles file also add an extra ".prof" 930 // extension to the cache path (5 bytes). 931 if (strlen(apk_path) >= (PKG_PATH_MAX - 8)) { 932 ALOGE("apk_path too long '%s'\n", apk_path); 933 return false; 934 } 935 936 if (!IsOutputDalvikCache(oat_dir)) { 937 // Oat dirs for secondary dex files are already validated. 938 if (!is_secondary_dex && validate_apk_path(oat_dir)) { 939 ALOGE("cannot validate apk path with oat_dir '%s'\n", oat_dir); 940 return false; 941 } 942 if (!calculate_oat_file_path(out_oat_path, oat_dir, apk_path, instruction_set)) { 943 return false; 944 } 945 } else { 946 if (!create_cache_path(out_oat_path, apk_path, instruction_set)) { 947 return false; 948 } 949 } 950 return true; 951} 952 953// Helper for fd management. This is similar to a unique_fd in that it closes the file descriptor 954// on destruction. It will also run the given cleanup (unless told not to) after closing. 955// 956// Usage example: 957// 958// Dex2oatFileWrapper file(open(...), 959// [name]() { 960// unlink(name.c_str()); 961// }); 962// // Note: care needs to be taken about name, as it needs to have a lifetime longer than the 963// wrapper if captured as a reference. 964// 965// if (file.get() == -1) { 966// // Error opening... 967// } 968// 969// ... 970// if (error) { 971// // At this point, when the Dex2oatFileWrapper is destructed, the cleanup function will run 972// // and delete the file (after the fd is closed). 973// return -1; 974// } 975// 976// (Success case) 977// file.SetCleanup(false); 978// // At this point, when the Dex2oatFileWrapper is destructed, the cleanup function will not run 979// // (leaving the file around; after the fd is closed). 980// 981class Dex2oatFileWrapper { 982 public: 983 Dex2oatFileWrapper() : value_(-1), cleanup_(), do_cleanup_(true), auto_close_(true) { 984 } 985 986 Dex2oatFileWrapper(int value, std::function<void ()> cleanup) 987 : value_(value), cleanup_(cleanup), do_cleanup_(true), auto_close_(true) {} 988 989 Dex2oatFileWrapper(Dex2oatFileWrapper&& other) { 990 value_ = other.value_; 991 cleanup_ = other.cleanup_; 992 do_cleanup_ = other.do_cleanup_; 993 auto_close_ = other.auto_close_; 994 other.release(); 995 } 996 997 Dex2oatFileWrapper& operator=(Dex2oatFileWrapper&& other) { 998 value_ = other.value_; 999 cleanup_ = other.cleanup_; 1000 do_cleanup_ = other.do_cleanup_; 1001 auto_close_ = other.auto_close_; 1002 other.release(); 1003 return *this; 1004 } 1005 1006 ~Dex2oatFileWrapper() { 1007 reset(-1); 1008 } 1009 1010 int get() { 1011 return value_; 1012 } 1013 1014 void SetCleanup(bool cleanup) { 1015 do_cleanup_ = cleanup; 1016 } 1017 1018 void reset(int new_value) { 1019 if (auto_close_ && value_ >= 0) { 1020 close(value_); 1021 } 1022 if (do_cleanup_ && cleanup_ != nullptr) { 1023 cleanup_(); 1024 } 1025 1026 value_ = new_value; 1027 } 1028 1029 void reset(int new_value, std::function<void ()> new_cleanup) { 1030 if (auto_close_ && value_ >= 0) { 1031 close(value_); 1032 } 1033 if (do_cleanup_ && cleanup_ != nullptr) { 1034 cleanup_(); 1035 } 1036 1037 value_ = new_value; 1038 cleanup_ = new_cleanup; 1039 } 1040 1041 void DisableAutoClose() { 1042 auto_close_ = false; 1043 } 1044 1045 private: 1046 void release() { 1047 value_ = -1; 1048 do_cleanup_ = false; 1049 cleanup_ = nullptr; 1050 } 1051 int value_; 1052 std::function<void ()> cleanup_; 1053 bool do_cleanup_; 1054 bool auto_close_; 1055}; 1056 1057// (re)Creates the app image if needed. 1058Dex2oatFileWrapper maybe_open_app_image(const char* out_oat_path, bool profile_guided, 1059 bool is_public, int uid, bool is_secondary_dex) { 1060 // Use app images only if it is enabled (by a set image format) and we are compiling 1061 // profile-guided (so the app image doesn't conservatively contain all classes). 1062 // Note that we don't create an image for secondary dex files. 1063 if (is_secondary_dex || !profile_guided) { 1064 return Dex2oatFileWrapper(); 1065 } 1066 1067 const std::string image_path = create_image_filename(out_oat_path); 1068 if (image_path.empty()) { 1069 // Happens when the out_oat_path has an unknown extension. 1070 return Dex2oatFileWrapper(); 1071 } 1072 char app_image_format[kPropertyValueMax]; 1073 bool have_app_image_format = 1074 get_property("dalvik.vm.appimageformat", app_image_format, NULL) > 0; 1075 if (!have_app_image_format) { 1076 return Dex2oatFileWrapper(); 1077 } 1078 // Recreate is true since we do not want to modify a mapped image. If the app is 1079 // already running and we modify the image file, it can cause crashes (b/27493510). 1080 Dex2oatFileWrapper wrapper_fd( 1081 open_output_file(image_path.c_str(), true /*recreate*/, 0600 /*permissions*/), 1082 [image_path]() { unlink(image_path.c_str()); }); 1083 if (wrapper_fd.get() < 0) { 1084 // Could not create application image file. Go on since we can compile without it. 1085 LOG(ERROR) << "installd could not create '" << image_path 1086 << "' for image file during dexopt"; 1087 // If we have a valid image file path but no image fd, explicitly erase the image file. 1088 if (unlink(image_path.c_str()) < 0) { 1089 if (errno != ENOENT) { 1090 PLOG(ERROR) << "Couldn't unlink image file " << image_path; 1091 } 1092 } 1093 } else if (!set_permissions_and_ownership( 1094 wrapper_fd.get(), is_public, uid, image_path.c_str(), is_secondary_dex)) { 1095 ALOGE("installd cannot set owner '%s' for image during dexopt\n", image_path.c_str()); 1096 wrapper_fd.reset(-1); 1097 } 1098 1099 return wrapper_fd; 1100} 1101 1102// Creates the dexopt swap file if necessary and return its fd. 1103// Returns -1 if there's no need for a swap or in case of errors. 1104unique_fd maybe_open_dexopt_swap_file(const char* out_oat_path) { 1105 if (!ShouldUseSwapFileForDexopt()) { 1106 return invalid_unique_fd(); 1107 } 1108 // Make sure there really is enough space. 1109 char swap_file_name[PKG_PATH_MAX]; 1110 strcpy(swap_file_name, out_oat_path); 1111 if (!add_extension_to_file_name(swap_file_name, ".swap")) { 1112 return invalid_unique_fd(); 1113 } 1114 unique_fd swap_fd(open_output_file( 1115 swap_file_name, /*recreate*/true, /*permissions*/0600)); 1116 if (swap_fd.get() < 0) { 1117 // Could not create swap file. Optimistically go on and hope that we can compile 1118 // without it. 1119 ALOGE("installd could not create '%s' for swap during dexopt\n", swap_file_name); 1120 } else { 1121 // Immediately unlink. We don't really want to hit flash. 1122 if (unlink(swap_file_name) < 0) { 1123 PLOG(ERROR) << "Couldn't unlink swap file " << swap_file_name; 1124 } 1125 } 1126 return swap_fd; 1127} 1128 1129// Opens the reference profiles if needed. 1130// Note that the reference profile might not exist so it's OK if the fd will be -1. 1131Dex2oatFileWrapper maybe_open_reference_profile(const std::string& pkgname, 1132 const std::string& dex_path, bool profile_guided, bool is_public, int uid, 1133 bool is_secondary_dex) { 1134 // Public apps should not be compiled with profile information ever. Same goes for the special 1135 // package '*' used for the system server. 1136 if (!profile_guided || is_public || (pkgname[0] == '*')) { 1137 return Dex2oatFileWrapper(); 1138 } 1139 1140 // Open reference profile in read only mode as dex2oat does not get write permissions. 1141 const std::string location = is_secondary_dex ? dex_path : pkgname; 1142 unique_fd ufd = open_reference_profile(uid, location, /*read_write*/false, is_secondary_dex); 1143 const auto& cleanup = [location, is_secondary_dex]() { 1144 clear_reference_profile(location.c_str(), is_secondary_dex); 1145 }; 1146 return Dex2oatFileWrapper(ufd.release(), cleanup); 1147} 1148 1149// Opens the vdex files and assigns the input fd to in_vdex_wrapper_fd and the output fd to 1150// out_vdex_wrapper_fd. Returns true for success or false in case of errors. 1151bool open_vdex_files(const char* apk_path, const char* out_oat_path, int dexopt_needed, 1152 const char* instruction_set, bool is_public, int uid, bool is_secondary_dex, 1153 Dex2oatFileWrapper* in_vdex_wrapper_fd, 1154 Dex2oatFileWrapper* out_vdex_wrapper_fd) { 1155 CHECK(in_vdex_wrapper_fd != nullptr); 1156 CHECK(out_vdex_wrapper_fd != nullptr); 1157 // Open the existing VDEX. We do this before creating the new output VDEX, which will 1158 // unlink the old one. 1159 char in_odex_path[PKG_PATH_MAX]; 1160 int dexopt_action = abs(dexopt_needed); 1161 bool is_odex_location = dexopt_needed < 0; 1162 std::string in_vdex_path_str; 1163 if (dexopt_action != DEX2OAT_FROM_SCRATCH) { 1164 // Open the possibly existing vdex. If none exist, we pass -1 to dex2oat for input-vdex-fd. 1165 const char* path = nullptr; 1166 if (is_odex_location) { 1167 if (calculate_odex_file_path(in_odex_path, apk_path, instruction_set)) { 1168 path = in_odex_path; 1169 } else { 1170 ALOGE("installd cannot compute input vdex location for '%s'\n", apk_path); 1171 return false; 1172 } 1173 } else { 1174 path = out_oat_path; 1175 } 1176 in_vdex_path_str = create_vdex_filename(path); 1177 if (in_vdex_path_str.empty()) { 1178 ALOGE("installd cannot compute input vdex location for '%s'\n", path); 1179 return false; 1180 } 1181 if (dexopt_action == DEX2OAT_FOR_BOOT_IMAGE) { 1182 // When we dex2oat because of boot image change, we are going to update 1183 // in-place the vdex file. 1184 in_vdex_wrapper_fd->reset(open(in_vdex_path_str.c_str(), O_RDWR, 0)); 1185 } else { 1186 in_vdex_wrapper_fd->reset(open(in_vdex_path_str.c_str(), O_RDONLY, 0)); 1187 } 1188 } 1189 1190 // Infer the name of the output VDEX and create it. 1191 const std::string out_vdex_path_str = create_vdex_filename(out_oat_path); 1192 if (out_vdex_path_str.empty()) { 1193 return false; 1194 } 1195 1196 // If we are compiling because the boot image is out of date, we do not 1197 // need to recreate a vdex, and can use the same existing one. 1198 if (dexopt_action == DEX2OAT_FOR_BOOT_IMAGE && 1199 in_vdex_wrapper_fd->get() != -1 && 1200 in_vdex_path_str == out_vdex_path_str) { 1201 out_vdex_wrapper_fd->reset(in_vdex_wrapper_fd->get()); 1202 // Disable auto close for the in wrapper fd (it will be done when destructing the out 1203 // wrapper). 1204 in_vdex_wrapper_fd->DisableAutoClose(); 1205 } else { 1206 out_vdex_wrapper_fd->reset( 1207 open_output_file(out_vdex_path_str.c_str(), /*recreate*/true, /*permissions*/0644), 1208 [out_vdex_path_str]() { unlink(out_vdex_path_str.c_str()); }); 1209 if (out_vdex_wrapper_fd->get() < 0) { 1210 ALOGE("installd cannot open vdex'%s' during dexopt\n", out_vdex_path_str.c_str()); 1211 return false; 1212 } 1213 } 1214 if (!set_permissions_and_ownership(out_vdex_wrapper_fd->get(), is_public, uid, 1215 out_vdex_path_str.c_str(), is_secondary_dex)) { 1216 ALOGE("installd cannot set owner '%s' for vdex during dexopt\n", out_vdex_path_str.c_str()); 1217 return false; 1218 } 1219 1220 // If we got here we successfully opened the vdex files. 1221 return true; 1222} 1223 1224// Opens the output oat file for the given apk. 1225// If successful it stores the output path into out_oat_path and returns true. 1226Dex2oatFileWrapper open_oat_out_file(const char* apk_path, const char* oat_dir, 1227 bool is_public, int uid, const char* instruction_set, bool is_secondary_dex, 1228 char* out_oat_path) { 1229 if (!create_oat_out_path(apk_path, instruction_set, oat_dir, is_secondary_dex, out_oat_path)) { 1230 return Dex2oatFileWrapper(); 1231 } 1232 const std::string out_oat_path_str(out_oat_path); 1233 Dex2oatFileWrapper wrapper_fd( 1234 open_output_file(out_oat_path, /*recreate*/true, /*permissions*/0644), 1235 [out_oat_path_str]() { unlink(out_oat_path_str.c_str()); }); 1236 if (wrapper_fd.get() < 0) { 1237 PLOG(ERROR) << "installd cannot open output during dexopt" << out_oat_path; 1238 } else if (!set_permissions_and_ownership( 1239 wrapper_fd.get(), is_public, uid, out_oat_path, is_secondary_dex)) { 1240 ALOGE("installd cannot set owner '%s' for output during dexopt\n", out_oat_path); 1241 wrapper_fd.reset(-1); 1242 } 1243 return wrapper_fd; 1244} 1245 1246// Updates the access times of out_oat_path based on those from apk_path. 1247void update_out_oat_access_times(const char* apk_path, const char* out_oat_path) { 1248 struct stat input_stat; 1249 memset(&input_stat, 0, sizeof(input_stat)); 1250 if (stat(apk_path, &input_stat) != 0) { 1251 PLOG(ERROR) << "Could not stat " << apk_path << " during dexopt"; 1252 return; 1253 } 1254 1255 struct utimbuf ut; 1256 ut.actime = input_stat.st_atime; 1257 ut.modtime = input_stat.st_mtime; 1258 if (utime(out_oat_path, &ut) != 0) { 1259 PLOG(WARNING) << "Could not update access times for " << apk_path << " during dexopt"; 1260 } 1261} 1262 1263// Runs (execv) dexoptanalyzer on the given arguments. 1264// The analyzer will check if the dex_file needs to be (re)compiled to match the compiler_filter. 1265// If this is for a profile guided compilation, profile_was_updated will tell whether or not 1266// the profile has changed. 1267static void exec_dexoptanalyzer(const std::string& dex_file, const char* instruction_set, 1268 const char* compiler_filter, bool profile_was_updated) { 1269 static const char* DEXOPTANALYZER_BIN = "/system/bin/dexoptanalyzer"; 1270 static const unsigned int MAX_INSTRUCTION_SET_LEN = 7; 1271 1272 if (strlen(instruction_set) >= MAX_INSTRUCTION_SET_LEN) { 1273 ALOGE("Instruction set %s longer than max length of %d", 1274 instruction_set, MAX_INSTRUCTION_SET_LEN); 1275 return; 1276 } 1277 1278 char dex_file_arg[strlen("--dex-file=") + PKG_PATH_MAX]; 1279 char isa_arg[strlen("--isa=") + MAX_INSTRUCTION_SET_LEN]; 1280 char compiler_filter_arg[strlen("--compiler-filter=") + kPropertyValueMax]; 1281 const char* assume_profile_changed = "--assume-profile-changed"; 1282 1283 sprintf(dex_file_arg, "--dex-file=%s", dex_file.c_str()); 1284 sprintf(isa_arg, "--isa=%s", instruction_set); 1285 sprintf(compiler_filter_arg, "--compiler-filter=%s", compiler_filter); 1286 1287 // program name, dex file, isa, filter, the final NULL 1288 const char* argv[5 + (profile_was_updated ? 1 : 0)]; 1289 int i = 0; 1290 argv[i++] = DEXOPTANALYZER_BIN; 1291 argv[i++] = dex_file_arg; 1292 argv[i++] = isa_arg; 1293 argv[i++] = compiler_filter_arg; 1294 if (profile_was_updated) { 1295 argv[i++] = assume_profile_changed; 1296 } 1297 argv[i] = NULL; 1298 1299 execv(DEXOPTANALYZER_BIN, (char * const *)argv); 1300 ALOGE("execv(%s) failed: %s\n", DEXOPTANALYZER_BIN, strerror(errno)); 1301} 1302 1303// Prepares the oat dir for the secondary dex files. 1304static bool prepare_secondary_dex_oat_dir(const std::string& dex_path, int uid, 1305 const char* instruction_set, std::string* oat_dir_out) { 1306 unsigned long dirIndex = dex_path.rfind('/'); 1307 if (dirIndex == std::string::npos) { 1308 LOG(ERROR ) << "Unexpected dir structure for secondary dex " << dex_path; 1309 return false; 1310 } 1311 std::string dex_dir = dex_path.substr(0, dirIndex); 1312 1313 // Create oat file output directory. 1314 mode_t oat_dir_mode = S_IRWXU | S_IRWXG | S_IXOTH; 1315 if (prepare_app_cache_dir(dex_dir, "oat", oat_dir_mode, uid, uid) != 0) { 1316 LOG(ERROR) << "Could not prepare oat dir for secondary dex: " << dex_path; 1317 return false; 1318 } 1319 1320 char oat_dir[PKG_PATH_MAX]; 1321 snprintf(oat_dir, PKG_PATH_MAX, "%s/oat", dex_dir.c_str()); 1322 oat_dir_out->assign(oat_dir); 1323 1324 // Create oat/isa output directory. 1325 if (prepare_app_cache_dir(*oat_dir_out, instruction_set, oat_dir_mode, uid, uid) != 0) { 1326 LOG(ERROR) << "Could not prepare oat/isa dir for secondary dex: " << dex_path; 1327 return false; 1328 } 1329 1330 return true; 1331} 1332 1333static int constexpr DEXOPTANALYZER_BIN_EXEC_ERROR = 200; 1334 1335// Verifies the result of dexoptanalyzer executed for the apk_path. 1336// If the result is valid returns true and sets dexopt_needed_out to a valid value. 1337// Returns false for errors or unexpected result values. 1338static bool process_dexoptanalyzer_result(const std::string& dex_path, int result, 1339 int* dexopt_needed_out) { 1340 // The result values are defined in dexoptanalyzer. 1341 switch (result) { 1342 case 0: // no_dexopt_needed 1343 *dexopt_needed_out = NO_DEXOPT_NEEDED; return true; 1344 case 1: // dex2oat_from_scratch 1345 *dexopt_needed_out = DEX2OAT_FROM_SCRATCH; return true; 1346 case 5: // dex2oat_for_bootimage_odex 1347 *dexopt_needed_out = -DEX2OAT_FOR_BOOT_IMAGE; return true; 1348 case 6: // dex2oat_for_filter_odex 1349 *dexopt_needed_out = -DEX2OAT_FOR_FILTER; return true; 1350 case 7: // dex2oat_for_relocation_odex 1351 *dexopt_needed_out = -DEX2OAT_FOR_RELOCATION; return true; 1352 case 2: // dex2oat_for_bootimage_oat 1353 case 3: // dex2oat_for_filter_oat 1354 case 4: // dex2oat_for_relocation_oat 1355 LOG(ERROR) << "Dexoptnalyzer return the status of an oat file." 1356 << " Expected odex file status for secondary dex " << dex_path 1357 << " : dexoptanalyzer result=" << result; 1358 return false; 1359 default: 1360 LOG(ERROR) << "Unexpected result for dexoptanalyzer " << dex_path 1361 << " exec_dexoptanalyzer result=" << result; 1362 return false; 1363 } 1364} 1365 1366// Processes the dex_path as a secondary dex files and return true if the path dex file should 1367// be compiled. Returns false for errors (logged) or true if the secondary dex path was process 1368// successfully. 1369// When returning true, the output parameters will be: 1370// - is_public_out: whether or not the oat file should not be made public 1371// - dexopt_needed_out: valid OatFileAsssitant::DexOptNeeded 1372// - oat_dir_out: the oat dir path where the oat file should be stored 1373// - dex_path_out: the real path of the dex file 1374static bool process_secondary_dex_dexopt(const char* original_dex_path, const char* pkgname, 1375 int dexopt_flags, const char* volume_uuid, int uid, const char* instruction_set, 1376 const char* compiler_filter, bool* is_public_out, int* dexopt_needed_out, 1377 std::string* oat_dir_out, std::string* dex_path_out) { 1378 int storage_flag; 1379 1380 if ((dexopt_flags & DEXOPT_STORAGE_CE) != 0) { 1381 storage_flag = FLAG_STORAGE_CE; 1382 if ((dexopt_flags & DEXOPT_STORAGE_DE) != 0) { 1383 LOG(ERROR) << "Ambiguous secondary dex storage flag. Both, CE and DE, flags are set"; 1384 return false; 1385 } 1386 } else if ((dexopt_flags & DEXOPT_STORAGE_DE) != 0) { 1387 storage_flag = FLAG_STORAGE_DE; 1388 } else { 1389 LOG(ERROR) << "Secondary dex storage flag must be set"; 1390 return false; 1391 } 1392 1393 { 1394 // As opposed to the primary apk, secondary dex files might contain symlinks. 1395 // Resolve the path before passing it to the validate method to 1396 // make sure the verification is done on the real location. 1397 UniqueCPtr<char> dex_real_path_cstr(realpath(original_dex_path, nullptr)); 1398 if (dex_real_path_cstr == nullptr) { 1399 PLOG(ERROR) << "Could not get the real path of the secondary dex file " 1400 << original_dex_path; 1401 return false; 1402 } else { 1403 dex_path_out->assign(dex_real_path_cstr.get()); 1404 } 1405 } 1406 const std::string& dex_path = *dex_path_out; 1407 if (!validate_secondary_dex_path(pkgname, dex_path, volume_uuid, uid, storage_flag)) { 1408 LOG(ERROR) << "Could not validate secondary dex path " << dex_path; 1409 return false; 1410 } 1411 1412 // Check if the path exist. If not, there's nothing to do. 1413 struct stat dex_path_stat; 1414 if (stat(dex_path.c_str(), &dex_path_stat) != 0) { 1415 if (errno == ENOENT) { 1416 // Secondary dex files might be deleted any time by the app. 1417 // Nothing to do if that's the case 1418 ALOGV("Secondary dex does not exist %s", dex_path.c_str()); 1419 return NO_DEXOPT_NEEDED; 1420 } else { 1421 PLOG(ERROR) << "Could not access secondary dex " << dex_path; 1422 } 1423 } 1424 1425 // Check if we should make the oat file public. 1426 // Note that if the dex file is not public the compiled code cannot be made public. 1427 *is_public_out = ((dexopt_flags & DEXOPT_PUBLIC) != 0) && 1428 ((dex_path_stat.st_mode & S_IROTH) != 0); 1429 1430 // Prepare the oat directories. 1431 if (!prepare_secondary_dex_oat_dir(dex_path, uid, instruction_set, oat_dir_out)) { 1432 return false; 1433 } 1434 1435 // Analyze profiles. 1436 bool profile_was_updated = analyze_profiles(uid, dex_path, /*is_secondary_dex*/true); 1437 1438 pid_t pid = fork(); 1439 if (pid == 0) { 1440 // child -- drop privileges before continuing. 1441 drop_capabilities(uid); 1442 // Run dexoptanalyzer to get dexopt_needed code. 1443 exec_dexoptanalyzer(dex_path, instruction_set, compiler_filter, profile_was_updated); 1444 exit(DEXOPTANALYZER_BIN_EXEC_ERROR); 1445 } 1446 1447 /* parent */ 1448 1449 int result = wait_child(pid); 1450 if (!WIFEXITED(result)) { 1451 LOG(ERROR) << "dexoptanalyzer failed for path " << dex_path << ": " << result; 1452 return false; 1453 } 1454 result = WEXITSTATUS(result); 1455 bool success = process_dexoptanalyzer_result(dex_path, result, dexopt_needed_out); 1456 // Run dexopt only if needed or forced. 1457 // Note that dexoptanalyzer is executed even if force compilation is enabled. 1458 // We ignore its valid dexopNeeded result, but still check (in process_dexoptanalyzer_result) 1459 // that we only get results for odex files (apk_dir/oat/isa/code.odex) and not 1460 // for oat files from dalvik-cache. 1461 if (success && ((dexopt_flags & DEXOPT_FORCE) != 0)) { 1462 *dexopt_needed_out = DEX2OAT_FROM_SCRATCH; 1463 } 1464 1465 return success; 1466} 1467 1468int dexopt(const char* dex_path, uid_t uid, const char* pkgname, const char* instruction_set, 1469 int dexopt_needed, const char* oat_dir, int dexopt_flags, const char* compiler_filter, 1470 const char* volume_uuid, const char* shared_libraries, const char* se_info) { 1471 CHECK(pkgname != nullptr); 1472 CHECK(pkgname[0] != 0); 1473 if ((dexopt_flags & ~DEXOPT_MASK) != 0) { 1474 LOG_FATAL("dexopt flags contains unknown fields\n"); 1475 } 1476 1477 bool is_public = (dexopt_flags & DEXOPT_PUBLIC) != 0; 1478 bool vm_safe_mode = (dexopt_flags & DEXOPT_SAFEMODE) != 0; 1479 bool debuggable = (dexopt_flags & DEXOPT_DEBUGGABLE) != 0; 1480 bool boot_complete = (dexopt_flags & DEXOPT_BOOTCOMPLETE) != 0; 1481 bool profile_guided = (dexopt_flags & DEXOPT_PROFILE_GUIDED) != 0; 1482 bool is_secondary_dex = (dexopt_flags & DEXOPT_SECONDARY_DEX) != 0; 1483 1484 // Check if we're dealing with a secondary dex file and if we need to compile it. 1485 std::string oat_dir_str; 1486 std::string dex_real_path; 1487 if (is_secondary_dex) { 1488 if (process_secondary_dex_dexopt(dex_path, pkgname, dexopt_flags, volume_uuid, uid, 1489 instruction_set, compiler_filter, &is_public, &dexopt_needed, &oat_dir_str, 1490 &dex_real_path)) { 1491 oat_dir = oat_dir_str.c_str(); 1492 dex_path = dex_real_path.c_str(); 1493 if (dexopt_needed == NO_DEXOPT_NEEDED) { 1494 return 0; // Nothing to do, report success. 1495 } 1496 } else { 1497 return -1; // We had an error, logged in the process method. 1498 } 1499 } else { 1500 // Currently these flags are only use for secondary dex files. 1501 // Verify that they are not set for primary apks. 1502 CHECK((dexopt_flags & DEXOPT_STORAGE_CE) == 0); 1503 CHECK((dexopt_flags & DEXOPT_STORAGE_DE) == 0); 1504 } 1505 1506 // Open the input file. 1507 unique_fd input_fd(open(dex_path, O_RDONLY, 0)); 1508 if (input_fd.get() < 0) { 1509 ALOGE("installd cannot open '%s' for input during dexopt\n", dex_path); 1510 return -1; 1511 } 1512 1513 // Create the output OAT file. 1514 char out_oat_path[PKG_PATH_MAX]; 1515 Dex2oatFileWrapper out_oat_fd = open_oat_out_file(dex_path, oat_dir, is_public, uid, 1516 instruction_set, is_secondary_dex, out_oat_path); 1517 if (out_oat_fd.get() < 0) { 1518 return -1; 1519 } 1520 1521 // Open vdex files. 1522 Dex2oatFileWrapper in_vdex_fd; 1523 Dex2oatFileWrapper out_vdex_fd; 1524 if (!open_vdex_files(dex_path, out_oat_path, dexopt_needed, instruction_set, is_public, uid, 1525 is_secondary_dex, &in_vdex_fd, &out_vdex_fd)) { 1526 return -1; 1527 } 1528 1529 // Ensure that the oat dir and the compiler artifacts of secondary dex files have the correct 1530 // selinux context (we generate them on the fly during the dexopt invocation and they don't 1531 // fully inherit their parent context). 1532 // Note that for primary apk the oat files are created before, in a separate installd 1533 // call which also does the restorecon. TODO(calin): unify the paths. 1534 if (is_secondary_dex) { 1535 if (selinux_android_restorecon_pkgdir(oat_dir, se_info, uid, 1536 SELINUX_ANDROID_RESTORECON_RECURSE)) { 1537 LOG(ERROR) << "Failed to restorecon " << oat_dir; 1538 return -1; 1539 } 1540 } 1541 1542 // Create a swap file if necessary. 1543 unique_fd swap_fd = maybe_open_dexopt_swap_file(out_oat_path); 1544 1545 // Create the app image file if needed. 1546 Dex2oatFileWrapper image_fd = 1547 maybe_open_app_image(out_oat_path, profile_guided, is_public, uid, is_secondary_dex); 1548 1549 // Open the reference profile if needed. 1550 Dex2oatFileWrapper reference_profile_fd = maybe_open_reference_profile( 1551 pkgname, dex_path, profile_guided, is_public, uid, is_secondary_dex); 1552 1553 ALOGV("DexInv: --- BEGIN '%s' ---\n", dex_path); 1554 1555 pid_t pid = fork(); 1556 if (pid == 0) { 1557 /* child -- drop privileges before continuing */ 1558 drop_capabilities(uid); 1559 1560 SetDex2OatScheduling(boot_complete); 1561 if (flock(out_oat_fd.get(), LOCK_EX | LOCK_NB) != 0) { 1562 ALOGE("flock(%s) failed: %s\n", out_oat_path, strerror(errno)); 1563 _exit(67); 1564 } 1565 1566 run_dex2oat(input_fd.get(), 1567 out_oat_fd.get(), 1568 in_vdex_fd.get(), 1569 out_vdex_fd.get(), 1570 image_fd.get(), 1571 dex_path, 1572 out_oat_path, 1573 swap_fd.get(), 1574 instruction_set, 1575 compiler_filter, 1576 vm_safe_mode, 1577 debuggable, 1578 boot_complete, 1579 reference_profile_fd.get(), 1580 shared_libraries); 1581 _exit(68); /* only get here on exec failure */ 1582 } else { 1583 int res = wait_child(pid); 1584 if (res == 0) { 1585 ALOGV("DexInv: --- END '%s' (success) ---\n", dex_path); 1586 } else { 1587 ALOGE("DexInv: --- END '%s' --- status=0x%04x, process failed\n", dex_path, res); 1588 return res; 1589 } 1590 } 1591 1592 update_out_oat_access_times(dex_path, out_oat_path); 1593 1594 // We've been successful, don't delete output. 1595 out_oat_fd.SetCleanup(false); 1596 out_vdex_fd.SetCleanup(false); 1597 image_fd.SetCleanup(false); 1598 reference_profile_fd.SetCleanup(false); 1599 1600 return 0; 1601} 1602 1603// Try to remove the given directory. Log an error if the directory exists 1604// and is empty but could not be removed. 1605static bool rmdir_if_empty(const char* dir) { 1606 if (rmdir(dir) == 0) { 1607 return true; 1608 } 1609 if (errno == ENOENT || errno == ENOTEMPTY) { 1610 return true; 1611 } 1612 PLOG(ERROR) << "Failed to remove dir: " << dir; 1613 return false; 1614} 1615 1616// Try to unlink the given file. Log an error if the file exists and could not 1617// be unlinked. 1618static bool unlink_if_exists(const std::string& file) { 1619 if (unlink(file.c_str()) == 0) { 1620 return true; 1621 } 1622 if (errno == ENOENT) { 1623 return true; 1624 1625 } 1626 PLOG(ERROR) << "Could not unlink: " << file; 1627 return false; 1628} 1629 1630// Create the oat file structure for the secondary dex 'dex_path' and assign 1631// the individual path component to the 'out_' parameters. 1632static bool create_secondary_dex_oat_layout(const std::string& dex_path, const std::string& isa, 1633 /*out*/char* out_oat_dir, /*out*/char* out_oat_isa_dir, /*out*/char* out_oat_path) { 1634 size_t dirIndex = dex_path.rfind('/'); 1635 if (dirIndex == std::string::npos) { 1636 LOG(ERROR) << "Unexpected dir structure for dex file " << dex_path; 1637 return false; 1638 } 1639 // TODO(calin): we have similar computations in at lest 3 other places 1640 // (InstalldNativeService, otapropt and dexopt). Unify them and get rid of snprintf by 1641 // use string append. 1642 std::string apk_dir = dex_path.substr(0, dirIndex); 1643 snprintf(out_oat_dir, PKG_PATH_MAX, "%s/oat", apk_dir.c_str()); 1644 snprintf(out_oat_isa_dir, PKG_PATH_MAX, "%s/%s", out_oat_dir, isa.c_str()); 1645 1646 if (!create_oat_out_path(dex_path.c_str(), isa.c_str(), out_oat_dir, 1647 /*is_secondary_dex*/true, out_oat_path)) { 1648 LOG(ERROR) << "Could not create oat path for secondary dex " << dex_path; 1649 return false; 1650 } 1651 return true; 1652} 1653 1654// Reconcile the secondary dex 'dex_path' and its generated oat files. 1655// Return true if all the parameters are valid and the secondary dex file was 1656// processed successfully (i.e. the dex_path either exists, or if not, its corresponding 1657// oat/vdex/art files where deleted successfully). In this case, out_secondary_dex_exists 1658// will be true if the secondary dex file still exists. If the secondary dex file does not exist, 1659// the method cleans up any previously generated compiler artifacts (oat, vdex, art). 1660// Return false if there were errors during processing. In this case 1661// out_secondary_dex_exists will be set to false. 1662bool reconcile_secondary_dex_file(const std::string& dex_path, 1663 const std::string& pkgname, int uid, const std::vector<std::string>& isas, 1664 const std::unique_ptr<std::string>& volume_uuid, int storage_flag, 1665 /*out*/bool* out_secondary_dex_exists) { 1666 // Set out to false to start with, just in case we have validation errors. 1667 *out_secondary_dex_exists = false; 1668 if (isas.size() == 0) { 1669 LOG(ERROR) << "reconcile_secondary_dex_file called with empty isas vector"; 1670 return false; 1671 } 1672 1673 const char* volume_uuid_cstr = volume_uuid == nullptr ? nullptr : volume_uuid->c_str(); 1674 if (!validate_secondary_dex_path(pkgname.c_str(), dex_path.c_str(), volume_uuid_cstr, 1675 uid, storage_flag)) { 1676 LOG(ERROR) << "Could not validate secondary dex path " << dex_path; 1677 return false; 1678 } 1679 1680 if (access(dex_path.c_str(), F_OK) == 0) { 1681 // The path exists, nothing to do. The odex files (if any) will be left untouched. 1682 *out_secondary_dex_exists = true; 1683 return true; 1684 } else if (errno != ENOENT) { 1685 PLOG(ERROR) << "Failed to check access to secondary dex " << dex_path; 1686 return false; 1687 } 1688 1689 // The secondary dex does not exist anymore. Clear any generated files. 1690 char oat_path[PKG_PATH_MAX]; 1691 char oat_dir[PKG_PATH_MAX]; 1692 char oat_isa_dir[PKG_PATH_MAX]; 1693 bool result = true; 1694 for (size_t i = 0; i < isas.size(); i++) { 1695 if (!create_secondary_dex_oat_layout(dex_path, isas[i], oat_dir, oat_isa_dir, oat_path)) { 1696 LOG(ERROR) << "Could not create secondary odex layout: " << dex_path; 1697 result = false; 1698 continue; 1699 } 1700 result = unlink_if_exists(oat_path) && result; 1701 result = unlink_if_exists(create_vdex_filename(oat_path)) && result; 1702 result = unlink_if_exists(create_image_filename(oat_path)) && result; 1703 1704 // Try removing the directories as well, they might be empty. 1705 result = rmdir_if_empty(oat_isa_dir) && result; 1706 result = rmdir_if_empty(oat_dir) && result; 1707 } 1708 1709 return result; 1710} 1711 1712// Helper for move_ab, so that we can have common failure-case cleanup. 1713static bool unlink_and_rename(const char* from, const char* to) { 1714 // Check whether "from" exists, and if so whether it's regular. If it is, unlink. Otherwise, 1715 // return a failure. 1716 struct stat s; 1717 if (stat(to, &s) == 0) { 1718 if (!S_ISREG(s.st_mode)) { 1719 LOG(ERROR) << from << " is not a regular file to replace for A/B."; 1720 return false; 1721 } 1722 if (unlink(to) != 0) { 1723 LOG(ERROR) << "Could not unlink " << to << " to move A/B."; 1724 return false; 1725 } 1726 } else { 1727 // This may be a permission problem. We could investigate the error code, but we'll just 1728 // let the rename failure do the work for us. 1729 } 1730 1731 // Try to rename "to" to "from." 1732 if (rename(from, to) != 0) { 1733 PLOG(ERROR) << "Could not rename " << from << " to " << to; 1734 return false; 1735 } 1736 return true; 1737} 1738 1739// Move/rename a B artifact (from) to an A artifact (to). 1740static bool move_ab_path(const std::string& b_path, const std::string& a_path) { 1741 // Check whether B exists. 1742 { 1743 struct stat s; 1744 if (stat(b_path.c_str(), &s) != 0) { 1745 // Silently ignore for now. The service calling this isn't smart enough to understand 1746 // lack of artifacts at the moment. 1747 return false; 1748 } 1749 if (!S_ISREG(s.st_mode)) { 1750 LOG(ERROR) << "A/B artifact " << b_path << " is not a regular file."; 1751 // Try to unlink, but swallow errors. 1752 unlink(b_path.c_str()); 1753 return false; 1754 } 1755 } 1756 1757 // Rename B to A. 1758 if (!unlink_and_rename(b_path.c_str(), a_path.c_str())) { 1759 // Delete the b_path so we don't try again (or fail earlier). 1760 if (unlink(b_path.c_str()) != 0) { 1761 PLOG(ERROR) << "Could not unlink " << b_path; 1762 } 1763 1764 return false; 1765 } 1766 1767 return true; 1768} 1769 1770bool move_ab(const char* apk_path, const char* instruction_set, const char* oat_dir) { 1771 // Get the current slot suffix. No suffix, no A/B. 1772 std::string slot_suffix; 1773 { 1774 char buf[kPropertyValueMax]; 1775 if (get_property("ro.boot.slot_suffix", buf, nullptr) <= 0) { 1776 return false; 1777 } 1778 slot_suffix = buf; 1779 1780 if (!ValidateTargetSlotSuffix(slot_suffix)) { 1781 LOG(ERROR) << "Target slot suffix not legal: " << slot_suffix; 1782 return false; 1783 } 1784 } 1785 1786 // Validate other inputs. 1787 if (validate_apk_path(apk_path) != 0) { 1788 LOG(ERROR) << "Invalid apk_path: " << apk_path; 1789 return false; 1790 } 1791 if (validate_apk_path(oat_dir) != 0) { 1792 LOG(ERROR) << "Invalid oat_dir: " << oat_dir; 1793 return false; 1794 } 1795 1796 char a_path[PKG_PATH_MAX]; 1797 if (!calculate_oat_file_path(a_path, oat_dir, apk_path, instruction_set)) { 1798 return false; 1799 } 1800 const std::string a_vdex_path = create_vdex_filename(a_path); 1801 const std::string a_image_path = create_image_filename(a_path); 1802 1803 // B path = A path + slot suffix. 1804 const std::string b_path = StringPrintf("%s.%s", a_path, slot_suffix.c_str()); 1805 const std::string b_vdex_path = StringPrintf("%s.%s", a_vdex_path.c_str(), slot_suffix.c_str()); 1806 const std::string b_image_path = StringPrintf("%s.%s", 1807 a_image_path.c_str(), 1808 slot_suffix.c_str()); 1809 1810 bool success = true; 1811 if (move_ab_path(b_path, a_path)) { 1812 if (move_ab_path(b_vdex_path, a_vdex_path)) { 1813 // Note: we can live without an app image. As such, ignore failure to move the image file. 1814 // If we decide to require the app image, or the app image being moved correctly, 1815 // then change accordingly. 1816 constexpr bool kIgnoreAppImageFailure = true; 1817 1818 if (!a_image_path.empty()) { 1819 if (!move_ab_path(b_image_path, a_image_path)) { 1820 unlink(a_image_path.c_str()); 1821 if (!kIgnoreAppImageFailure) { 1822 success = false; 1823 } 1824 } 1825 } 1826 } else { 1827 // Cleanup: delete B image, ignore errors. 1828 unlink(b_image_path.c_str()); 1829 success = false; 1830 } 1831 } else { 1832 // Cleanup: delete B image, ignore errors. 1833 unlink(b_vdex_path.c_str()); 1834 unlink(b_image_path.c_str()); 1835 success = false; 1836 } 1837 return success; 1838} 1839 1840bool delete_odex(const char* apk_path, const char* instruction_set, const char* oat_dir) { 1841 // Delete the oat/odex file. 1842 char out_path[PKG_PATH_MAX]; 1843 if (!create_oat_out_path(apk_path, instruction_set, oat_dir, 1844 /*is_secondary_dex*/false, out_path)) { 1845 return false; 1846 } 1847 1848 // In case of a permission failure report the issue. Otherwise just print a warning. 1849 auto unlink_and_check = [](const char* path) -> bool { 1850 int result = unlink(path); 1851 if (result != 0) { 1852 if (errno == EACCES || errno == EPERM) { 1853 PLOG(ERROR) << "Could not unlink " << path; 1854 return false; 1855 } 1856 PLOG(WARNING) << "Could not unlink " << path; 1857 } 1858 return true; 1859 }; 1860 1861 // Delete the oat/odex file. 1862 bool return_value_oat = unlink_and_check(out_path); 1863 1864 // Derive and delete the app image. 1865 bool return_value_art = unlink_and_check(create_image_filename(out_path).c_str()); 1866 1867 // Report success. 1868 return return_value_oat && return_value_art; 1869} 1870 1871} // namespace installd 1872} // namespace android 1873