Home | History | Annotate | Download | only in installd
      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