Home | History | Annotate | Download | only in installd
      1 /*
      2 ** Copyright 2008, The Android Open Source Project
      3 **
      4 ** Licensed under the Apache License, Version 2.0 (the "License");
      5 ** you may not use this file except in compliance with the License.
      6 ** You may obtain a copy of the License at
      7 **
      8 **     http://www.apache.org/licenses/LICENSE-2.0
      9 **
     10 ** Unless required by applicable law or agreed to in writing, software
     11 ** distributed under the License is distributed on an "AS IS" BASIS,
     12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 ** See the License for the specific language governing permissions and
     14 ** limitations under the License.
     15 */
     16 
     17 #include "commands.h"
     18 
     19 #include <errno.h>
     20 #include <inttypes.h>
     21 #include <regex>
     22 #include <stdlib.h>
     23 #include <sys/capability.h>
     24 #include <sys/file.h>
     25 #include <sys/resource.h>
     26 #include <sys/stat.h>
     27 #include <sys/types.h>
     28 #include <sys/wait.h>
     29 #include <sys/xattr.h>
     30 #include <unistd.h>
     31 
     32 #include <android-base/logging.h>
     33 #include <android-base/stringprintf.h>
     34 #include <android-base/strings.h>
     35 #include <android-base/unique_fd.h>
     36 #include <cutils/fs.h>
     37 #include <cutils/log.h>               // TODO: Move everything to base/logging.
     38 #include <cutils/sched_policy.h>
     39 #include <diskusage/dirsize.h>
     40 #include <logwrap/logwrap.h>
     41 #include <private/android_filesystem_config.h>
     42 #include <selinux/android.h>
     43 #include <system/thread_defs.h>
     44 
     45 #include <globals.h>
     46 #include <installd_deps.h>
     47 #include <otapreopt_utils.h>
     48 #include <utils.h>
     49 
     50 #ifndef LOG_TAG
     51 #define LOG_TAG "installd"
     52 #endif
     53 
     54 using android::base::EndsWith;
     55 using android::base::StringPrintf;
     56 
     57 namespace android {
     58 namespace installd {
     59 
     60 static constexpr const char* kCpPath = "/system/bin/cp";
     61 static constexpr const char* kXattrDefault = "user.default";
     62 
     63 static constexpr const char* PKG_LIB_POSTFIX = "/lib";
     64 static constexpr const char* CACHE_DIR_POSTFIX = "/cache";
     65 static constexpr const char* CODE_CACHE_DIR_POSTFIX = "/code_cache";
     66 
     67 static constexpr const char* IDMAP_PREFIX = "/data/resource-cache/";
     68 static constexpr const char* IDMAP_SUFFIX = "@idmap";
     69 
     70 // NOTE: keep in sync with StorageManager
     71 static constexpr int FLAG_STORAGE_DE = 1 << 0;
     72 static constexpr int FLAG_STORAGE_CE = 1 << 1;
     73 
     74 // NOTE: keep in sync with Installer
     75 static constexpr int FLAG_CLEAR_CACHE_ONLY = 1 << 8;
     76 static constexpr int FLAG_CLEAR_CODE_CACHE_ONLY = 1 << 9;
     77 
     78 /* dexopt needed flags matching those in dalvik.system.DexFile */
     79 static constexpr int DEXOPT_DEX2OAT_NEEDED       = 1;
     80 static constexpr int DEXOPT_PATCHOAT_NEEDED      = 2;
     81 static constexpr int DEXOPT_SELF_PATCHOAT_NEEDED = 3;
     82 
     83 #define MIN_RESTRICTED_HOME_SDK_VERSION 24 // > M
     84 
     85 typedef int fd_t;
     86 
     87 static bool property_get_bool(const char* property_name, bool default_value = false) {
     88     char tmp_property_value[kPropertyValueMax];
     89     bool have_property = get_property(property_name, tmp_property_value, nullptr) > 0;
     90     if (!have_property) {
     91         return default_value;
     92     }
     93     return strcmp(tmp_property_value, "true") == 0;
     94 }
     95 
     96 // Keep profile paths in sync with ActivityThread.
     97 constexpr const char* PRIMARY_PROFILE_NAME = "primary.prof";
     98 static std::string create_primary_profile(const std::string& profile_dir) {
     99     return StringPrintf("%s/%s", profile_dir.c_str(), PRIMARY_PROFILE_NAME);
    100 }
    101 
    102 /**
    103  * Perform restorecon of the given path, but only perform recursive restorecon
    104  * if the label of that top-level file actually changed.  This can save us
    105  * significant time by avoiding no-op traversals of large filesystem trees.
    106  */
    107 static int restorecon_app_data_lazy(const std::string& path, const char* seinfo, uid_t uid) {
    108     int res = 0;
    109     char* before = nullptr;
    110     char* after = nullptr;
    111 
    112     // Note that SELINUX_ANDROID_RESTORECON_DATADATA flag is set by
    113     // libselinux. Not needed here.
    114 
    115     if (lgetfilecon(path.c_str(), &before) < 0) {
    116         PLOG(ERROR) << "Failed before getfilecon for " << path;
    117         goto fail;
    118     }
    119     if (selinux_android_restorecon_pkgdir(path.c_str(), seinfo, uid, 0) < 0) {
    120         PLOG(ERROR) << "Failed top-level restorecon for " << path;
    121         goto fail;
    122     }
    123     if (lgetfilecon(path.c_str(), &after) < 0) {
    124         PLOG(ERROR) << "Failed after getfilecon for " << path;
    125         goto fail;
    126     }
    127 
    128     // If the initial top-level restorecon above changed the label, then go
    129     // back and restorecon everything recursively
    130     if (strcmp(before, after)) {
    131         LOG(DEBUG) << "Detected label change from " << before << " to " << after << " at " << path
    132                 << "; running recursive restorecon";
    133         if (selinux_android_restorecon_pkgdir(path.c_str(), seinfo, uid,
    134                 SELINUX_ANDROID_RESTORECON_RECURSE) < 0) {
    135             PLOG(ERROR) << "Failed recursive restorecon for " << path;
    136             goto fail;
    137         }
    138     }
    139 
    140     goto done;
    141 fail:
    142     res = -1;
    143 done:
    144     free(before);
    145     free(after);
    146     return res;
    147 }
    148 
    149 static int restorecon_app_data_lazy(const std::string& parent, const char* name, const char* seinfo,
    150         uid_t uid) {
    151     return restorecon_app_data_lazy(StringPrintf("%s/%s", parent.c_str(), name), seinfo, uid);
    152 }
    153 
    154 static int prepare_app_dir(const std::string& path, mode_t target_mode, uid_t uid) {
    155     if (fs_prepare_dir_strict(path.c_str(), target_mode, uid, uid) != 0) {
    156         PLOG(ERROR) << "Failed to prepare " << path;
    157         return -1;
    158     }
    159     return 0;
    160 }
    161 
    162 static int prepare_app_dir(const std::string& parent, const char* name, mode_t target_mode,
    163         uid_t uid) {
    164     return prepare_app_dir(StringPrintf("%s/%s", parent.c_str(), name), target_mode, uid);
    165 }
    166 
    167 int create_app_data(const char *uuid, const char *pkgname, userid_t userid, int flags,
    168         appid_t appid, const char* seinfo, int target_sdk_version) {
    169     uid_t uid = multiuser_get_uid(userid, appid);
    170     mode_t target_mode = target_sdk_version >= MIN_RESTRICTED_HOME_SDK_VERSION ? 0700 : 0751;
    171     if (flags & FLAG_STORAGE_CE) {
    172         auto path = create_data_user_ce_package_path(uuid, userid, pkgname);
    173         if (prepare_app_dir(path, target_mode, uid) ||
    174                 prepare_app_dir(path, "cache", 0771, uid) ||
    175                 prepare_app_dir(path, "code_cache", 0771, uid)) {
    176             return -1;
    177         }
    178 
    179         // Consider restorecon over contents if label changed
    180         if (restorecon_app_data_lazy(path, seinfo, uid) ||
    181                 restorecon_app_data_lazy(path, "cache", seinfo, uid) ||
    182                 restorecon_app_data_lazy(path, "code_cache", seinfo, uid)) {
    183             return -1;
    184         }
    185 
    186         // Remember inode numbers of cache directories so that we can clear
    187         // contents while CE storage is locked
    188         if (write_path_inode(path, "cache", kXattrInodeCache) ||
    189                 write_path_inode(path, "code_cache", kXattrInodeCodeCache)) {
    190             return -1;
    191         }
    192     }
    193     if (flags & FLAG_STORAGE_DE) {
    194         auto path = create_data_user_de_package_path(uuid, userid, pkgname);
    195         if (prepare_app_dir(path, target_mode, uid)) {
    196             // TODO: include result once 25796509 is fixed
    197             return 0;
    198         }
    199 
    200         // Consider restorecon over contents if label changed
    201         if (restorecon_app_data_lazy(path, seinfo, uid)) {
    202             return -1;
    203         }
    204 
    205         if (property_get_bool("dalvik.vm.usejitprofiles")) {
    206             const std::string profile_path = create_data_user_profile_package_path(userid, pkgname);
    207             // read-write-execute only for the app user.
    208             if (fs_prepare_dir_strict(profile_path.c_str(), 0700, uid, uid) != 0) {
    209                 PLOG(ERROR) << "Failed to prepare " << profile_path;
    210                 return -1;
    211             }
    212             std::string profile_file = create_primary_profile(profile_path);
    213             // read-write only for the app user.
    214             if (fs_prepare_file_strict(profile_file.c_str(), 0600, uid, uid) != 0) {
    215                 PLOG(ERROR) << "Failed to prepare " << profile_path;
    216                 return -1;
    217             }
    218             const std::string ref_profile_path = create_data_ref_profile_package_path(pkgname);
    219             // dex2oat/profman runs under the shared app gid and it needs to read/write reference
    220             // profiles.
    221             appid_t shared_app_gid = multiuser_get_shared_app_gid(uid);
    222             if (fs_prepare_dir_strict(
    223                     ref_profile_path.c_str(), 0700, shared_app_gid, shared_app_gid) != 0) {
    224                 PLOG(ERROR) << "Failed to prepare " << ref_profile_path;
    225                 return -1;
    226             }
    227         }
    228     }
    229     return 0;
    230 }
    231 
    232 int migrate_app_data(const char *uuid, const char *pkgname, userid_t userid, int flags) {
    233     // This method only exists to upgrade system apps that have requested
    234     // forceDeviceEncrypted, so their default storage always lives in a
    235     // consistent location.  This only works on non-FBE devices, since we
    236     // never want to risk exposing data on a device with real CE/DE storage.
    237 
    238     auto ce_path = create_data_user_ce_package_path(uuid, userid, pkgname);
    239     auto de_path = create_data_user_de_package_path(uuid, userid, pkgname);
    240 
    241     // If neither directory is marked as default, assume CE is default
    242     if (getxattr(ce_path.c_str(), kXattrDefault, nullptr, 0) == -1
    243             && getxattr(de_path.c_str(), kXattrDefault, nullptr, 0) == -1) {
    244         if (setxattr(ce_path.c_str(), kXattrDefault, nullptr, 0, 0) != 0) {
    245             PLOG(ERROR) << "Failed to mark default storage " << ce_path;
    246             return -1;
    247         }
    248     }
    249 
    250     // Migrate default data location if needed
    251     auto target = (flags & FLAG_STORAGE_DE) ? de_path : ce_path;
    252     auto source = (flags & FLAG_STORAGE_DE) ? ce_path : de_path;
    253 
    254     if (getxattr(target.c_str(), kXattrDefault, nullptr, 0) == -1) {
    255         LOG(WARNING) << "Requested default storage " << target
    256                 << " is not active; migrating from " << source;
    257         if (delete_dir_contents_and_dir(target) != 0) {
    258             PLOG(ERROR) << "Failed to delete";
    259             return -1;
    260         }
    261         if (rename(source.c_str(), target.c_str()) != 0) {
    262             PLOG(ERROR) << "Failed to rename";
    263             return -1;
    264         }
    265     }
    266 
    267     return 0;
    268 }
    269 
    270 static bool clear_profile(const std::string& profile) {
    271     base::unique_fd ufd(open(profile.c_str(), O_WRONLY | O_NOFOLLOW | O_CLOEXEC));
    272     if (ufd.get() < 0) {
    273         if (errno != ENOENT) {
    274             PLOG(WARNING) << "Could not open profile " << profile;
    275             return false;
    276         } else {
    277             // Nothing to clear. That's ok.
    278             return true;
    279         }
    280     }
    281 
    282     if (flock(ufd.get(), LOCK_EX | LOCK_NB) != 0) {
    283         if (errno != EWOULDBLOCK) {
    284             PLOG(WARNING) << "Error locking profile " << profile;
    285         }
    286         // This implies that the app owning this profile is running
    287         // (and has acquired the lock).
    288         //
    289         // If we can't acquire the lock bail out since clearing is useless anyway
    290         // (the app will write again to the profile).
    291         //
    292         // Note:
    293         // This does not impact the this is not an issue for the profiling correctness.
    294         // In case this is needed because of an app upgrade, profiles will still be
    295         // eventually cleared by the app itself due to checksum mismatch.
    296         // If this is needed because profman advised, then keeping the data around
    297         // until the next run is again not an issue.
    298         //
    299         // If the app attempts to acquire a lock while we've held one here,
    300         // it will simply skip the current write cycle.
    301         return false;
    302     }
    303 
    304     bool truncated = ftruncate(ufd.get(), 0) == 0;
    305     if (!truncated) {
    306         PLOG(WARNING) << "Could not truncate " << profile;
    307     }
    308     if (flock(ufd.get(), LOCK_UN) != 0) {
    309         PLOG(WARNING) << "Error unlocking profile " << profile;
    310     }
    311     return truncated;
    312 }
    313 
    314 static bool clear_reference_profile(const char* pkgname) {
    315     std::string reference_profile_dir = create_data_ref_profile_package_path(pkgname);
    316     std::string reference_profile = create_primary_profile(reference_profile_dir);
    317     return clear_profile(reference_profile);
    318 }
    319 
    320 static bool clear_current_profile(const char* pkgname, userid_t user) {
    321     std::string profile_dir = create_data_user_profile_package_path(user, pkgname);
    322     std::string profile = create_primary_profile(profile_dir);
    323     return clear_profile(profile);
    324 }
    325 
    326 static bool clear_current_profiles(const char* pkgname) {
    327     bool success = true;
    328     std::vector<userid_t> users = get_known_users(/*volume_uuid*/ nullptr);
    329     for (auto user : users) {
    330         success &= clear_current_profile(pkgname, user);
    331     }
    332     return success;
    333 }
    334 
    335 int clear_app_profiles(const char* pkgname) {
    336     bool success = true;
    337     success &= clear_reference_profile(pkgname);
    338     success &= clear_current_profiles(pkgname);
    339     return success ? 0 : -1;
    340 }
    341 
    342 int clear_app_data(const char *uuid, const char *pkgname, userid_t userid, int flags,
    343         ino_t ce_data_inode) {
    344     int res = 0;
    345     if (flags & FLAG_STORAGE_CE) {
    346         auto path = create_data_user_ce_package_path(uuid, userid, pkgname, ce_data_inode);
    347         if (flags & FLAG_CLEAR_CACHE_ONLY) {
    348             path = read_path_inode(path, "cache", kXattrInodeCache);
    349         } else if (flags & FLAG_CLEAR_CODE_CACHE_ONLY) {
    350             path = read_path_inode(path, "code_cache", kXattrInodeCodeCache);
    351         }
    352         if (access(path.c_str(), F_OK) == 0) {
    353             res |= delete_dir_contents(path);
    354         }
    355     }
    356     if (flags & FLAG_STORAGE_DE) {
    357         std::string suffix = "";
    358         bool only_cache = false;
    359         if (flags & FLAG_CLEAR_CACHE_ONLY) {
    360             suffix = CACHE_DIR_POSTFIX;
    361             only_cache = true;
    362         } else if (flags & FLAG_CLEAR_CODE_CACHE_ONLY) {
    363             suffix = CODE_CACHE_DIR_POSTFIX;
    364             only_cache = true;
    365         }
    366 
    367         auto path = create_data_user_de_package_path(uuid, userid, pkgname) + suffix;
    368         if (access(path.c_str(), F_OK) == 0) {
    369             // TODO: include result once 25796509 is fixed
    370             delete_dir_contents(path);
    371         }
    372         if (!only_cache) {
    373             if (!clear_current_profile(pkgname, userid)) {
    374                 res |= -1;
    375             }
    376         }
    377     }
    378     return res;
    379 }
    380 
    381 static int destroy_app_reference_profile(const char *pkgname) {
    382     return delete_dir_contents_and_dir(
    383         create_data_ref_profile_package_path(pkgname),
    384         /*ignore_if_missing*/ true);
    385 }
    386 
    387 static int destroy_app_current_profiles(const char *pkgname, userid_t userid) {
    388     return delete_dir_contents_and_dir(
    389         create_data_user_profile_package_path(userid, pkgname),
    390         /*ignore_if_missing*/ true);
    391 }
    392 
    393 int destroy_app_profiles(const char *pkgname) {
    394     int result = 0;
    395     std::vector<userid_t> users = get_known_users(/*volume_uuid*/ nullptr);
    396     for (auto user : users) {
    397         result |= destroy_app_current_profiles(pkgname, user);
    398     }
    399     result |= destroy_app_reference_profile(pkgname);
    400     return result;
    401 }
    402 
    403 int destroy_app_data(const char *uuid, const char *pkgname, userid_t userid, int flags,
    404         ino_t ce_data_inode) {
    405     int res = 0;
    406     if (flags & FLAG_STORAGE_CE) {
    407         res |= delete_dir_contents_and_dir(
    408                 create_data_user_ce_package_path(uuid, userid, pkgname, ce_data_inode));
    409     }
    410     if (flags & FLAG_STORAGE_DE) {
    411         res |= delete_dir_contents_and_dir(
    412                 create_data_user_de_package_path(uuid, userid, pkgname));
    413         destroy_app_current_profiles(pkgname, userid);
    414         // TODO(calin): If the package is still installed by other users it's probably
    415         // beneficial to keep the reference profile around.
    416         // Verify if it's ok to do that.
    417         destroy_app_reference_profile(pkgname);
    418     }
    419     return res;
    420 }
    421 
    422 int move_complete_app(const char *from_uuid, const char *to_uuid, const char *package_name,
    423         const char *data_app_name, appid_t appid, const char* seinfo, int target_sdk_version) {
    424     std::vector<userid_t> users = get_known_users(from_uuid);
    425 
    426     // Copy app
    427     {
    428         auto from = create_data_app_package_path(from_uuid, data_app_name);
    429         auto to = create_data_app_package_path(to_uuid, data_app_name);
    430         auto to_parent = create_data_app_path(to_uuid);
    431 
    432         char *argv[] = {
    433             (char*) kCpPath,
    434             (char*) "-F", /* delete any existing destination file first (--remove-destination) */
    435             (char*) "-p", /* preserve timestamps, ownership, and permissions */
    436             (char*) "-R", /* recurse into subdirectories (DEST must be a directory) */
    437             (char*) "-P", /* Do not follow symlinks [default] */
    438             (char*) "-d", /* don't dereference symlinks */
    439             (char*) from.c_str(),
    440             (char*) to_parent.c_str()
    441         };
    442 
    443         LOG(DEBUG) << "Copying " << from << " to " << to;
    444         int rc = android_fork_execvp(ARRAY_SIZE(argv), argv, NULL, false, true);
    445 
    446         if (rc != 0) {
    447             LOG(ERROR) << "Failed copying " << from << " to " << to
    448                     << ": status " << rc;
    449             goto fail;
    450         }
    451 
    452         if (selinux_android_restorecon(to.c_str(), SELINUX_ANDROID_RESTORECON_RECURSE) != 0) {
    453             LOG(ERROR) << "Failed to restorecon " << to;
    454             goto fail;
    455         }
    456     }
    457 
    458     // Copy private data for all known users
    459     for (auto user : users) {
    460 
    461         // Data source may not exist for all users; that's okay
    462         auto from_ce = create_data_user_ce_package_path(from_uuid, user, package_name);
    463         if (access(from_ce.c_str(), F_OK) != 0) {
    464             LOG(INFO) << "Missing source " << from_ce;
    465             continue;
    466         }
    467 
    468         if (create_app_data(to_uuid, package_name, user, FLAG_STORAGE_CE | FLAG_STORAGE_DE,
    469                 appid, seinfo, target_sdk_version) != 0) {
    470             LOG(ERROR) << "Failed to create package target on " << to_uuid;
    471             goto fail;
    472         }
    473 
    474         char *argv[] = {
    475             (char*) kCpPath,
    476             (char*) "-F", /* delete any existing destination file first (--remove-destination) */
    477             (char*) "-p", /* preserve timestamps, ownership, and permissions */
    478             (char*) "-R", /* recurse into subdirectories (DEST must be a directory) */
    479             (char*) "-P", /* Do not follow symlinks [default] */
    480             (char*) "-d", /* don't dereference symlinks */
    481             nullptr,
    482             nullptr
    483         };
    484 
    485         {
    486             auto from = create_data_user_de_package_path(from_uuid, user, package_name);
    487             auto to = create_data_user_de_path(to_uuid, user);
    488             argv[6] = (char*) from.c_str();
    489             argv[7] = (char*) to.c_str();
    490 
    491             LOG(DEBUG) << "Copying " << from << " to " << to;
    492             int rc = android_fork_execvp(ARRAY_SIZE(argv), argv, NULL, false, true);
    493             if (rc != 0) {
    494                 LOG(ERROR) << "Failed copying " << from << " to " << to << " with status " << rc;
    495                 goto fail;
    496             }
    497         }
    498         {
    499             auto from = create_data_user_ce_package_path(from_uuid, user, package_name);
    500             auto to = create_data_user_ce_path(to_uuid, user);
    501             argv[6] = (char*) from.c_str();
    502             argv[7] = (char*) to.c_str();
    503 
    504             LOG(DEBUG) << "Copying " << from << " to " << to;
    505             int rc = android_fork_execvp(ARRAY_SIZE(argv), argv, NULL, false, true);
    506             if (rc != 0) {
    507                 LOG(ERROR) << "Failed copying " << from << " to " << to << " with status " << rc;
    508                 goto fail;
    509             }
    510         }
    511 
    512         if (restorecon_app_data(to_uuid, package_name, user, FLAG_STORAGE_CE | FLAG_STORAGE_DE,
    513                 appid, seinfo) != 0) {
    514             LOG(ERROR) << "Failed to restorecon";
    515             goto fail;
    516         }
    517     }
    518 
    519     // We let the framework scan the new location and persist that before
    520     // deleting the data in the old location; this ordering ensures that
    521     // we can recover from things like battery pulls.
    522     return 0;
    523 
    524 fail:
    525     // Nuke everything we might have already copied
    526     {
    527         auto to = create_data_app_package_path(to_uuid, data_app_name);
    528         if (delete_dir_contents(to.c_str(), 1, NULL) != 0) {
    529             LOG(WARNING) << "Failed to rollback " << to;
    530         }
    531     }
    532     for (auto user : users) {
    533         {
    534             auto to = create_data_user_de_package_path(to_uuid, user, package_name);
    535             if (delete_dir_contents(to.c_str(), 1, NULL) != 0) {
    536                 LOG(WARNING) << "Failed to rollback " << to;
    537             }
    538         }
    539         {
    540             auto to = create_data_user_ce_package_path(to_uuid, user, package_name);
    541             if (delete_dir_contents(to.c_str(), 1, NULL) != 0) {
    542                 LOG(WARNING) << "Failed to rollback " << to;
    543             }
    544         }
    545     }
    546     return -1;
    547 }
    548 
    549 int create_user_data(const char *uuid, userid_t userid, int user_serial ATTRIBUTE_UNUSED,
    550         int flags) {
    551     if (flags & FLAG_STORAGE_DE) {
    552         if (uuid == nullptr) {
    553             return ensure_config_user_dirs(userid);
    554         }
    555     }
    556     return 0;
    557 }
    558 
    559 int destroy_user_data(const char *uuid, userid_t userid, int flags) {
    560     int res = 0;
    561     if (flags & FLAG_STORAGE_DE) {
    562         res |= delete_dir_contents_and_dir(create_data_user_de_path(uuid, userid), true);
    563         if (uuid == nullptr) {
    564             res |= delete_dir_contents_and_dir(create_data_misc_legacy_path(userid), true);
    565             res |= delete_dir_contents_and_dir(create_data_user_profiles_path(userid), true);
    566         }
    567     }
    568     if (flags & FLAG_STORAGE_CE) {
    569         res |= delete_dir_contents_and_dir(create_data_user_ce_path(uuid, userid), true);
    570         res |= delete_dir_contents_and_dir(create_data_media_path(uuid, userid), true);
    571     }
    572     return res;
    573 }
    574 
    575 /* Try to ensure free_size bytes of storage are available.
    576  * Returns 0 on success.
    577  * This is rather simple-minded because doing a full LRU would
    578  * be potentially memory-intensive, and without atime it would
    579  * also require that apps constantly modify file metadata even
    580  * when just reading from the cache, which is pretty awful.
    581  */
    582 int free_cache(const char *uuid, int64_t free_size) {
    583     cache_t* cache;
    584     int64_t avail;
    585 
    586     auto data_path = create_data_path(uuid);
    587 
    588     avail = data_disk_free(data_path);
    589     if (avail < 0) return -1;
    590 
    591     ALOGI("free_cache(%" PRId64 ") avail %" PRId64 "\n", free_size, avail);
    592     if (avail >= free_size) return 0;
    593 
    594     cache = start_cache_collection();
    595 
    596     auto users = get_known_users(uuid);
    597     for (auto user : users) {
    598         add_cache_files(cache, create_data_user_ce_path(uuid, user));
    599         add_cache_files(cache, create_data_user_de_path(uuid, user));
    600         add_cache_files(cache,
    601                 StringPrintf("%s/Android/data", create_data_media_path(uuid, user).c_str()));
    602     }
    603 
    604     clear_cache_files(data_path, cache, free_size);
    605     finish_cache_collection(cache);
    606 
    607     return data_disk_free(data_path) >= free_size ? 0 : -1;
    608 }
    609 
    610 int rm_dex(const char *path, const char *instruction_set)
    611 {
    612     char dex_path[PKG_PATH_MAX];
    613 
    614     if (validate_apk_path(path) && validate_system_app_path(path)) {
    615         ALOGE("invalid apk path '%s' (bad prefix)\n", path);
    616         return -1;
    617     }
    618 
    619     if (!create_cache_path(dex_path, path, instruction_set)) return -1;
    620 
    621     ALOGV("unlink %s\n", dex_path);
    622     if (unlink(dex_path) < 0) {
    623         if (errno != ENOENT) {
    624             ALOGE("Couldn't unlink %s: %s\n", dex_path, strerror(errno));
    625         }
    626         return -1;
    627     } else {
    628         return 0;
    629     }
    630 }
    631 
    632 static void add_app_data_size(std::string& path, int64_t *codesize, int64_t *datasize,
    633         int64_t *cachesize) {
    634     DIR *d;
    635     int dfd;
    636     struct dirent *de;
    637     struct stat s;
    638 
    639     d = opendir(path.c_str());
    640     if (d == nullptr) {
    641         PLOG(WARNING) << "Failed to open " << path;
    642         return;
    643     }
    644     dfd = dirfd(d);
    645     while ((de = readdir(d))) {
    646         const char *name = de->d_name;
    647 
    648         int64_t statsize = 0;
    649         if (fstatat(dfd, name, &s, AT_SYMLINK_NOFOLLOW) == 0) {
    650             statsize = stat_size(&s);
    651         }
    652 
    653         if (de->d_type == DT_DIR) {
    654             int subfd;
    655             int64_t dirsize = 0;
    656             /* always skip "." and ".." */
    657             if (name[0] == '.') {
    658                 if (name[1] == 0) continue;
    659                 if ((name[1] == '.') && (name[2] == 0)) continue;
    660             }
    661             subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY);
    662             if (subfd >= 0) {
    663                 dirsize = calculate_dir_size(subfd);
    664                 close(subfd);
    665             }
    666             // TODO: check xattrs!
    667             if (!strcmp(name, "cache") || !strcmp(name, "code_cache")) {
    668                 *datasize += statsize;
    669                 *cachesize += dirsize;
    670             } else {
    671                 *datasize += dirsize + statsize;
    672             }
    673         } else if (de->d_type == DT_LNK && !strcmp(name, "lib")) {
    674             *codesize += statsize;
    675         } else {
    676             *datasize += statsize;
    677         }
    678     }
    679     closedir(d);
    680 }
    681 
    682 int get_app_size(const char *uuid, const char *pkgname, int userid, int flags, ino_t ce_data_inode,
    683         const char *code_path, int64_t *codesize, int64_t *datasize, int64_t *cachesize,
    684         int64_t* asecsize) {
    685     DIR *d;
    686     int dfd;
    687 
    688     d = opendir(code_path);
    689     if (d != nullptr) {
    690         dfd = dirfd(d);
    691         *codesize += calculate_dir_size(dfd);
    692         closedir(d);
    693     }
    694 
    695     if (flags & FLAG_STORAGE_CE) {
    696         auto path = create_data_user_ce_package_path(uuid, userid, pkgname, ce_data_inode);
    697         add_app_data_size(path, codesize, datasize, cachesize);
    698     }
    699     if (flags & FLAG_STORAGE_DE) {
    700         auto path = create_data_user_de_package_path(uuid, userid, pkgname);
    701         add_app_data_size(path, codesize, datasize, cachesize);
    702     }
    703 
    704     *asecsize = 0;
    705 
    706     return 0;
    707 }
    708 
    709 int get_app_data_inode(const char *uuid, const char *pkgname, int userid, int flags, ino_t *inode) {
    710     if (flags & FLAG_STORAGE_CE) {
    711         auto path = create_data_user_ce_package_path(uuid, userid, pkgname);
    712         return get_path_inode(path, inode);
    713     }
    714     return -1;
    715 }
    716 
    717 static int split_count(const char *str)
    718 {
    719   char *ctx;
    720   int count = 0;
    721   char buf[kPropertyValueMax];
    722 
    723   strncpy(buf, str, sizeof(buf));
    724   char *pBuf = buf;
    725 
    726   while(strtok_r(pBuf, " ", &ctx) != NULL) {
    727     count++;
    728     pBuf = NULL;
    729   }
    730 
    731   return count;
    732 }
    733 
    734 static int split(char *buf, const char **argv)
    735 {
    736   char *ctx;
    737   int count = 0;
    738   char *tok;
    739   char *pBuf = buf;
    740 
    741   while((tok = strtok_r(pBuf, " ", &ctx)) != NULL) {
    742     argv[count++] = tok;
    743     pBuf = NULL;
    744   }
    745 
    746   return count;
    747 }
    748 
    749 static void run_patchoat(int input_fd, int oat_fd, const char* input_file_name,
    750     const char* output_file_name, const char *pkgname ATTRIBUTE_UNUSED, const char *instruction_set)
    751 {
    752     static const int MAX_INT_LEN = 12;      // '-'+10dig+'\0' -OR- 0x+8dig
    753     static const unsigned int MAX_INSTRUCTION_SET_LEN = 7;
    754 
    755     static const char* PATCHOAT_BIN = "/system/bin/patchoat";
    756     if (strlen(instruction_set) >= MAX_INSTRUCTION_SET_LEN) {
    757         ALOGE("Instruction set %s longer than max length of %d",
    758               instruction_set, MAX_INSTRUCTION_SET_LEN);
    759         return;
    760     }
    761 
    762     /* input_file_name/input_fd should be the .odex/.oat file that is precompiled. I think*/
    763     char instruction_set_arg[strlen("--instruction-set=") + MAX_INSTRUCTION_SET_LEN];
    764     char output_oat_fd_arg[strlen("--output-oat-fd=") + MAX_INT_LEN];
    765     char input_oat_fd_arg[strlen("--input-oat-fd=") + MAX_INT_LEN];
    766     const char* patched_image_location_arg = "--patched-image-location=/system/framework/boot.art";
    767     // The caller has already gotten all the locks we need.
    768     const char* no_lock_arg = "--no-lock-output";
    769     sprintf(instruction_set_arg, "--instruction-set=%s", instruction_set);
    770     sprintf(output_oat_fd_arg, "--output-oat-fd=%d", oat_fd);
    771     sprintf(input_oat_fd_arg, "--input-oat-fd=%d", input_fd);
    772     ALOGV("Running %s isa=%s in-fd=%d (%s) out-fd=%d (%s)\n",
    773           PATCHOAT_BIN, instruction_set, input_fd, input_file_name, oat_fd, output_file_name);
    774 
    775     /* patchoat, patched-image-location, no-lock, isa, input-fd, output-fd */
    776     char* argv[7];
    777     argv[0] = (char*) PATCHOAT_BIN;
    778     argv[1] = (char*) patched_image_location_arg;
    779     argv[2] = (char*) no_lock_arg;
    780     argv[3] = instruction_set_arg;
    781     argv[4] = output_oat_fd_arg;
    782     argv[5] = input_oat_fd_arg;
    783     argv[6] = NULL;
    784 
    785     execv(PATCHOAT_BIN, (char* const *)argv);
    786     ALOGE("execv(%s) failed: %s\n", PATCHOAT_BIN, strerror(errno));
    787 }
    788 
    789 static void run_dex2oat(int zip_fd, int oat_fd, int image_fd, const char* input_file_name,
    790         const char* output_file_name, int swap_fd, const char *instruction_set,
    791         const char* compiler_filter, bool vm_safe_mode, bool debuggable, bool post_bootcomplete,
    792         int profile_fd, const char* shared_libraries) {
    793     static const unsigned int MAX_INSTRUCTION_SET_LEN = 7;
    794 
    795     if (strlen(instruction_set) >= MAX_INSTRUCTION_SET_LEN) {
    796         ALOGE("Instruction set %s longer than max length of %d",
    797               instruction_set, MAX_INSTRUCTION_SET_LEN);
    798         return;
    799     }
    800 
    801     char dex2oat_Xms_flag[kPropertyValueMax];
    802     bool have_dex2oat_Xms_flag = get_property("dalvik.vm.dex2oat-Xms", dex2oat_Xms_flag, NULL) > 0;
    803 
    804     char dex2oat_Xmx_flag[kPropertyValueMax];
    805     bool have_dex2oat_Xmx_flag = get_property("dalvik.vm.dex2oat-Xmx", dex2oat_Xmx_flag, NULL) > 0;
    806 
    807     char dex2oat_threads_buf[kPropertyValueMax];
    808     bool have_dex2oat_threads_flag = get_property(post_bootcomplete
    809                                                       ? "dalvik.vm.dex2oat-threads"
    810                                                       : "dalvik.vm.boot-dex2oat-threads",
    811                                                   dex2oat_threads_buf,
    812                                                   NULL) > 0;
    813     char dex2oat_threads_arg[kPropertyValueMax + 2];
    814     if (have_dex2oat_threads_flag) {
    815         sprintf(dex2oat_threads_arg, "-j%s", dex2oat_threads_buf);
    816     }
    817 
    818     char dex2oat_isa_features_key[kPropertyKeyMax];
    819     sprintf(dex2oat_isa_features_key, "dalvik.vm.isa.%s.features", instruction_set);
    820     char dex2oat_isa_features[kPropertyValueMax];
    821     bool have_dex2oat_isa_features = get_property(dex2oat_isa_features_key,
    822                                                   dex2oat_isa_features, NULL) > 0;
    823 
    824     char dex2oat_isa_variant_key[kPropertyKeyMax];
    825     sprintf(dex2oat_isa_variant_key, "dalvik.vm.isa.%s.variant", instruction_set);
    826     char dex2oat_isa_variant[kPropertyValueMax];
    827     bool have_dex2oat_isa_variant = get_property(dex2oat_isa_variant_key,
    828                                                  dex2oat_isa_variant, NULL) > 0;
    829 
    830     const char *dex2oat_norelocation = "-Xnorelocate";
    831     bool have_dex2oat_relocation_skip_flag = false;
    832 
    833     char dex2oat_flags[kPropertyValueMax];
    834     int dex2oat_flags_count = get_property("dalvik.vm.dex2oat-flags",
    835                                  dex2oat_flags, NULL) <= 0 ? 0 : split_count(dex2oat_flags);
    836     ALOGV("dalvik.vm.dex2oat-flags=%s\n", dex2oat_flags);
    837 
    838     // If we booting without the real /data, don't spend time compiling.
    839     char vold_decrypt[kPropertyValueMax];
    840     bool have_vold_decrypt = get_property("vold.decrypt", vold_decrypt, "") > 0;
    841     bool skip_compilation = (have_vold_decrypt &&
    842                              (strcmp(vold_decrypt, "trigger_restart_min_framework") == 0 ||
    843                              (strcmp(vold_decrypt, "1") == 0)));
    844 
    845     bool generate_debug_info = property_get_bool("debug.generate-debug-info");
    846 
    847     char app_image_format[kPropertyValueMax];
    848     char image_format_arg[strlen("--image-format=") + kPropertyValueMax];
    849     bool have_app_image_format =
    850             image_fd >= 0 && get_property("dalvik.vm.appimageformat", app_image_format, NULL) > 0;
    851     if (have_app_image_format) {
    852         sprintf(image_format_arg, "--image-format=%s", app_image_format);
    853     }
    854 
    855     char dex2oat_large_app_threshold[kPropertyValueMax];
    856     bool have_dex2oat_large_app_threshold =
    857             get_property("dalvik.vm.dex2oat-very-large", dex2oat_large_app_threshold, NULL) > 0;
    858     char dex2oat_large_app_threshold_arg[strlen("--very-large-app-threshold=") + kPropertyValueMax];
    859     if (have_dex2oat_large_app_threshold) {
    860         sprintf(dex2oat_large_app_threshold_arg,
    861                 "--very-large-app-threshold=%s",
    862                 dex2oat_large_app_threshold);
    863     }
    864 
    865     static const char* DEX2OAT_BIN = "/system/bin/dex2oat";
    866 
    867     static const char* RUNTIME_ARG = "--runtime-arg";
    868 
    869     static const int MAX_INT_LEN = 12;      // '-'+10dig+'\0' -OR- 0x+8dig
    870 
    871     char zip_fd_arg[strlen("--zip-fd=") + MAX_INT_LEN];
    872     char zip_location_arg[strlen("--zip-location=") + PKG_PATH_MAX];
    873     char oat_fd_arg[strlen("--oat-fd=") + MAX_INT_LEN];
    874     char oat_location_arg[strlen("--oat-location=") + PKG_PATH_MAX];
    875     char instruction_set_arg[strlen("--instruction-set=") + MAX_INSTRUCTION_SET_LEN];
    876     char instruction_set_variant_arg[strlen("--instruction-set-variant=") + kPropertyValueMax];
    877     char instruction_set_features_arg[strlen("--instruction-set-features=") + kPropertyValueMax];
    878     char dex2oat_Xms_arg[strlen("-Xms") + kPropertyValueMax];
    879     char dex2oat_Xmx_arg[strlen("-Xmx") + kPropertyValueMax];
    880     char dex2oat_compiler_filter_arg[strlen("--compiler-filter=") + kPropertyValueMax];
    881     bool have_dex2oat_swap_fd = false;
    882     char dex2oat_swap_fd[strlen("--swap-fd=") + MAX_INT_LEN];
    883     bool have_dex2oat_image_fd = false;
    884     char dex2oat_image_fd[strlen("--app-image-fd=") + MAX_INT_LEN];
    885 
    886     sprintf(zip_fd_arg, "--zip-fd=%d", zip_fd);
    887     sprintf(zip_location_arg, "--zip-location=%s", input_file_name);
    888     sprintf(oat_fd_arg, "--oat-fd=%d", oat_fd);
    889     sprintf(oat_location_arg, "--oat-location=%s", output_file_name);
    890     sprintf(instruction_set_arg, "--instruction-set=%s", instruction_set);
    891     sprintf(instruction_set_variant_arg, "--instruction-set-variant=%s", dex2oat_isa_variant);
    892     sprintf(instruction_set_features_arg, "--instruction-set-features=%s", dex2oat_isa_features);
    893     if (swap_fd >= 0) {
    894         have_dex2oat_swap_fd = true;
    895         sprintf(dex2oat_swap_fd, "--swap-fd=%d", swap_fd);
    896     }
    897     if (image_fd >= 0) {
    898         have_dex2oat_image_fd = true;
    899         sprintf(dex2oat_image_fd, "--app-image-fd=%d", image_fd);
    900     }
    901 
    902     if (have_dex2oat_Xms_flag) {
    903         sprintf(dex2oat_Xms_arg, "-Xms%s", dex2oat_Xms_flag);
    904     }
    905     if (have_dex2oat_Xmx_flag) {
    906         sprintf(dex2oat_Xmx_arg, "-Xmx%s", dex2oat_Xmx_flag);
    907     }
    908 
    909     // Compute compiler filter.
    910 
    911     bool have_dex2oat_compiler_filter_flag;
    912     if (skip_compilation) {
    913         strcpy(dex2oat_compiler_filter_arg, "--compiler-filter=verify-none");
    914         have_dex2oat_compiler_filter_flag = true;
    915         have_dex2oat_relocation_skip_flag = true;
    916     } else if (vm_safe_mode) {
    917         strcpy(dex2oat_compiler_filter_arg, "--compiler-filter=interpret-only");
    918         have_dex2oat_compiler_filter_flag = true;
    919     } else if (compiler_filter != nullptr &&
    920             strlen(compiler_filter) + strlen("--compiler-filter=") <
    921                     arraysize(dex2oat_compiler_filter_arg)) {
    922         sprintf(dex2oat_compiler_filter_arg, "--compiler-filter=%s", compiler_filter);
    923         have_dex2oat_compiler_filter_flag = true;
    924     } else {
    925         char dex2oat_compiler_filter_flag[kPropertyValueMax];
    926         have_dex2oat_compiler_filter_flag = get_property("dalvik.vm.dex2oat-filter",
    927                                                          dex2oat_compiler_filter_flag, NULL) > 0;
    928         if (have_dex2oat_compiler_filter_flag) {
    929             sprintf(dex2oat_compiler_filter_arg,
    930                     "--compiler-filter=%s",
    931                     dex2oat_compiler_filter_flag);
    932         }
    933     }
    934 
    935     // Check whether all apps should be compiled debuggable.
    936     if (!debuggable) {
    937         char prop_buf[kPropertyValueMax];
    938         debuggable =
    939                 (get_property("dalvik.vm.always_debuggable", prop_buf, "0") > 0) &&
    940                 (prop_buf[0] == '1');
    941     }
    942     char profile_arg[strlen("--profile-file-fd=") + MAX_INT_LEN];
    943     if (profile_fd != -1) {
    944         sprintf(profile_arg, "--profile-file-fd=%d", profile_fd);
    945     }
    946 
    947 
    948     ALOGV("Running %s in=%s out=%s\n", DEX2OAT_BIN, input_file_name, output_file_name);
    949 
    950     const char* argv[7  // program name, mandatory arguments and the final NULL
    951                      + (have_dex2oat_isa_variant ? 1 : 0)
    952                      + (have_dex2oat_isa_features ? 1 : 0)
    953                      + (have_dex2oat_Xms_flag ? 2 : 0)
    954                      + (have_dex2oat_Xmx_flag ? 2 : 0)
    955                      + (have_dex2oat_compiler_filter_flag ? 1 : 0)
    956                      + (have_dex2oat_threads_flag ? 1 : 0)
    957                      + (have_dex2oat_swap_fd ? 1 : 0)
    958                      + (have_dex2oat_image_fd ? 1 : 0)
    959                      + (have_dex2oat_relocation_skip_flag ? 2 : 0)
    960                      + (generate_debug_info ? 1 : 0)
    961                      + (debuggable ? 1 : 0)
    962                      + (have_app_image_format ? 1 : 0)
    963                      + dex2oat_flags_count
    964                      + (profile_fd == -1 ? 0 : 1)
    965                      + (shared_libraries != nullptr ? 4 : 0)
    966                      + (have_dex2oat_large_app_threshold ? 1 : 0)];
    967     int i = 0;
    968     argv[i++] = DEX2OAT_BIN;
    969     argv[i++] = zip_fd_arg;
    970     argv[i++] = zip_location_arg;
    971     argv[i++] = oat_fd_arg;
    972     argv[i++] = oat_location_arg;
    973     argv[i++] = instruction_set_arg;
    974     if (have_dex2oat_isa_variant) {
    975         argv[i++] = instruction_set_variant_arg;
    976     }
    977     if (have_dex2oat_isa_features) {
    978         argv[i++] = instruction_set_features_arg;
    979     }
    980     if (have_dex2oat_Xms_flag) {
    981         argv[i++] = RUNTIME_ARG;
    982         argv[i++] = dex2oat_Xms_arg;
    983     }
    984     if (have_dex2oat_Xmx_flag) {
    985         argv[i++] = RUNTIME_ARG;
    986         argv[i++] = dex2oat_Xmx_arg;
    987     }
    988     if (have_dex2oat_compiler_filter_flag) {
    989         argv[i++] = dex2oat_compiler_filter_arg;
    990     }
    991     if (have_dex2oat_threads_flag) {
    992         argv[i++] = dex2oat_threads_arg;
    993     }
    994     if (have_dex2oat_swap_fd) {
    995         argv[i++] = dex2oat_swap_fd;
    996     }
    997     if (have_dex2oat_image_fd) {
    998         argv[i++] = dex2oat_image_fd;
    999     }
   1000     if (generate_debug_info) {
   1001         argv[i++] = "--generate-debug-info";
   1002     }
   1003     if (debuggable) {
   1004         argv[i++] = "--debuggable";
   1005     }
   1006     if (have_app_image_format) {
   1007         argv[i++] = image_format_arg;
   1008     }
   1009     if (have_dex2oat_large_app_threshold) {
   1010         argv[i++] = dex2oat_large_app_threshold_arg;
   1011     }
   1012     if (dex2oat_flags_count) {
   1013         i += split(dex2oat_flags, argv + i);
   1014     }
   1015     if (have_dex2oat_relocation_skip_flag) {
   1016         argv[i++] = RUNTIME_ARG;
   1017         argv[i++] = dex2oat_norelocation;
   1018     }
   1019     if (profile_fd != -1) {
   1020         argv[i++] = profile_arg;
   1021     }
   1022     if (shared_libraries != nullptr) {
   1023         argv[i++] = RUNTIME_ARG;
   1024         argv[i++] = "-classpath";
   1025         argv[i++] = RUNTIME_ARG;
   1026         argv[i++] = shared_libraries;
   1027     }
   1028     // Do not add after dex2oat_flags, they should override others for debugging.
   1029     argv[i] = NULL;
   1030 
   1031     execv(DEX2OAT_BIN, (char * const *)argv);
   1032     ALOGE("execv(%s) failed: %s\n", DEX2OAT_BIN, strerror(errno));
   1033 }
   1034 
   1035 /*
   1036  * Whether dexopt should use a swap file when compiling an APK.
   1037  *
   1038  * If kAlwaysProvideSwapFile, do this on all devices (dex2oat will make a more informed decision
   1039  * itself, anyways).
   1040  *
   1041  * Otherwise, read "dalvik.vm.dex2oat-swap". If the property exists, return whether it is "true".
   1042  *
   1043  * Otherwise, return true if this is a low-mem device.
   1044  *
   1045  * Otherwise, return default value.
   1046  */
   1047 static bool kAlwaysProvideSwapFile = false;
   1048 static bool kDefaultProvideSwapFile = true;
   1049 
   1050 static bool ShouldUseSwapFileForDexopt() {
   1051     if (kAlwaysProvideSwapFile) {
   1052         return true;
   1053     }
   1054 
   1055     // Check the "override" property. If it exists, return value == "true".
   1056     char dex2oat_prop_buf[kPropertyValueMax];
   1057     if (get_property("dalvik.vm.dex2oat-swap", dex2oat_prop_buf, "") > 0) {
   1058         if (strcmp(dex2oat_prop_buf, "true") == 0) {
   1059             return true;
   1060         } else {
   1061             return false;
   1062         }
   1063     }
   1064 
   1065     // Shortcut for default value. This is an implementation optimization for the process sketched
   1066     // above. If the default value is true, we can avoid to check whether this is a low-mem device,
   1067     // as low-mem is never returning false. The compiler will optimize this away if it can.
   1068     if (kDefaultProvideSwapFile) {
   1069         return true;
   1070     }
   1071 
   1072     bool is_low_mem = property_get_bool("ro.config.low_ram");
   1073     if (is_low_mem) {
   1074         return true;
   1075     }
   1076 
   1077     // Default value must be false here.
   1078     return kDefaultProvideSwapFile;
   1079 }
   1080 
   1081 static void SetDex2OatAndPatchOatScheduling(bool set_to_bg) {
   1082     if (set_to_bg) {
   1083         if (set_sched_policy(0, SP_BACKGROUND) < 0) {
   1084             ALOGE("set_sched_policy failed: %s\n", strerror(errno));
   1085             exit(70);
   1086         }
   1087         if (setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_BACKGROUND) < 0) {
   1088             ALOGE("setpriority failed: %s\n", strerror(errno));
   1089             exit(71);
   1090         }
   1091     }
   1092 }
   1093 
   1094 static void close_all_fds(const std::vector<fd_t>& fds, const char* description) {
   1095     for (size_t i = 0; i < fds.size(); i++) {
   1096         if (close(fds[i]) != 0) {
   1097             PLOG(WARNING) << "Failed to close fd for " << description << " at index " << i;
   1098         }
   1099     }
   1100 }
   1101 
   1102 static fd_t open_profile_dir(const std::string& profile_dir) {
   1103     fd_t profile_dir_fd = TEMP_FAILURE_RETRY(open(profile_dir.c_str(),
   1104             O_PATH | O_CLOEXEC | O_DIRECTORY | O_NOFOLLOW));
   1105     if (profile_dir_fd < 0) {
   1106         // In a multi-user environment, these directories can be created at
   1107         // different points and it's possible we'll attempt to open a profile
   1108         // dir before it exists.
   1109         if (errno != ENOENT) {
   1110             PLOG(ERROR) << "Failed to open profile_dir: " << profile_dir;
   1111         }
   1112     }
   1113     return profile_dir_fd;
   1114 }
   1115 
   1116 static fd_t open_primary_profile_file_from_dir(const std::string& profile_dir, mode_t open_mode) {
   1117     fd_t profile_dir_fd  = open_profile_dir(profile_dir);
   1118     if (profile_dir_fd < 0) {
   1119         return -1;
   1120     }
   1121 
   1122     fd_t profile_fd = -1;
   1123     std::string profile_file = create_primary_profile(profile_dir);
   1124 
   1125     profile_fd = TEMP_FAILURE_RETRY(open(profile_file.c_str(), open_mode | O_NOFOLLOW));
   1126     if (profile_fd == -1) {
   1127         // It's not an error if the profile file does not exist.
   1128         if (errno != ENOENT) {
   1129             PLOG(ERROR) << "Failed to lstat profile_dir: " << profile_dir;
   1130         }
   1131     }
   1132     // TODO(calin): use AutoCloseFD instead of closing the fd manually.
   1133     if (close(profile_dir_fd) != 0) {
   1134         PLOG(WARNING) << "Could not close profile dir " << profile_dir;
   1135     }
   1136     return profile_fd;
   1137 }
   1138 
   1139 static fd_t open_primary_profile_file(userid_t user, const char* pkgname) {
   1140     std::string profile_dir = create_data_user_profile_package_path(user, pkgname);
   1141     return open_primary_profile_file_from_dir(profile_dir, O_RDONLY);
   1142 }
   1143 
   1144 static fd_t open_reference_profile(uid_t uid, const char* pkgname, bool read_write) {
   1145     std::string reference_profile_dir = create_data_ref_profile_package_path(pkgname);
   1146     int flags = read_write ? O_RDWR | O_CREAT : O_RDONLY;
   1147     fd_t fd = open_primary_profile_file_from_dir(reference_profile_dir, flags);
   1148     if (fd < 0) {
   1149         return -1;
   1150     }
   1151     if (read_write) {
   1152         // Fix the owner.
   1153         if (fchown(fd, uid, uid) < 0) {
   1154             close(fd);
   1155             return -1;
   1156         }
   1157     }
   1158     return fd;
   1159 }
   1160 
   1161 static void open_profile_files(uid_t uid, const char* pkgname,
   1162             /*out*/ std::vector<fd_t>* profiles_fd, /*out*/ fd_t* reference_profile_fd) {
   1163     // Open the reference profile in read-write mode as profman might need to save the merge.
   1164     *reference_profile_fd = open_reference_profile(uid, pkgname, /*read_write*/ true);
   1165     if (*reference_profile_fd < 0) {
   1166         // We can't access the reference profile file.
   1167         return;
   1168     }
   1169 
   1170     std::vector<userid_t> users = get_known_users(/*volume_uuid*/ nullptr);
   1171     for (auto user : users) {
   1172         fd_t profile_fd = open_primary_profile_file(user, pkgname);
   1173         // Add to the lists only if both fds are valid.
   1174         if (profile_fd >= 0) {
   1175             profiles_fd->push_back(profile_fd);
   1176         }
   1177     }
   1178 }
   1179 
   1180 static void drop_capabilities(uid_t uid) {
   1181     if (setgid(uid) != 0) {
   1182         ALOGE("setgid(%d) failed in installd during dexopt\n", uid);
   1183         exit(64);
   1184     }
   1185     if (setuid(uid) != 0) {
   1186         ALOGE("setuid(%d) failed in installd during dexopt\n", uid);
   1187         exit(65);
   1188     }
   1189     // drop capabilities
   1190     struct __user_cap_header_struct capheader;
   1191     struct __user_cap_data_struct capdata[2];
   1192     memset(&capheader, 0, sizeof(capheader));
   1193     memset(&capdata, 0, sizeof(capdata));
   1194     capheader.version = _LINUX_CAPABILITY_VERSION_3;
   1195     if (capset(&capheader, &capdata[0]) < 0) {
   1196         ALOGE("capset failed: %s\n", strerror(errno));
   1197         exit(66);
   1198     }
   1199 }
   1200 
   1201 static constexpr int PROFMAN_BIN_RETURN_CODE_COMPILE = 0;
   1202 static constexpr int PROFMAN_BIN_RETURN_CODE_SKIP_COMPILATION = 1;
   1203 static constexpr int PROFMAN_BIN_RETURN_CODE_BAD_PROFILES = 2;
   1204 static constexpr int PROFMAN_BIN_RETURN_CODE_ERROR_IO = 3;
   1205 static constexpr int PROFMAN_BIN_RETURN_CODE_ERROR_LOCKING = 4;
   1206 
   1207 static void run_profman_merge(const std::vector<fd_t>& profiles_fd, fd_t reference_profile_fd) {
   1208     static const size_t MAX_INT_LEN = 32;
   1209     static const char* PROFMAN_BIN = "/system/bin/profman";
   1210 
   1211     std::vector<std::string> profile_args(profiles_fd.size());
   1212     char profile_buf[strlen("--profile-file-fd=") + MAX_INT_LEN];
   1213     for (size_t k = 0; k < profiles_fd.size(); k++) {
   1214         sprintf(profile_buf, "--profile-file-fd=%d", profiles_fd[k]);
   1215         profile_args[k].assign(profile_buf);
   1216     }
   1217     char reference_profile_arg[strlen("--reference-profile-file-fd=") + MAX_INT_LEN];
   1218     sprintf(reference_profile_arg, "--reference-profile-file-fd=%d", reference_profile_fd);
   1219 
   1220     // program name, reference profile fd, the final NULL and the profile fds
   1221     const char* argv[3 + profiles_fd.size()];
   1222     int i = 0;
   1223     argv[i++] = PROFMAN_BIN;
   1224     argv[i++] = reference_profile_arg;
   1225     for (size_t k = 0; k < profile_args.size(); k++) {
   1226         argv[i++] = profile_args[k].c_str();
   1227     }
   1228     // Do not add after dex2oat_flags, they should override others for debugging.
   1229     argv[i] = NULL;
   1230 
   1231     execv(PROFMAN_BIN, (char * const *)argv);
   1232     ALOGE("execv(%s) failed: %s\n", PROFMAN_BIN, strerror(errno));
   1233     exit(68);   /* only get here on exec failure */
   1234 }
   1235 
   1236 // Decides if profile guided compilation is needed or not based on existing profiles.
   1237 // Returns true if there is enough information in the current profiles that worth
   1238 // a re-compilation of the package.
   1239 // If the return value is true all the current profiles would have been merged into
   1240 // the reference profiles accessible with open_reference_profile().
   1241 static bool analyse_profiles(uid_t uid, const char* pkgname) {
   1242     std::vector<fd_t> profiles_fd;
   1243     fd_t reference_profile_fd = -1;
   1244     open_profile_files(uid, pkgname, &profiles_fd, &reference_profile_fd);
   1245     if (profiles_fd.empty() || (reference_profile_fd == -1)) {
   1246         // Skip profile guided compilation because no profiles were found.
   1247         // Or if the reference profile info couldn't be opened.
   1248         close_all_fds(profiles_fd, "profiles_fd");
   1249         if ((reference_profile_fd != - 1) && (close(reference_profile_fd) != 0)) {
   1250             PLOG(WARNING) << "Failed to close fd for reference profile";
   1251         }
   1252         return false;
   1253     }
   1254 
   1255     ALOGV("PROFMAN (MERGE): --- BEGIN '%s' ---\n", pkgname);
   1256 
   1257     pid_t pid = fork();
   1258     if (pid == 0) {
   1259         /* child -- drop privileges before continuing */
   1260         drop_capabilities(uid);
   1261         run_profman_merge(profiles_fd, reference_profile_fd);
   1262         exit(68);   /* only get here on exec failure */
   1263     }
   1264     /* parent */
   1265     int return_code = wait_child(pid);
   1266     bool need_to_compile = false;
   1267     bool should_clear_current_profiles = false;
   1268     bool should_clear_reference_profile = false;
   1269     if (!WIFEXITED(return_code)) {
   1270         LOG(WARNING) << "profman failed for package " << pkgname << ": " << return_code;
   1271     } else {
   1272         return_code = WEXITSTATUS(return_code);
   1273         switch (return_code) {
   1274             case PROFMAN_BIN_RETURN_CODE_COMPILE:
   1275                 need_to_compile = true;
   1276                 should_clear_current_profiles = true;
   1277                 should_clear_reference_profile = false;
   1278                 break;
   1279             case PROFMAN_BIN_RETURN_CODE_SKIP_COMPILATION:
   1280                 need_to_compile = false;
   1281                 should_clear_current_profiles = false;
   1282                 should_clear_reference_profile = false;
   1283                 break;
   1284             case PROFMAN_BIN_RETURN_CODE_BAD_PROFILES:
   1285                 LOG(WARNING) << "Bad profiles for package " << pkgname;
   1286                 need_to_compile = false;
   1287                 should_clear_current_profiles = true;
   1288                 should_clear_reference_profile = true;
   1289                 break;
   1290             case PROFMAN_BIN_RETURN_CODE_ERROR_IO:  // fall-through
   1291             case PROFMAN_BIN_RETURN_CODE_ERROR_LOCKING:
   1292                 // Temporary IO problem (e.g. locking). Ignore but log a warning.
   1293                 LOG(WARNING) << "IO error while reading profiles for package " << pkgname;
   1294                 need_to_compile = false;
   1295                 should_clear_current_profiles = false;
   1296                 should_clear_reference_profile = false;
   1297                 break;
   1298            default:
   1299                 // Unknown return code or error. Unlink profiles.
   1300                 LOG(WARNING) << "Unknown error code while processing profiles for package " << pkgname
   1301                         << ": " << return_code;
   1302                 need_to_compile = false;
   1303                 should_clear_current_profiles = true;
   1304                 should_clear_reference_profile = true;
   1305                 break;
   1306         }
   1307     }
   1308     close_all_fds(profiles_fd, "profiles_fd");
   1309     if (close(reference_profile_fd) != 0) {
   1310         PLOG(WARNING) << "Failed to close fd for reference profile";
   1311     }
   1312     if (should_clear_current_profiles) {
   1313         clear_current_profiles(pkgname);
   1314     }
   1315     if (should_clear_reference_profile) {
   1316         clear_reference_profile(pkgname);
   1317     }
   1318     return need_to_compile;
   1319 }
   1320 
   1321 static void run_profman_dump(const std::vector<fd_t>& profile_fds,
   1322                              fd_t reference_profile_fd,
   1323                              const std::vector<std::string>& dex_locations,
   1324                              const std::vector<fd_t>& apk_fds,
   1325                              fd_t output_fd) {
   1326     std::vector<std::string> profman_args;
   1327     static const char* PROFMAN_BIN = "/system/bin/profman";
   1328     profman_args.push_back(PROFMAN_BIN);
   1329     profman_args.push_back("--dump-only");
   1330     profman_args.push_back(StringPrintf("--dump-output-to-fd=%d", output_fd));
   1331     if (reference_profile_fd != -1) {
   1332         profman_args.push_back(StringPrintf("--reference-profile-file-fd=%d",
   1333                                             reference_profile_fd));
   1334     }
   1335     for (fd_t profile_fd : profile_fds) {
   1336         profman_args.push_back(StringPrintf("--profile-file-fd=%d", profile_fd));
   1337     }
   1338     for (const std::string& dex_location : dex_locations) {
   1339         profman_args.push_back(StringPrintf("--dex-location=%s", dex_location.c_str()));
   1340     }
   1341     for (fd_t apk_fd : apk_fds) {
   1342         profman_args.push_back(StringPrintf("--apk-fd=%d", apk_fd));
   1343     }
   1344     const char **argv = new const char*[profman_args.size() + 1];
   1345     size_t i = 0;
   1346     for (const std::string& profman_arg : profman_args) {
   1347         argv[i++] = profman_arg.c_str();
   1348     }
   1349     argv[i] = NULL;
   1350 
   1351     execv(PROFMAN_BIN, (char * const *)argv);
   1352     ALOGE("execv(%s) failed: %s\n", PROFMAN_BIN, strerror(errno));
   1353     exit(68);   /* only get here on exec failure */
   1354 }
   1355 
   1356 static const char* get_location_from_path(const char* path) {
   1357     static constexpr char kLocationSeparator = '/';
   1358     const char *location = strrchr(path, kLocationSeparator);
   1359     if (location == NULL) {
   1360         return path;
   1361     } else {
   1362         // Skip the separator character.
   1363         return location + 1;
   1364     }
   1365 }
   1366 
   1367 // Dumps the contents of a profile file, using pkgname's dex files for pretty
   1368 // printing the result.
   1369 bool dump_profile(uid_t uid, const char* pkgname, const char* code_path_string) {
   1370     std::vector<fd_t> profile_fds;
   1371     fd_t reference_profile_fd = -1;
   1372     std::string out_file_name = StringPrintf("/data/misc/profman/%s.txt", pkgname);
   1373 
   1374     ALOGV("PROFMAN (DUMP): --- BEGIN '%s' ---\n", pkgname);
   1375 
   1376     open_profile_files(uid, pkgname, &profile_fds, &reference_profile_fd);
   1377 
   1378     const bool has_reference_profile = (reference_profile_fd != -1);
   1379     const bool has_profiles = !profile_fds.empty();
   1380 
   1381     if (!has_reference_profile && !has_profiles) {
   1382         ALOGE("profman dump: no profiles to dump for '%s'", pkgname);
   1383         return false;
   1384     }
   1385 
   1386     fd_t output_fd = open(out_file_name.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW);
   1387     if (fchmod(output_fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
   1388         ALOGE("installd cannot chmod '%s' dump_profile\n", out_file_name.c_str());
   1389         return false;
   1390     }
   1391     std::vector<std::string> code_full_paths = base::Split(code_path_string, ";");
   1392     std::vector<std::string> dex_locations;
   1393     std::vector<fd_t> apk_fds;
   1394     for (const std::string& code_full_path : code_full_paths) {
   1395         const char* full_path = code_full_path.c_str();
   1396         fd_t apk_fd = open(full_path, O_RDONLY | O_NOFOLLOW);
   1397         if (apk_fd == -1) {
   1398             ALOGE("installd cannot open '%s'\n", full_path);
   1399             return false;
   1400         }
   1401         dex_locations.push_back(get_location_from_path(full_path));
   1402         apk_fds.push_back(apk_fd);
   1403     }
   1404 
   1405     pid_t pid = fork();
   1406     if (pid == 0) {
   1407         /* child -- drop privileges before continuing */
   1408         drop_capabilities(uid);
   1409         run_profman_dump(profile_fds, reference_profile_fd, dex_locations,
   1410                          apk_fds, output_fd);
   1411         exit(68);   /* only get here on exec failure */
   1412     }
   1413     /* parent */
   1414     close_all_fds(apk_fds, "apk_fds");
   1415     close_all_fds(profile_fds, "profile_fds");
   1416     if (close(reference_profile_fd) != 0) {
   1417         PLOG(WARNING) << "Failed to close fd for reference profile";
   1418     }
   1419     int return_code = wait_child(pid);
   1420     if (!WIFEXITED(return_code)) {
   1421         LOG(WARNING) << "profman failed for package " << pkgname << ": "
   1422                 << return_code;
   1423         return false;
   1424     }
   1425     return true;
   1426 }
   1427 
   1428 // Translate the given oat path to an art (app image) path. An empty string
   1429 // denotes an error.
   1430 static std::string create_image_filename(const std::string& oat_path) {
   1431   // A standard dalvik-cache entry. Replace ".dex" with ".art."
   1432   if (EndsWith(oat_path, ".dex")) {
   1433     std::string art_path = oat_path;
   1434     art_path.replace(art_path.length() - strlen("dex"), strlen("dex"), "art");
   1435     CHECK(EndsWith(art_path, ".art"));
   1436     return art_path;
   1437   }
   1438 
   1439   // An odex entry. Not that this may not be an extension, e.g., in the OTA
   1440   // case (where the base name will have an extension for the B artifact).
   1441   size_t odex_pos = oat_path.rfind(".odex");
   1442   if (odex_pos != std::string::npos) {
   1443     std::string art_path = oat_path;
   1444     art_path.replace(odex_pos, strlen(".odex"), ".art");
   1445     CHECK_NE(art_path.find(".art"), std::string::npos);
   1446     return art_path;
   1447   }
   1448 
   1449   // Don't know how to handle this.
   1450   return "";
   1451 }
   1452 
   1453 static bool add_extension_to_file_name(char* file_name, const char* extension) {
   1454     if (strlen(file_name) + strlen(extension) + 1 > PKG_PATH_MAX) {
   1455         return false;
   1456     }
   1457     strcat(file_name, extension);
   1458     return true;
   1459 }
   1460 
   1461 static int open_output_file(const char* file_name, bool recreate, int permissions) {
   1462     int flags = O_RDWR | O_CREAT;
   1463     if (recreate) {
   1464         if (unlink(file_name) < 0) {
   1465             if (errno != ENOENT) {
   1466                 PLOG(ERROR) << "open_output_file: Couldn't unlink " << file_name;
   1467             }
   1468         }
   1469         flags |= O_EXCL;
   1470     }
   1471     return open(file_name, flags, permissions);
   1472 }
   1473 
   1474 static bool set_permissions_and_ownership(int fd, bool is_public, int uid, const char* path) {
   1475     if (fchmod(fd,
   1476                S_IRUSR|S_IWUSR|S_IRGRP |
   1477                (is_public ? S_IROTH : 0)) < 0) {
   1478         ALOGE("installd cannot chmod '%s' during dexopt\n", path);
   1479         return false;
   1480     } else if (fchown(fd, AID_SYSTEM, uid) < 0) {
   1481         ALOGE("installd cannot chown '%s' during dexopt\n", path);
   1482         return false;
   1483     }
   1484     return true;
   1485 }
   1486 
   1487 static bool create_oat_out_path(const char* apk_path, const char* instruction_set,
   1488             const char* oat_dir, /*out*/ char* out_path) {
   1489     // Early best-effort check whether we can fit the the path into our buffers.
   1490     // Note: the cache path will require an additional 5 bytes for ".swap", but we'll try to run
   1491     // without a swap file, if necessary. Reference profiles file also add an extra ".prof"
   1492     // extension to the cache path (5 bytes).
   1493     if (strlen(apk_path) >= (PKG_PATH_MAX - 8)) {
   1494         ALOGE("apk_path too long '%s'\n", apk_path);
   1495         return false;
   1496     }
   1497 
   1498     if (oat_dir != NULL && oat_dir[0] != '!') {
   1499         if (validate_apk_path(oat_dir)) {
   1500             ALOGE("invalid oat_dir '%s'\n", oat_dir);
   1501             return false;
   1502         }
   1503         if (!calculate_oat_file_path(out_path, oat_dir, apk_path, instruction_set)) {
   1504             return false;
   1505         }
   1506     } else {
   1507         if (!create_cache_path(out_path, apk_path, instruction_set)) {
   1508             return false;
   1509         }
   1510     }
   1511     return true;
   1512 }
   1513 
   1514 // TODO: Consider returning error codes.
   1515 bool merge_profiles(uid_t uid, const char *pkgname) {
   1516     return analyse_profiles(uid, pkgname);
   1517 }
   1518 
   1519 static const char* parse_null(const char* arg) {
   1520     if (strcmp(arg, "!") == 0) {
   1521         return nullptr;
   1522     } else {
   1523         return arg;
   1524     }
   1525 }
   1526 
   1527 int dexopt(const char* const params[DEXOPT_PARAM_COUNT]) {
   1528     return dexopt(params[0],                    // apk_path
   1529                   atoi(params[1]),              // uid
   1530                   params[2],                    // pkgname
   1531                   params[3],                    // instruction_set
   1532                   atoi(params[4]),              // dexopt_needed
   1533                   params[5],                    // oat_dir
   1534                   atoi(params[6]),              // dexopt_flags
   1535                   params[7],                    // compiler_filter
   1536                   parse_null(params[8]),        // volume_uuid
   1537                   parse_null(params[9]));       // shared_libraries
   1538     static_assert(DEXOPT_PARAM_COUNT == 10U, "Unexpected dexopt param count");
   1539 }
   1540 
   1541 // Helper for fd management. This is similar to a unique_fd in that it closes the file descriptor
   1542 // on destruction. It will also run the given cleanup (unless told not to) after closing.
   1543 //
   1544 // Usage example:
   1545 //
   1546 //   Dex2oatFileWrapper<std::function<void ()>> file(open(...),
   1547 //                                                   [name]() {
   1548 //                                                       unlink(name.c_str());
   1549 //                                                   });
   1550 //   // Note: care needs to be taken about name, as it needs to have a lifetime longer than the
   1551 //            wrapper if captured as a reference.
   1552 //
   1553 //   if (file.get() == -1) {
   1554 //       // Error opening...
   1555 //   }
   1556 //
   1557 //   ...
   1558 //   if (error) {
   1559 //       // At this point, when the Dex2oatFileWrapper is destructed, the cleanup function will run
   1560 //       // and delete the file (after the fd is closed).
   1561 //       return -1;
   1562 //   }
   1563 //
   1564 //   (Success case)
   1565 //   file.SetCleanup(false);
   1566 //   // At this point, when the Dex2oatFileWrapper is destructed, the cleanup function will not run
   1567 //   // (leaving the file around; after the fd is closed).
   1568 //
   1569 template <typename Cleanup>
   1570 class Dex2oatFileWrapper {
   1571  public:
   1572     Dex2oatFileWrapper() : value_(-1), cleanup_(), do_cleanup_(true) {
   1573     }
   1574 
   1575     Dex2oatFileWrapper(int value, Cleanup cleanup)
   1576             : value_(value), cleanup_(cleanup), do_cleanup_(true) {}
   1577 
   1578     ~Dex2oatFileWrapper() {
   1579         reset(-1);
   1580     }
   1581 
   1582     int get() {
   1583         return value_;
   1584     }
   1585 
   1586     void SetCleanup(bool cleanup) {
   1587         do_cleanup_ = cleanup;
   1588     }
   1589 
   1590     void reset(int new_value) {
   1591         if (value_ >= 0) {
   1592             close(value_);
   1593         }
   1594         if (do_cleanup_ && cleanup_ != nullptr) {
   1595             cleanup_();
   1596         }
   1597 
   1598         value_ = new_value;
   1599     }
   1600 
   1601     void reset(int new_value, Cleanup new_cleanup) {
   1602         if (value_ >= 0) {
   1603             close(value_);
   1604         }
   1605         if (do_cleanup_ && cleanup_ != nullptr) {
   1606             cleanup_();
   1607         }
   1608 
   1609         value_ = new_value;
   1610         cleanup_ = new_cleanup;
   1611     }
   1612 
   1613  private:
   1614     int value_;
   1615     Cleanup cleanup_;
   1616     bool do_cleanup_;
   1617 };
   1618 
   1619 int dexopt(const char* apk_path, uid_t uid, const char* pkgname, const char* instruction_set,
   1620            int dexopt_needed, const char* oat_dir, int dexopt_flags, const char* compiler_filter,
   1621            const char* volume_uuid ATTRIBUTE_UNUSED, const char* shared_libraries)
   1622 {
   1623     bool is_public = ((dexopt_flags & DEXOPT_PUBLIC) != 0);
   1624     bool vm_safe_mode = (dexopt_flags & DEXOPT_SAFEMODE) != 0;
   1625     bool debuggable = (dexopt_flags & DEXOPT_DEBUGGABLE) != 0;
   1626     bool boot_complete = (dexopt_flags & DEXOPT_BOOTCOMPLETE) != 0;
   1627     bool profile_guided = (dexopt_flags & DEXOPT_PROFILE_GUIDED) != 0;
   1628 
   1629     // Don't use profile for vm_safe_mode. b/30688277
   1630     profile_guided = profile_guided && !vm_safe_mode;
   1631 
   1632     CHECK(pkgname != nullptr);
   1633     CHECK(pkgname[0] != 0);
   1634 
   1635     // Public apps should not be compiled with profile information ever. Same goes for the special
   1636     // package '*' used for the system server.
   1637     Dex2oatFileWrapper<std::function<void ()>> reference_profile_fd;
   1638     if (!is_public && pkgname[0] != '*') {
   1639         // Open reference profile in read only mode as dex2oat does not get write permissions.
   1640         const std::string pkgname_str(pkgname);
   1641         reference_profile_fd.reset(open_reference_profile(uid, pkgname, /*read_write*/ false),
   1642                                    [pkgname_str]() {
   1643                                        clear_reference_profile(pkgname_str.c_str());
   1644                                    });
   1645         // Note: it's OK to not find a profile here.
   1646     }
   1647 
   1648     if ((dexopt_flags & ~DEXOPT_MASK) != 0) {
   1649         LOG_FATAL("dexopt flags contains unknown fields\n");
   1650     }
   1651 
   1652     char out_path[PKG_PATH_MAX];
   1653     if (!create_oat_out_path(apk_path, instruction_set, oat_dir, out_path)) {
   1654         return false;
   1655     }
   1656 
   1657     const char *input_file;
   1658     char in_odex_path[PKG_PATH_MAX];
   1659     switch (dexopt_needed) {
   1660         case DEXOPT_DEX2OAT_NEEDED:
   1661             input_file = apk_path;
   1662             break;
   1663 
   1664         case DEXOPT_PATCHOAT_NEEDED:
   1665             if (!calculate_odex_file_path(in_odex_path, apk_path, instruction_set)) {
   1666                 return -1;
   1667             }
   1668             input_file = in_odex_path;
   1669             break;
   1670 
   1671         case DEXOPT_SELF_PATCHOAT_NEEDED:
   1672             input_file = out_path;
   1673             break;
   1674 
   1675         default:
   1676             ALOGE("Invalid dexopt needed: %d\n", dexopt_needed);
   1677             return 72;
   1678     }
   1679 
   1680     struct stat input_stat;
   1681     memset(&input_stat, 0, sizeof(input_stat));
   1682     stat(input_file, &input_stat);
   1683 
   1684     base::unique_fd input_fd(open(input_file, O_RDONLY, 0));
   1685     if (input_fd.get() < 0) {
   1686         ALOGE("installd cannot open '%s' for input during dexopt\n", input_file);
   1687         return -1;
   1688     }
   1689 
   1690     const std::string out_path_str(out_path);
   1691     Dex2oatFileWrapper<std::function<void ()>> out_fd(
   1692             open_output_file(out_path, /*recreate*/true, /*permissions*/0644),
   1693             [out_path_str]() { unlink(out_path_str.c_str()); });
   1694     if (out_fd.get() < 0) {
   1695         ALOGE("installd cannot open '%s' for output during dexopt\n", out_path);
   1696         return -1;
   1697     }
   1698     if (!set_permissions_and_ownership(out_fd.get(), is_public, uid, out_path)) {
   1699         return -1;
   1700     }
   1701 
   1702     // Create a swap file if necessary.
   1703     base::unique_fd swap_fd;
   1704     if (ShouldUseSwapFileForDexopt()) {
   1705         // Make sure there really is enough space.
   1706         char swap_file_name[PKG_PATH_MAX];
   1707         strcpy(swap_file_name, out_path);
   1708         if (add_extension_to_file_name(swap_file_name, ".swap")) {
   1709             swap_fd.reset(open_output_file(swap_file_name, /*recreate*/true, /*permissions*/0600));
   1710         }
   1711         if (swap_fd.get() < 0) {
   1712             // Could not create swap file. Optimistically go on and hope that we can compile
   1713             // without it.
   1714             ALOGE("installd could not create '%s' for swap during dexopt\n", swap_file_name);
   1715         } else {
   1716             // Immediately unlink. We don't really want to hit flash.
   1717             if (unlink(swap_file_name) < 0) {
   1718                 PLOG(ERROR) << "Couldn't unlink swap file " << swap_file_name;
   1719             }
   1720         }
   1721     }
   1722 
   1723     // Avoid generating an app image for extract only since it will not contain any classes.
   1724     Dex2oatFileWrapper<std::function<void ()>> image_fd;
   1725     const std::string image_path = create_image_filename(out_path);
   1726     if (!image_path.empty()) {
   1727         char app_image_format[kPropertyValueMax];
   1728         bool have_app_image_format =
   1729                 get_property("dalvik.vm.appimageformat", app_image_format, NULL) > 0;
   1730         // Use app images only if it is enabled (by a set image format) and we are compiling
   1731         // profile-guided (so the app image doesn't conservatively contain all classes).
   1732         if (profile_guided && have_app_image_format) {
   1733             // Recreate is true since we do not want to modify a mapped image. If the app is
   1734             // already running and we modify the image file, it can cause crashes (b/27493510).
   1735             image_fd.reset(open_output_file(image_path.c_str(),
   1736                                             true /*recreate*/,
   1737                                             0600 /*permissions*/),
   1738                            [image_path]() { unlink(image_path.c_str()); }
   1739                            );
   1740             if (image_fd.get() < 0) {
   1741                 // Could not create application image file. Go on since we can compile without
   1742                 // it.
   1743                 LOG(ERROR) << "installd could not create '"
   1744                         << image_path
   1745                         << "' for image file during dexopt";
   1746             } else if (!set_permissions_and_ownership(image_fd.get(),
   1747                                                       is_public,
   1748                                                       uid,
   1749                                                       image_path.c_str())) {
   1750                 image_fd.reset(-1);
   1751             }
   1752         }
   1753         // If we have a valid image file path but no image fd, explicitly erase the image file.
   1754         if (image_fd.get() < 0) {
   1755             if (unlink(image_path.c_str()) < 0) {
   1756                 if (errno != ENOENT) {
   1757                     PLOG(ERROR) << "Couldn't unlink image file " << image_path;
   1758                 }
   1759             }
   1760         }
   1761     }
   1762 
   1763     ALOGV("DexInv: --- BEGIN '%s' ---\n", input_file);
   1764 
   1765     pid_t pid = fork();
   1766     if (pid == 0) {
   1767         /* child -- drop privileges before continuing */
   1768         drop_capabilities(uid);
   1769 
   1770         SetDex2OatAndPatchOatScheduling(boot_complete);
   1771         if (flock(out_fd.get(), LOCK_EX | LOCK_NB) != 0) {
   1772             ALOGE("flock(%s) failed: %s\n", out_path, strerror(errno));
   1773             _exit(67);
   1774         }
   1775 
   1776         if (dexopt_needed == DEXOPT_PATCHOAT_NEEDED
   1777             || dexopt_needed == DEXOPT_SELF_PATCHOAT_NEEDED) {
   1778             run_patchoat(input_fd.get(),
   1779                          out_fd.get(),
   1780                          input_file,
   1781                          out_path,
   1782                          pkgname,
   1783                          instruction_set);
   1784         } else if (dexopt_needed == DEXOPT_DEX2OAT_NEEDED) {
   1785             // Pass dex2oat the relative path to the input file.
   1786             const char *input_file_name = get_location_from_path(input_file);
   1787             run_dex2oat(input_fd.get(),
   1788                         out_fd.get(),
   1789                         image_fd.get(),
   1790                         input_file_name,
   1791                         out_path,
   1792                         swap_fd.get(),
   1793                         instruction_set,
   1794                         compiler_filter,
   1795                         vm_safe_mode,
   1796                         debuggable,
   1797                         boot_complete,
   1798                         reference_profile_fd.get(),
   1799                         shared_libraries);
   1800         } else {
   1801             ALOGE("Invalid dexopt needed: %d\n", dexopt_needed);
   1802             _exit(73);
   1803         }
   1804         _exit(68);   /* only get here on exec failure */
   1805     } else {
   1806         int res = wait_child(pid);
   1807         if (res == 0) {
   1808             ALOGV("DexInv: --- END '%s' (success) ---\n", input_file);
   1809         } else {
   1810             ALOGE("DexInv: --- END '%s' --- status=0x%04x, process failed\n", input_file, res);
   1811             return -1;
   1812         }
   1813     }
   1814 
   1815     struct utimbuf ut;
   1816     ut.actime = input_stat.st_atime;
   1817     ut.modtime = input_stat.st_mtime;
   1818     utime(out_path, &ut);
   1819 
   1820     // We've been successful, don't delete output.
   1821     out_fd.SetCleanup(false);
   1822     image_fd.SetCleanup(false);
   1823     reference_profile_fd.SetCleanup(false);
   1824 
   1825     return 0;
   1826 }
   1827 
   1828 int mark_boot_complete(const char* instruction_set)
   1829 {
   1830   char boot_marker_path[PKG_PATH_MAX];
   1831   sprintf(boot_marker_path,
   1832           "%s/%s/%s/.booting",
   1833           android_data_dir.path,
   1834           DALVIK_CACHE,
   1835           instruction_set);
   1836 
   1837   ALOGV("mark_boot_complete : %s", boot_marker_path);
   1838   if (unlink(boot_marker_path) != 0) {
   1839       ALOGE("Unable to unlink boot marker at %s, error=%s", boot_marker_path,
   1840             strerror(errno));
   1841       return -1;
   1842   }
   1843 
   1844   return 0;
   1845 }
   1846 
   1847 void mkinnerdirs(char* path, int basepos, mode_t mode, int uid, int gid,
   1848         struct stat* statbuf)
   1849 {
   1850     while (path[basepos] != 0) {
   1851         if (path[basepos] == '/') {
   1852             path[basepos] = 0;
   1853             if (lstat(path, statbuf) < 0) {
   1854                 ALOGV("Making directory: %s\n", path);
   1855                 if (mkdir(path, mode) == 0) {
   1856                     chown(path, uid, gid);
   1857                 } else {
   1858                     ALOGW("Unable to make directory %s: %s\n", path, strerror(errno));
   1859                 }
   1860             }
   1861             path[basepos] = '/';
   1862             basepos++;
   1863         }
   1864         basepos++;
   1865     }
   1866 }
   1867 
   1868 int linklib(const char* uuid, const char* pkgname, const char* asecLibDir, int userId)
   1869 {
   1870     struct stat s, libStat;
   1871     int rc = 0;
   1872 
   1873     std::string _pkgdir(create_data_user_ce_package_path(uuid, userId, pkgname));
   1874     std::string _libsymlink(_pkgdir + PKG_LIB_POSTFIX);
   1875 
   1876     const char* pkgdir = _pkgdir.c_str();
   1877     const char* libsymlink = _libsymlink.c_str();
   1878 
   1879     if (stat(pkgdir, &s) < 0) return -1;
   1880 
   1881     if (chown(pkgdir, AID_INSTALL, AID_INSTALL) < 0) {
   1882         ALOGE("failed to chown '%s': %s\n", pkgdir, strerror(errno));
   1883         return -1;
   1884     }
   1885 
   1886     if (chmod(pkgdir, 0700) < 0) {
   1887         ALOGE("linklib() 1: failed to chmod '%s': %s\n", pkgdir, strerror(errno));
   1888         rc = -1;
   1889         goto out;
   1890     }
   1891 
   1892     if (lstat(libsymlink, &libStat) < 0) {
   1893         if (errno != ENOENT) {
   1894             ALOGE("couldn't stat lib dir: %s\n", strerror(errno));
   1895             rc = -1;
   1896             goto out;
   1897         }
   1898     } else {
   1899         if (S_ISDIR(libStat.st_mode)) {
   1900             if (delete_dir_contents(libsymlink, 1, NULL) < 0) {
   1901                 rc = -1;
   1902                 goto out;
   1903             }
   1904         } else if (S_ISLNK(libStat.st_mode)) {
   1905             if (unlink(libsymlink) < 0) {
   1906                 ALOGE("couldn't unlink lib dir: %s\n", strerror(errno));
   1907                 rc = -1;
   1908                 goto out;
   1909             }
   1910         }
   1911     }
   1912 
   1913     if (symlink(asecLibDir, libsymlink) < 0) {
   1914         ALOGE("couldn't symlink directory '%s' -> '%s': %s\n", libsymlink, asecLibDir,
   1915                 strerror(errno));
   1916         rc = -errno;
   1917         goto out;
   1918     }
   1919 
   1920 out:
   1921     if (chmod(pkgdir, s.st_mode) < 0) {
   1922         ALOGE("linklib() 2: failed to chmod '%s': %s\n", pkgdir, strerror(errno));
   1923         rc = -errno;
   1924     }
   1925 
   1926     if (chown(pkgdir, s.st_uid, s.st_gid) < 0) {
   1927         ALOGE("failed to chown '%s' : %s\n", pkgdir, strerror(errno));
   1928         return -errno;
   1929     }
   1930 
   1931     return rc;
   1932 }
   1933 
   1934 static void run_idmap(const char *target_apk, const char *overlay_apk, int idmap_fd)
   1935 {
   1936     static const char *IDMAP_BIN = "/system/bin/idmap";
   1937     static const size_t MAX_INT_LEN = 32;
   1938     char idmap_str[MAX_INT_LEN];
   1939 
   1940     snprintf(idmap_str, sizeof(idmap_str), "%d", idmap_fd);
   1941 
   1942     execl(IDMAP_BIN, IDMAP_BIN, "--fd", target_apk, overlay_apk, idmap_str, (char*)NULL);
   1943     ALOGE("execl(%s) failed: %s\n", IDMAP_BIN, strerror(errno));
   1944 }
   1945 
   1946 // Transform string /a/b/c.apk to (prefix)/a@b (at) c.apk@(suffix)
   1947 // eg /a/b/c.apk to /data/resource-cache/a@b (at) c.apk@idmap
   1948 static int flatten_path(const char *prefix, const char *suffix,
   1949         const char *overlay_path, char *idmap_path, size_t N)
   1950 {
   1951     if (overlay_path == NULL || idmap_path == NULL) {
   1952         return -1;
   1953     }
   1954     const size_t len_overlay_path = strlen(overlay_path);
   1955     // will access overlay_path + 1 further below; requires absolute path
   1956     if (len_overlay_path < 2 || *overlay_path != '/') {
   1957         return -1;
   1958     }
   1959     const size_t len_idmap_root = strlen(prefix);
   1960     const size_t len_suffix = strlen(suffix);
   1961     if (SIZE_MAX - len_idmap_root < len_overlay_path ||
   1962             SIZE_MAX - (len_idmap_root + len_overlay_path) < len_suffix) {
   1963         // additions below would cause overflow
   1964         return -1;
   1965     }
   1966     if (N < len_idmap_root + len_overlay_path + len_suffix) {
   1967         return -1;
   1968     }
   1969     memset(idmap_path, 0, N);
   1970     snprintf(idmap_path, N, "%s%s%s", prefix, overlay_path + 1, suffix);
   1971     char *ch = idmap_path + len_idmap_root;
   1972     while (*ch != '\0') {
   1973         if (*ch == '/') {
   1974             *ch = '@';
   1975         }
   1976         ++ch;
   1977     }
   1978     return 0;
   1979 }
   1980 
   1981 int idmap(const char *target_apk, const char *overlay_apk, uid_t uid)
   1982 {
   1983     ALOGV("idmap target_apk=%s overlay_apk=%s uid=%d\n", target_apk, overlay_apk, uid);
   1984 
   1985     int idmap_fd = -1;
   1986     char idmap_path[PATH_MAX];
   1987 
   1988     if (flatten_path(IDMAP_PREFIX, IDMAP_SUFFIX, overlay_apk,
   1989                 idmap_path, sizeof(idmap_path)) == -1) {
   1990         ALOGE("idmap cannot generate idmap path for overlay %s\n", overlay_apk);
   1991         goto fail;
   1992     }
   1993 
   1994     unlink(idmap_path);
   1995     idmap_fd = open(idmap_path, O_RDWR | O_CREAT | O_EXCL, 0644);
   1996     if (idmap_fd < 0) {
   1997         ALOGE("idmap cannot open '%s' for output: %s\n", idmap_path, strerror(errno));
   1998         goto fail;
   1999     }
   2000     if (fchown(idmap_fd, AID_SYSTEM, uid) < 0) {
   2001         ALOGE("idmap cannot chown '%s'\n", idmap_path);
   2002         goto fail;
   2003     }
   2004     if (fchmod(idmap_fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0) {
   2005         ALOGE("idmap cannot chmod '%s'\n", idmap_path);
   2006         goto fail;
   2007     }
   2008 
   2009     pid_t pid;
   2010     pid = fork();
   2011     if (pid == 0) {
   2012         /* child -- drop privileges before continuing */
   2013         if (setgid(uid) != 0) {
   2014             ALOGE("setgid(%d) failed during idmap\n", uid);
   2015             exit(1);
   2016         }
   2017         if (setuid(uid) != 0) {
   2018             ALOGE("setuid(%d) failed during idmap\n", uid);
   2019             exit(1);
   2020         }
   2021         if (flock(idmap_fd, LOCK_EX | LOCK_NB) != 0) {
   2022             ALOGE("flock(%s) failed during idmap: %s\n", idmap_path, strerror(errno));
   2023             exit(1);
   2024         }
   2025 
   2026         run_idmap(target_apk, overlay_apk, idmap_fd);
   2027         exit(1); /* only if exec call to idmap failed */
   2028     } else {
   2029         int status = wait_child(pid);
   2030         if (status != 0) {
   2031             ALOGE("idmap failed, status=0x%04x\n", status);
   2032             goto fail;
   2033         }
   2034     }
   2035 
   2036     close(idmap_fd);
   2037     return 0;
   2038 fail:
   2039     if (idmap_fd >= 0) {
   2040         close(idmap_fd);
   2041         unlink(idmap_path);
   2042     }
   2043     return -1;
   2044 }
   2045 
   2046 int restorecon_app_data(const char* uuid, const char* pkgName, userid_t userid, int flags,
   2047         appid_t appid, const char* seinfo) {
   2048     int res = 0;
   2049 
   2050     // SELINUX_ANDROID_RESTORECON_DATADATA flag is set by libselinux. Not needed here.
   2051     unsigned int seflags = SELINUX_ANDROID_RESTORECON_RECURSE;
   2052 
   2053     if (!pkgName || !seinfo) {
   2054         ALOGE("Package name or seinfo tag is null when trying to restorecon.");
   2055         return -1;
   2056     }
   2057 
   2058     uid_t uid = multiuser_get_uid(userid, appid);
   2059     if (flags & FLAG_STORAGE_CE) {
   2060         auto path = create_data_user_ce_package_path(uuid, userid, pkgName);
   2061         if (selinux_android_restorecon_pkgdir(path.c_str(), seinfo, uid, seflags) < 0) {
   2062             PLOG(ERROR) << "restorecon failed for " << path;
   2063             res = -1;
   2064         }
   2065     }
   2066     if (flags & FLAG_STORAGE_DE) {
   2067         auto path = create_data_user_de_package_path(uuid, userid, pkgName);
   2068         if (selinux_android_restorecon_pkgdir(path.c_str(), seinfo, uid, seflags) < 0) {
   2069             PLOG(ERROR) << "restorecon failed for " << path;
   2070             // TODO: include result once 25796509 is fixed
   2071         }
   2072     }
   2073 
   2074     return res;
   2075 }
   2076 
   2077 int create_oat_dir(const char* oat_dir, const char* instruction_set)
   2078 {
   2079     char oat_instr_dir[PKG_PATH_MAX];
   2080 
   2081     if (validate_apk_path(oat_dir)) {
   2082         ALOGE("invalid apk path '%s' (bad prefix)\n", oat_dir);
   2083         return -1;
   2084     }
   2085     if (fs_prepare_dir(oat_dir, S_IRWXU | S_IRWXG | S_IXOTH, AID_SYSTEM, AID_INSTALL)) {
   2086         return -1;
   2087     }
   2088     if (selinux_android_restorecon(oat_dir, 0)) {
   2089         ALOGE("cannot restorecon dir '%s': %s\n", oat_dir, strerror(errno));
   2090         return -1;
   2091     }
   2092     snprintf(oat_instr_dir, PKG_PATH_MAX, "%s/%s", oat_dir, instruction_set);
   2093     if (fs_prepare_dir(oat_instr_dir, S_IRWXU | S_IRWXG | S_IXOTH, AID_SYSTEM, AID_INSTALL)) {
   2094         return -1;
   2095     }
   2096     return 0;
   2097 }
   2098 
   2099 int rm_package_dir(const char* apk_path)
   2100 {
   2101     if (validate_apk_path(apk_path)) {
   2102         ALOGE("invalid apk path '%s' (bad prefix)\n", apk_path);
   2103         return -1;
   2104     }
   2105     return delete_dir_contents(apk_path, 1 /* also_delete_dir */ , NULL /* exclusion_predicate */);
   2106 }
   2107 
   2108 int link_file(const char* relative_path, const char* from_base, const char* to_base) {
   2109     char from_path[PKG_PATH_MAX];
   2110     char to_path[PKG_PATH_MAX];
   2111     snprintf(from_path, PKG_PATH_MAX, "%s/%s", from_base, relative_path);
   2112     snprintf(to_path, PKG_PATH_MAX, "%s/%s", to_base, relative_path);
   2113 
   2114     if (validate_apk_path_subdirs(from_path)) {
   2115         ALOGE("invalid app data sub-path '%s' (bad prefix)\n", from_path);
   2116         return -1;
   2117     }
   2118 
   2119     if (validate_apk_path_subdirs(to_path)) {
   2120         ALOGE("invalid app data sub-path '%s' (bad prefix)\n", to_path);
   2121         return -1;
   2122     }
   2123 
   2124     const int ret = link(from_path, to_path);
   2125     if (ret < 0) {
   2126         ALOGE("link(%s, %s) failed : %s", from_path, to_path, strerror(errno));
   2127         return -1;
   2128     }
   2129 
   2130     return 0;
   2131 }
   2132 
   2133 // Helper for move_ab, so that we can have common failure-case cleanup.
   2134 static bool unlink_and_rename(const char* from, const char* to) {
   2135     // Check whether "from" exists, and if so whether it's regular. If it is, unlink. Otherwise,
   2136     // return a failure.
   2137     struct stat s;
   2138     if (stat(to, &s) == 0) {
   2139         if (!S_ISREG(s.st_mode)) {
   2140             LOG(ERROR) << from << " is not a regular file to replace for A/B.";
   2141             return false;
   2142         }
   2143         if (unlink(to) != 0) {
   2144             LOG(ERROR) << "Could not unlink " << to << " to move A/B.";
   2145             return false;
   2146         }
   2147     } else {
   2148         // This may be a permission problem. We could investigate the error code, but we'll just
   2149         // let the rename failure do the work for us.
   2150     }
   2151 
   2152     // Try to rename "to" to "from."
   2153     if (rename(from, to) != 0) {
   2154         PLOG(ERROR) << "Could not rename " << from << " to " << to;
   2155         return false;
   2156     }
   2157 
   2158     return true;
   2159 }
   2160 
   2161 // Move/rename a B artifact (from) to an A artifact (to).
   2162 static bool move_ab_path(const std::string& b_path, const std::string& a_path) {
   2163     // Check whether B exists.
   2164     {
   2165         struct stat s;
   2166         if (stat(b_path.c_str(), &s) != 0) {
   2167             // Silently ignore for now. The service calling this isn't smart enough to understand
   2168             // lack of artifacts at the moment.
   2169             return false;
   2170         }
   2171         if (!S_ISREG(s.st_mode)) {
   2172             LOG(ERROR) << "A/B artifact " << b_path << " is not a regular file.";
   2173             // Try to unlink, but swallow errors.
   2174             unlink(b_path.c_str());
   2175             return false;
   2176         }
   2177     }
   2178 
   2179     // Rename B to A.
   2180     if (!unlink_and_rename(b_path.c_str(), a_path.c_str())) {
   2181         // Delete the b_path so we don't try again (or fail earlier).
   2182         if (unlink(b_path.c_str()) != 0) {
   2183             PLOG(ERROR) << "Could not unlink " << b_path;
   2184         }
   2185 
   2186         return false;
   2187     }
   2188 
   2189     return true;
   2190 }
   2191 
   2192 int move_ab(const char* apk_path, const char* instruction_set, const char* oat_dir) {
   2193     if (apk_path == nullptr || instruction_set == nullptr || oat_dir == nullptr) {
   2194         LOG(ERROR) << "Cannot move_ab with null input";
   2195         return -1;
   2196     }
   2197 
   2198     // Get the current slot suffix. No suffix, no A/B.
   2199     std::string slot_suffix;
   2200     {
   2201         char buf[kPropertyValueMax];
   2202         if (get_property("ro.boot.slot_suffix", buf, nullptr) <= 0) {
   2203             return -1;
   2204         }
   2205         slot_suffix = buf;
   2206 
   2207         if (!ValidateTargetSlotSuffix(slot_suffix)) {
   2208             LOG(ERROR) << "Target slot suffix not legal: " << slot_suffix;
   2209             return -1;
   2210         }
   2211     }
   2212 
   2213     // Validate other inputs.
   2214     if (validate_apk_path(apk_path) != 0) {
   2215         LOG(ERROR) << "invalid apk_path " << apk_path;
   2216         return -1;
   2217     }
   2218     if (validate_apk_path(oat_dir) != 0) {
   2219         LOG(ERROR) << "invalid oat_dir " << oat_dir;
   2220         return -1;
   2221     }
   2222 
   2223     char a_path[PKG_PATH_MAX];
   2224     if (!calculate_oat_file_path(a_path, oat_dir, apk_path, instruction_set)) {
   2225         return -1;
   2226     }
   2227     const std::string a_image_path = create_image_filename(a_path);
   2228 
   2229     // B path = A path + slot suffix.
   2230     const std::string b_path = StringPrintf("%s.%s", a_path, slot_suffix.c_str());
   2231     const std::string b_image_path = StringPrintf("%s.%s",
   2232                                                   a_image_path.c_str(),
   2233                                                   slot_suffix.c_str());
   2234 
   2235     bool oat_success = move_ab_path(b_path, a_path);
   2236     bool success;
   2237 
   2238     if (oat_success) {
   2239         // Note: we can live without an app image. As such, ignore failure to move the image file.
   2240         //       If we decide to require the app image, or the app image being moved correctly,
   2241         //       then change accordingly.
   2242         constexpr bool kIgnoreAppImageFailure = true;
   2243 
   2244         bool art_success = true;
   2245         if (!a_image_path.empty()) {
   2246             art_success = move_ab_path(b_image_path, a_image_path);
   2247             if (!art_success) {
   2248                 unlink(a_image_path.c_str());
   2249             }
   2250         }
   2251 
   2252         success = art_success || kIgnoreAppImageFailure;
   2253     } else {
   2254         // Cleanup: delete B image, ignore errors.
   2255         unlink(b_image_path.c_str());
   2256 
   2257         success = false;
   2258     }
   2259 
   2260     return success ? 0 : -1;
   2261 }
   2262 
   2263 bool delete_odex(const char *apk_path, const char *instruction_set, const char *oat_dir) {
   2264     // Delete the oat/odex file.
   2265     char out_path[PKG_PATH_MAX];
   2266     if (!create_oat_out_path(apk_path, instruction_set, oat_dir, out_path)) {
   2267         return false;
   2268     }
   2269 
   2270     // In case of a permission failure report the issue. Otherwise just print a warning.
   2271     auto unlink_and_check = [](const char* path) -> bool {
   2272         int result = unlink(path);
   2273         if (result != 0) {
   2274             if (errno == EACCES || errno == EPERM) {
   2275                 PLOG(ERROR) << "Could not unlink " << path;
   2276                 return false;
   2277             }
   2278             PLOG(WARNING) << "Could not unlink " << path;
   2279         }
   2280         return true;
   2281     };
   2282 
   2283     // Delete the oat/odex file.
   2284     bool return_value_oat = unlink_and_check(out_path);
   2285 
   2286     // Derive and delete the app image.
   2287     bool return_value_art = unlink_and_check(create_image_filename(out_path).c_str());
   2288 
   2289     // Report success.
   2290     return return_value_oat && return_value_art;
   2291 }
   2292 
   2293 }  // namespace installd
   2294 }  // namespace android
   2295