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