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 "InstalldNativeService.h"
     18 
     19 #define ATRACE_TAG ATRACE_TAG_PACKAGE_MANAGER
     20 
     21 #include <algorithm>
     22 #include <errno.h>
     23 #include <fstream>
     24 #include <fts.h>
     25 #include <functional>
     26 #include <inttypes.h>
     27 #include <regex>
     28 #include <stdlib.h>
     29 #include <string.h>
     30 #include <sys/capability.h>
     31 #include <sys/file.h>
     32 #include <sys/ioctl.h>
     33 #include <sys/mman.h>
     34 #include <sys/resource.h>
     35 #include <sys/stat.h>
     36 #include <sys/statvfs.h>
     37 #include <sys/types.h>
     38 #include <sys/wait.h>
     39 #include <sys/xattr.h>
     40 #include <unistd.h>
     41 
     42 #include <android-base/file.h>
     43 #include <android-base/logging.h>
     44 #include <android-base/properties.h>
     45 #include <android-base/scopeguard.h>
     46 #include <android-base/stringprintf.h>
     47 #include <android-base/strings.h>
     48 #include <android-base/unique_fd.h>
     49 #include <cutils/ashmem.h>
     50 #include <cutils/fs.h>
     51 #include <cutils/properties.h>
     52 #include <cutils/sched_policy.h>
     53 #include <log/log.h>               // TODO: Move everything to base/logging.
     54 #include <logwrap/logwrap.h>
     55 #include <private/android_filesystem_config.h>
     56 #include <selinux/android.h>
     57 #include <system/thread_defs.h>
     58 #include <utils/Trace.h>
     59 
     60 #include "dexopt.h"
     61 #include "globals.h"
     62 #include "installd_deps.h"
     63 #include "otapreopt_utils.h"
     64 #include "utils.h"
     65 #include "view_compiler.h"
     66 
     67 #include "CacheTracker.h"
     68 #include "MatchExtensionGen.h"
     69 #include "QuotaUtils.h"
     70 
     71 #ifndef LOG_TAG
     72 #define LOG_TAG "installd"
     73 #endif
     74 
     75 using android::base::StringPrintf;
     76 using std::endl;
     77 
     78 namespace android {
     79 namespace installd {
     80 
     81 // An uuid used in unit tests.
     82 static constexpr const char* kTestUuid = "TEST";
     83 
     84 static constexpr const mode_t kRollbackFolderMode = 0700;
     85 
     86 static constexpr const char* kCpPath = "/system/bin/cp";
     87 static constexpr const char* kXattrDefault = "user.default";
     88 
     89 static constexpr const int MIN_RESTRICTED_HOME_SDK_VERSION = 24; // > M
     90 
     91 static constexpr const char* PKG_LIB_POSTFIX = "/lib";
     92 static constexpr const char* CACHE_DIR_POSTFIX = "/cache";
     93 static constexpr const char* CODE_CACHE_DIR_POSTFIX = "/code_cache";
     94 
     95 static constexpr const char *kIdMapPath = "/system/bin/idmap";
     96 static constexpr const char* IDMAP_PREFIX = "/data/resource-cache/";
     97 static constexpr const char* IDMAP_SUFFIX = "@idmap";
     98 
     99 // fsverity assumes the page size is always 4096. If not, the feature can not be
    100 // enabled.
    101 static constexpr int kVerityPageSize = 4096;
    102 static constexpr size_t kSha256Size = 32;
    103 static constexpr const char* kPropApkVerityMode = "ro.apk_verity.mode";
    104 
    105 namespace {
    106 
    107 constexpr const char* kDump = "android.permission.DUMP";
    108 
    109 static binder::Status ok() {
    110     return binder::Status::ok();
    111 }
    112 
    113 static binder::Status exception(uint32_t code, const std::string& msg) {
    114     LOG(ERROR) << msg << " (" << code << ")";
    115     return binder::Status::fromExceptionCode(code, String8(msg.c_str()));
    116 }
    117 
    118 static binder::Status error() {
    119     return binder::Status::fromServiceSpecificError(errno);
    120 }
    121 
    122 static binder::Status error(const std::string& msg) {
    123     PLOG(ERROR) << msg;
    124     return binder::Status::fromServiceSpecificError(errno, String8(msg.c_str()));
    125 }
    126 
    127 static binder::Status error(uint32_t code, const std::string& msg) {
    128     LOG(ERROR) << msg << " (" << code << ")";
    129     return binder::Status::fromServiceSpecificError(code, String8(msg.c_str()));
    130 }
    131 
    132 binder::Status checkPermission(const char* permission) {
    133     pid_t pid;
    134     uid_t uid;
    135 
    136     if (checkCallingPermission(String16(permission), reinterpret_cast<int32_t*>(&pid),
    137             reinterpret_cast<int32_t*>(&uid))) {
    138         return ok();
    139     } else {
    140         return exception(binder::Status::EX_SECURITY,
    141                 StringPrintf("UID %d / PID %d lacks permission %s", uid, pid, permission));
    142     }
    143 }
    144 
    145 binder::Status checkUid(uid_t expectedUid) {
    146     uid_t uid = IPCThreadState::self()->getCallingUid();
    147     if (uid == expectedUid || uid == AID_ROOT) {
    148         return ok();
    149     } else {
    150         return exception(binder::Status::EX_SECURITY,
    151                 StringPrintf("UID %d is not expected UID %d", uid, expectedUid));
    152     }
    153 }
    154 
    155 binder::Status checkArgumentUuid(const std::unique_ptr<std::string>& uuid) {
    156     if (!uuid || is_valid_filename(*uuid)) {
    157         return ok();
    158     } else {
    159         return exception(binder::Status::EX_ILLEGAL_ARGUMENT,
    160                 StringPrintf("UUID %s is malformed", uuid->c_str()));
    161     }
    162 }
    163 
    164 binder::Status checkArgumentUuidTestOrNull(const std::unique_ptr<std::string>& uuid) {
    165     if (!uuid || strcmp(uuid->c_str(), kTestUuid) == 0) {
    166         return ok();
    167     } else {
    168         return exception(binder::Status::EX_ILLEGAL_ARGUMENT,
    169                 StringPrintf("UUID must be null or \"%s\", got: %s", kTestUuid, uuid->c_str()));
    170     }
    171 }
    172 
    173 binder::Status checkArgumentPackageName(const std::string& packageName) {
    174     if (is_valid_package_name(packageName)) {
    175         return ok();
    176     } else {
    177         return exception(binder::Status::EX_ILLEGAL_ARGUMENT,
    178                 StringPrintf("Package name %s is malformed", packageName.c_str()));
    179     }
    180 }
    181 
    182 binder::Status checkArgumentPath(const std::string& path) {
    183     if (path.empty()) {
    184         return exception(binder::Status::EX_ILLEGAL_ARGUMENT, "Missing path");
    185     }
    186     if (path[0] != '/') {
    187         return exception(binder::Status::EX_ILLEGAL_ARGUMENT,
    188                 StringPrintf("Path %s is relative", path.c_str()));
    189     }
    190     if ((path + '/').find("/../") != std::string::npos) {
    191         return exception(binder::Status::EX_ILLEGAL_ARGUMENT,
    192                 StringPrintf("Path %s is shady", path.c_str()));
    193     }
    194     for (const char& c : path) {
    195         if (c == '\0' || c == '\n') {
    196             return exception(binder::Status::EX_ILLEGAL_ARGUMENT,
    197                     StringPrintf("Path %s is malformed", path.c_str()));
    198         }
    199     }
    200     return ok();
    201 }
    202 
    203 binder::Status checkArgumentPath(const std::unique_ptr<std::string>& path) {
    204     if (path) {
    205         return checkArgumentPath(*path);
    206     } else {
    207         return ok();
    208     }
    209 }
    210 
    211 #define ENFORCE_UID(uid) {                                  \
    212     binder::Status status = checkUid((uid));                \
    213     if (!status.isOk()) {                                   \
    214         return status;                                      \
    215     }                                                       \
    216 }
    217 
    218 #define CHECK_ARGUMENT_UUID(uuid) {                         \
    219     binder::Status status = checkArgumentUuid((uuid));      \
    220     if (!status.isOk()) {                                   \
    221         return status;                                      \
    222     }                                                       \
    223 }
    224 
    225 #define CHECK_ARGUMENT_UUID_IS_TEST_OR_NULL(uuid) {         \
    226     auto status = checkArgumentUuidTestOrNull(uuid);        \
    227     if (!status.isOk()) {                                   \
    228         return status;                                      \
    229     }                                                       \
    230 }                                                           \
    231 
    232 #define CHECK_ARGUMENT_PACKAGE_NAME(packageName) {          \
    233     binder::Status status =                                 \
    234             checkArgumentPackageName((packageName));        \
    235     if (!status.isOk()) {                                   \
    236         return status;                                      \
    237     }                                                       \
    238 }
    239 
    240 #define CHECK_ARGUMENT_PATH(path) {                         \
    241     binder::Status status = checkArgumentPath((path));      \
    242     if (!status.isOk()) {                                   \
    243         return status;                                      \
    244     }                                                       \
    245 }
    246 
    247 #define ASSERT_PAGE_SIZE_4K() {                             \
    248     if (getpagesize() != kVerityPageSize) {                 \
    249         return error("FSVerity only supports 4K pages");     \
    250     }                                                       \
    251 }
    252 
    253 }  // namespace
    254 
    255 status_t InstalldNativeService::start() {
    256     IPCThreadState::self()->disableBackgroundScheduling(true);
    257     status_t ret = BinderService<InstalldNativeService>::publish();
    258     if (ret != android::OK) {
    259         return ret;
    260     }
    261     sp<ProcessState> ps(ProcessState::self());
    262     ps->startThreadPool();
    263     ps->giveThreadPoolName();
    264     return android::OK;
    265 }
    266 
    267 status_t InstalldNativeService::dump(int fd, const Vector<String16> & /* args */) {
    268     auto out = std::fstream(StringPrintf("/proc/self/fd/%d", fd));
    269     const binder::Status dump_permission = checkPermission(kDump);
    270     if (!dump_permission.isOk()) {
    271         out << dump_permission.toString8() << endl;
    272         return PERMISSION_DENIED;
    273     }
    274     std::lock_guard<std::recursive_mutex> lock(mLock);
    275 
    276     out << "installd is happy!" << endl;
    277 
    278     {
    279         std::lock_guard<std::recursive_mutex> lock(mMountsLock);
    280         out << endl << "Storage mounts:" << endl;
    281         for (const auto& n : mStorageMounts) {
    282             out << "    " << n.first << " = " << n.second << endl;
    283         }
    284     }
    285 
    286     {
    287         std::lock_guard<std::recursive_mutex> lock(mQuotasLock);
    288         out << endl << "Per-UID cache quotas:" << endl;
    289         for (const auto& n : mCacheQuotas) {
    290             out << "    " << n.first << " = " << n.second << endl;
    291         }
    292     }
    293 
    294     out << endl;
    295     out.flush();
    296 
    297     return NO_ERROR;
    298 }
    299 
    300 /**
    301  * Perform restorecon of the given path, but only perform recursive restorecon
    302  * if the label of that top-level file actually changed.  This can save us
    303  * significant time by avoiding no-op traversals of large filesystem trees.
    304  */
    305 static int restorecon_app_data_lazy(const std::string& path, const std::string& seInfo, uid_t uid,
    306         bool existing) {
    307     int res = 0;
    308     char* before = nullptr;
    309     char* after = nullptr;
    310 
    311     // Note that SELINUX_ANDROID_RESTORECON_DATADATA flag is set by
    312     // libselinux. Not needed here.
    313 
    314     if (lgetfilecon(path.c_str(), &before) < 0) {
    315         PLOG(ERROR) << "Failed before getfilecon for " << path;
    316         goto fail;
    317     }
    318     if (selinux_android_restorecon_pkgdir(path.c_str(), seInfo.c_str(), uid, 0) < 0) {
    319         PLOG(ERROR) << "Failed top-level restorecon for " << path;
    320         goto fail;
    321     }
    322     if (lgetfilecon(path.c_str(), &after) < 0) {
    323         PLOG(ERROR) << "Failed after getfilecon for " << path;
    324         goto fail;
    325     }
    326 
    327     // If the initial top-level restorecon above changed the label, then go
    328     // back and restorecon everything recursively
    329     if (strcmp(before, after)) {
    330         if (existing) {
    331             LOG(DEBUG) << "Detected label change from " << before << " to " << after << " at "
    332                     << path << "; running recursive restorecon";
    333         }
    334         if (selinux_android_restorecon_pkgdir(path.c_str(), seInfo.c_str(), uid,
    335                 SELINUX_ANDROID_RESTORECON_RECURSE) < 0) {
    336             PLOG(ERROR) << "Failed recursive restorecon for " << path;
    337             goto fail;
    338         }
    339     }
    340 
    341     goto done;
    342 fail:
    343     res = -1;
    344 done:
    345     free(before);
    346     free(after);
    347     return res;
    348 }
    349 
    350 static int restorecon_app_data_lazy(const std::string& parent, const char* name,
    351         const std::string& seInfo, uid_t uid, bool existing) {
    352     return restorecon_app_data_lazy(StringPrintf("%s/%s", parent.c_str(), name), seInfo, uid,
    353             existing);
    354 }
    355 
    356 static int prepare_app_dir(const std::string& path, mode_t target_mode, uid_t uid) {
    357     if (fs_prepare_dir_strict(path.c_str(), target_mode, uid, uid) != 0) {
    358         PLOG(ERROR) << "Failed to prepare " << path;
    359         return -1;
    360     }
    361     return 0;
    362 }
    363 
    364 static bool prepare_app_profile_dir(const std::string& packageName, int32_t appId, int32_t userId) {
    365     if (!property_get_bool("dalvik.vm.usejitprofiles", false)) {
    366         return true;
    367     }
    368 
    369     int32_t uid = multiuser_get_uid(userId, appId);
    370     int shared_app_gid = multiuser_get_shared_gid(userId, appId);
    371     if (shared_app_gid == -1) {
    372         // TODO(calin): this should no longer be possible but do not continue if we don't get
    373         // a valid shared gid.
    374         PLOG(WARNING) << "Invalid shared_app_gid for " << packageName;
    375         return true;
    376     }
    377 
    378     const std::string profile_dir =
    379             create_primary_current_profile_package_dir_path(userId, packageName);
    380     // read-write-execute only for the app user.
    381     if (fs_prepare_dir_strict(profile_dir.c_str(), 0700, uid, uid) != 0) {
    382         PLOG(ERROR) << "Failed to prepare " << profile_dir;
    383         return false;
    384     }
    385 
    386     const std::string ref_profile_path =
    387             create_primary_reference_profile_package_dir_path(packageName);
    388 
    389     // Prepare the reference profile directory. Note that we use the non strict version of
    390     // fs_prepare_dir. This will fix the permission and the ownership to the correct values.
    391     // This is particularly important given that in O there were some fixes for how the
    392     // shared_app_gid is computed.
    393     //
    394     // Note that by the time we get here we know that we are using a correct uid (otherwise
    395     // prepare_app_dir and the above fs_prepare_file_strict which check the uid). So we
    396     // are sure that the gid being used belongs to the owning app and not someone else.
    397     //
    398     // dex2oat/profman runs under the shared app gid and it needs to read/write reference profiles.
    399     if (fs_prepare_dir(ref_profile_path.c_str(), 0770, AID_SYSTEM, shared_app_gid) != 0) {
    400         PLOG(ERROR) << "Failed to prepare " << ref_profile_path;
    401         return false;
    402     }
    403 
    404     return true;
    405 }
    406 
    407 binder::Status InstalldNativeService::createAppData(const std::unique_ptr<std::string>& uuid,
    408         const std::string& packageName, int32_t userId, int32_t flags, int32_t appId,
    409         const std::string& seInfo, int32_t targetSdkVersion, int64_t* _aidl_return) {
    410     ENFORCE_UID(AID_SYSTEM);
    411     CHECK_ARGUMENT_UUID(uuid);
    412     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
    413     std::lock_guard<std::recursive_mutex> lock(mLock);
    414 
    415     const char* uuid_ = uuid ? uuid->c_str() : nullptr;
    416     const char* pkgname = packageName.c_str();
    417 
    418     // Assume invalid inode unless filled in below
    419     if (_aidl_return != nullptr) *_aidl_return = -1;
    420 
    421     int32_t uid = multiuser_get_uid(userId, appId);
    422     int32_t cacheGid = multiuser_get_cache_gid(userId, appId);
    423     mode_t targetMode = targetSdkVersion >= MIN_RESTRICTED_HOME_SDK_VERSION ? 0700 : 0751;
    424 
    425     // If UID doesn't have a specific cache GID, use UID value
    426     if (cacheGid == -1) {
    427         cacheGid = uid;
    428     }
    429 
    430     if (flags & FLAG_STORAGE_CE) {
    431         auto path = create_data_user_ce_package_path(uuid_, userId, pkgname);
    432         bool existing = (access(path.c_str(), F_OK) == 0);
    433 
    434         if (prepare_app_dir(path, targetMode, uid) ||
    435                 prepare_app_cache_dir(path, "cache", 02771, uid, cacheGid) ||
    436                 prepare_app_cache_dir(path, "code_cache", 02771, uid, cacheGid)) {
    437             return error("Failed to prepare " + path);
    438         }
    439 
    440         // Consider restorecon over contents if label changed
    441         if (restorecon_app_data_lazy(path, seInfo, uid, existing) ||
    442                 restorecon_app_data_lazy(path, "cache", seInfo, uid, existing) ||
    443                 restorecon_app_data_lazy(path, "code_cache", seInfo, uid, existing)) {
    444             return error("Failed to restorecon " + path);
    445         }
    446 
    447         // Remember inode numbers of cache directories so that we can clear
    448         // contents while CE storage is locked
    449         if (write_path_inode(path, "cache", kXattrInodeCache) ||
    450                 write_path_inode(path, "code_cache", kXattrInodeCodeCache)) {
    451             return error("Failed to write_path_inode for " + path);
    452         }
    453 
    454         // And return the CE inode of the top-level data directory so we can
    455         // clear contents while CE storage is locked
    456         if ((_aidl_return != nullptr)
    457                 && get_path_inode(path, reinterpret_cast<ino_t*>(_aidl_return)) != 0) {
    458             return error("Failed to get_path_inode for " + path);
    459         }
    460     }
    461     if (flags & FLAG_STORAGE_DE) {
    462         auto path = create_data_user_de_package_path(uuid_, userId, pkgname);
    463         bool existing = (access(path.c_str(), F_OK) == 0);
    464 
    465         if (prepare_app_dir(path, targetMode, uid) ||
    466                 prepare_app_cache_dir(path, "cache", 02771, uid, cacheGid) ||
    467                 prepare_app_cache_dir(path, "code_cache", 02771, uid, cacheGid)) {
    468             return error("Failed to prepare " + path);
    469         }
    470 
    471         // Consider restorecon over contents if label changed
    472         if (restorecon_app_data_lazy(path, seInfo, uid, existing) ||
    473                 restorecon_app_data_lazy(path, "cache", seInfo, uid, existing) ||
    474                 restorecon_app_data_lazy(path, "code_cache", seInfo, uid, existing)) {
    475             return error("Failed to restorecon " + path);
    476         }
    477 
    478         if (!prepare_app_profile_dir(packageName, appId, userId)) {
    479             return error("Failed to prepare profiles for " + packageName);
    480         }
    481     }
    482     return ok();
    483 }
    484 
    485 binder::Status InstalldNativeService::migrateAppData(const std::unique_ptr<std::string>& uuid,
    486         const std::string& packageName, int32_t userId, int32_t flags) {
    487     ENFORCE_UID(AID_SYSTEM);
    488     CHECK_ARGUMENT_UUID(uuid);
    489     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
    490     std::lock_guard<std::recursive_mutex> lock(mLock);
    491 
    492     const char* uuid_ = uuid ? uuid->c_str() : nullptr;
    493     const char* pkgname = packageName.c_str();
    494 
    495     // This method only exists to upgrade system apps that have requested
    496     // forceDeviceEncrypted, so their default storage always lives in a
    497     // consistent location.  This only works on non-FBE devices, since we
    498     // never want to risk exposing data on a device with real CE/DE storage.
    499 
    500     auto ce_path = create_data_user_ce_package_path(uuid_, userId, pkgname);
    501     auto de_path = create_data_user_de_package_path(uuid_, userId, pkgname);
    502 
    503     // If neither directory is marked as default, assume CE is default
    504     if (getxattr(ce_path.c_str(), kXattrDefault, nullptr, 0) == -1
    505             && getxattr(de_path.c_str(), kXattrDefault, nullptr, 0) == -1) {
    506         if (setxattr(ce_path.c_str(), kXattrDefault, nullptr, 0, 0) != 0) {
    507             return error("Failed to mark default storage " + ce_path);
    508         }
    509     }
    510 
    511     // Migrate default data location if needed
    512     auto target = (flags & FLAG_STORAGE_DE) ? de_path : ce_path;
    513     auto source = (flags & FLAG_STORAGE_DE) ? ce_path : de_path;
    514 
    515     if (getxattr(target.c_str(), kXattrDefault, nullptr, 0) == -1) {
    516         LOG(WARNING) << "Requested default storage " << target
    517                 << " is not active; migrating from " << source;
    518         if (delete_dir_contents_and_dir(target) != 0) {
    519             return error("Failed to delete " + target);
    520         }
    521         if (rename(source.c_str(), target.c_str()) != 0) {
    522             return error("Failed to rename " + source + " to " + target);
    523         }
    524     }
    525 
    526     return ok();
    527 }
    528 
    529 
    530 binder::Status InstalldNativeService::clearAppProfiles(const std::string& packageName,
    531         const std::string& profileName) {
    532     ENFORCE_UID(AID_SYSTEM);
    533     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
    534     std::lock_guard<std::recursive_mutex> lock(mLock);
    535 
    536     binder::Status res = ok();
    537     if (!clear_primary_reference_profile(packageName, profileName)) {
    538         res = error("Failed to clear reference profile for " + packageName);
    539     }
    540     if (!clear_primary_current_profiles(packageName, profileName)) {
    541         res = error("Failed to clear current profiles for " + packageName);
    542     }
    543     return res;
    544 }
    545 
    546 binder::Status InstalldNativeService::clearAppData(const std::unique_ptr<std::string>& uuid,
    547         const std::string& packageName, int32_t userId, int32_t flags, int64_t ceDataInode) {
    548     ENFORCE_UID(AID_SYSTEM);
    549     CHECK_ARGUMENT_UUID(uuid);
    550     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
    551     std::lock_guard<std::recursive_mutex> lock(mLock);
    552 
    553     const char* uuid_ = uuid ? uuid->c_str() : nullptr;
    554     const char* pkgname = packageName.c_str();
    555 
    556     binder::Status res = ok();
    557     if (flags & FLAG_STORAGE_CE) {
    558         auto path = create_data_user_ce_package_path(uuid_, userId, pkgname, ceDataInode);
    559         if (flags & FLAG_CLEAR_CACHE_ONLY) {
    560             path = read_path_inode(path, "cache", kXattrInodeCache);
    561         } else if (flags & FLAG_CLEAR_CODE_CACHE_ONLY) {
    562             path = read_path_inode(path, "code_cache", kXattrInodeCodeCache);
    563         }
    564         if (access(path.c_str(), F_OK) == 0) {
    565             if (delete_dir_contents(path) != 0) {
    566                 res = error("Failed to delete contents of " + path);
    567             } else if ((flags & (FLAG_CLEAR_CACHE_ONLY | FLAG_CLEAR_CODE_CACHE_ONLY)) == 0) {
    568                 remove_path_xattr(path, kXattrInodeCache);
    569                 remove_path_xattr(path, kXattrInodeCodeCache);
    570             }
    571         }
    572     }
    573     if (flags & FLAG_STORAGE_DE) {
    574         std::string suffix = "";
    575         bool only_cache = false;
    576         if (flags & FLAG_CLEAR_CACHE_ONLY) {
    577             suffix = CACHE_DIR_POSTFIX;
    578             only_cache = true;
    579         } else if (flags & FLAG_CLEAR_CODE_CACHE_ONLY) {
    580             suffix = CODE_CACHE_DIR_POSTFIX;
    581             only_cache = true;
    582         }
    583 
    584         auto path = create_data_user_de_package_path(uuid_, userId, pkgname) + suffix;
    585         if (access(path.c_str(), F_OK) == 0) {
    586             if (delete_dir_contents(path) != 0) {
    587                 res = error("Failed to delete contents of " + path);
    588             }
    589         }
    590     }
    591     if (flags & FLAG_STORAGE_EXTERNAL) {
    592         std::lock_guard<std::recursive_mutex> lock(mMountsLock);
    593         for (const auto& n : mStorageMounts) {
    594             auto extPath = n.second;
    595             if (n.first.compare(0, 14, "/mnt/media_rw/") != 0) {
    596                 extPath += StringPrintf("/%d", userId);
    597             } else if (userId != 0) {
    598                 // TODO: support devices mounted under secondary users
    599                 continue;
    600             }
    601             if (flags & FLAG_CLEAR_CACHE_ONLY) {
    602                 // Clear only cached data from shared storage
    603                 auto path = StringPrintf("%s/Android/data/%s/cache", extPath.c_str(), pkgname);
    604                 if (delete_dir_contents(path, true) != 0) {
    605                     res = error("Failed to delete contents of " + path);
    606                 }
    607             } else if (flags & FLAG_CLEAR_CODE_CACHE_ONLY) {
    608                 // No code cache on shared storage
    609             } else {
    610                 // Clear everything on shared storage
    611                 auto path = StringPrintf("%s/Android/data/%s", extPath.c_str(), pkgname);
    612                 if (delete_dir_contents(path, true) != 0) {
    613                     res = error("Failed to delete contents of " + path);
    614                 }
    615                 path = StringPrintf("%s/Android/media/%s", extPath.c_str(), pkgname);
    616                 if (delete_dir_contents(path, true) != 0) {
    617                     res = error("Failed to delete contents of " + path);
    618                 }
    619                 path = StringPrintf("%s/Android/obb/%s", extPath.c_str(), pkgname);
    620                 if (delete_dir_contents(path, true) != 0) {
    621                     res = error("Failed to delete contents of " + path);
    622                 }
    623             }
    624         }
    625     }
    626     return res;
    627 }
    628 
    629 static int destroy_app_reference_profile(const std::string& pkgname) {
    630     return delete_dir_contents_and_dir(
    631         create_primary_reference_profile_package_dir_path(pkgname),
    632         /*ignore_if_missing*/ true);
    633 }
    634 
    635 static int destroy_app_current_profiles(const std::string& pkgname, userid_t userid) {
    636     return delete_dir_contents_and_dir(
    637         create_primary_current_profile_package_dir_path(userid, pkgname),
    638         /*ignore_if_missing*/ true);
    639 }
    640 
    641 binder::Status InstalldNativeService::destroyAppProfiles(const std::string& packageName) {
    642     ENFORCE_UID(AID_SYSTEM);
    643     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
    644     std::lock_guard<std::recursive_mutex> lock(mLock);
    645 
    646     binder::Status res = ok();
    647     std::vector<userid_t> users = get_known_users(/*volume_uuid*/ nullptr);
    648     for (auto user : users) {
    649         if (destroy_app_current_profiles(packageName, user) != 0) {
    650             res = error("Failed to destroy current profiles for " + packageName);
    651         }
    652     }
    653     if (destroy_app_reference_profile(packageName) != 0) {
    654         res = error("Failed to destroy reference profile for " + packageName);
    655     }
    656     return res;
    657 }
    658 
    659 binder::Status InstalldNativeService::destroyAppData(const std::unique_ptr<std::string>& uuid,
    660         const std::string& packageName, int32_t userId, int32_t flags, int64_t ceDataInode) {
    661     ENFORCE_UID(AID_SYSTEM);
    662     CHECK_ARGUMENT_UUID(uuid);
    663     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
    664     std::lock_guard<std::recursive_mutex> lock(mLock);
    665 
    666     const char* uuid_ = uuid ? uuid->c_str() : nullptr;
    667     const char* pkgname = packageName.c_str();
    668 
    669     binder::Status res = ok();
    670     if (flags & FLAG_STORAGE_CE) {
    671         auto path = create_data_user_ce_package_path(uuid_, userId, pkgname, ceDataInode);
    672         if (delete_dir_contents_and_dir(path) != 0) {
    673             res = error("Failed to delete " + path);
    674         }
    675     }
    676     if (flags & FLAG_STORAGE_DE) {
    677         auto path = create_data_user_de_package_path(uuid_, userId, pkgname);
    678         if (delete_dir_contents_and_dir(path) != 0) {
    679             res = error("Failed to delete " + path);
    680         }
    681         destroy_app_current_profiles(packageName, userId);
    682         // TODO(calin): If the package is still installed by other users it's probably
    683         // beneficial to keep the reference profile around.
    684         // Verify if it's ok to do that.
    685         destroy_app_reference_profile(packageName);
    686     }
    687     if (flags & FLAG_STORAGE_EXTERNAL) {
    688         std::lock_guard<std::recursive_mutex> lock(mMountsLock);
    689         for (const auto& n : mStorageMounts) {
    690             auto extPath = n.second;
    691             if (n.first.compare(0, 14, "/mnt/media_rw/") != 0) {
    692                 extPath += StringPrintf("/%d", userId);
    693             } else if (userId != 0) {
    694                 // TODO: support devices mounted under secondary users
    695                 continue;
    696             }
    697             auto path = StringPrintf("%s/Android/data/%s", extPath.c_str(), pkgname);
    698             if (delete_dir_contents_and_dir(path, true) != 0) {
    699                 res = error("Failed to delete contents of " + path);
    700             }
    701             path = StringPrintf("%s/Android/media/%s", extPath.c_str(), pkgname);
    702             if (delete_dir_contents_and_dir(path, true) != 0) {
    703                 res = error("Failed to delete contents of " + path);
    704             }
    705             path = StringPrintf("%s/Android/obb/%s", extPath.c_str(), pkgname);
    706             if (delete_dir_contents_and_dir(path, true) != 0) {
    707                 res = error("Failed to delete contents of " + path);
    708             }
    709         }
    710     }
    711     return res;
    712 }
    713 
    714 static gid_t get_cache_gid(uid_t uid) {
    715     int32_t gid = multiuser_get_cache_gid(multiuser_get_user_id(uid), multiuser_get_app_id(uid));
    716     return (gid != -1) ? gid : uid;
    717 }
    718 
    719 binder::Status InstalldNativeService::fixupAppData(const std::unique_ptr<std::string>& uuid,
    720         int32_t flags) {
    721     ENFORCE_UID(AID_SYSTEM);
    722     CHECK_ARGUMENT_UUID(uuid);
    723     std::lock_guard<std::recursive_mutex> lock(mLock);
    724 
    725     const char* uuid_ = uuid ? uuid->c_str() : nullptr;
    726     for (auto user : get_known_users(uuid_)) {
    727         ATRACE_BEGIN("fixup user");
    728         FTS* fts;
    729         FTSENT* p;
    730         auto ce_path = create_data_user_ce_path(uuid_, user);
    731         auto de_path = create_data_user_de_path(uuid_, user);
    732         char *argv[] = { (char*) ce_path.c_str(), (char*) de_path.c_str(), nullptr };
    733         if (!(fts = fts_open(argv, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, nullptr))) {
    734             return error("Failed to fts_open");
    735         }
    736         while ((p = fts_read(fts)) != nullptr) {
    737             if (p->fts_info == FTS_D && p->fts_level == 1) {
    738                 // Track down inodes of cache directories
    739                 uint64_t raw = 0;
    740                 ino_t inode_cache = 0;
    741                 ino_t inode_code_cache = 0;
    742                 if (getxattr(p->fts_path, kXattrInodeCache, &raw, sizeof(raw)) == sizeof(raw)) {
    743                     inode_cache = raw;
    744                 }
    745                 if (getxattr(p->fts_path, kXattrInodeCodeCache, &raw, sizeof(raw)) == sizeof(raw)) {
    746                     inode_code_cache = raw;
    747                 }
    748 
    749                 // Figure out expected GID of each child
    750                 FTSENT* child = fts_children(fts, 0);
    751                 while (child != nullptr) {
    752                     if ((child->fts_statp->st_ino == inode_cache)
    753                             || (child->fts_statp->st_ino == inode_code_cache)
    754                             || !strcmp(child->fts_name, "cache")
    755                             || !strcmp(child->fts_name, "code_cache")) {
    756                         child->fts_number = get_cache_gid(p->fts_statp->st_uid);
    757                     } else {
    758                         child->fts_number = p->fts_statp->st_uid;
    759                     }
    760                     child = child->fts_link;
    761                 }
    762             } else if (p->fts_level >= 2) {
    763                 if (p->fts_level > 2) {
    764                     // Inherit GID from parent once we're deeper into tree
    765                     p->fts_number = p->fts_parent->fts_number;
    766                 }
    767 
    768                 uid_t uid = p->fts_parent->fts_statp->st_uid;
    769                 gid_t cache_gid = get_cache_gid(uid);
    770                 gid_t expected = p->fts_number;
    771                 gid_t actual = p->fts_statp->st_gid;
    772                 if (actual == expected) {
    773 #if FIXUP_DEBUG
    774                     LOG(DEBUG) << "Ignoring " << p->fts_path << " with expected GID " << expected;
    775 #endif
    776                     if (!(flags & FLAG_FORCE)) {
    777                         fts_set(fts, p, FTS_SKIP);
    778                     }
    779                 } else if ((actual == uid) || (actual == cache_gid)) {
    780                     // Only consider fixing up when current GID belongs to app
    781                     if (p->fts_info != FTS_D) {
    782                         LOG(INFO) << "Fixing " << p->fts_path << " with unexpected GID " << actual
    783                                 << " instead of " << expected;
    784                     }
    785                     switch (p->fts_info) {
    786                     case FTS_DP:
    787                         // If we're moving towards cache GID, we need to set S_ISGID
    788                         if (expected == cache_gid) {
    789                             if (chmod(p->fts_path, 02771) != 0) {
    790                                 PLOG(WARNING) << "Failed to chmod " << p->fts_path;
    791                             }
    792                         }
    793                         [[fallthrough]]; // also set GID
    794                     case FTS_F:
    795                         if (chown(p->fts_path, -1, expected) != 0) {
    796                             PLOG(WARNING) << "Failed to chown " << p->fts_path;
    797                         }
    798                         break;
    799                     case FTS_SL:
    800                     case FTS_SLNONE:
    801                         if (lchown(p->fts_path, -1, expected) != 0) {
    802                             PLOG(WARNING) << "Failed to chown " << p->fts_path;
    803                         }
    804                         break;
    805                     }
    806                 } else {
    807                     // Ignore all other GID transitions, since they're kinda shady
    808                     LOG(WARNING) << "Ignoring " << p->fts_path << " with unexpected GID " << actual
    809                             << " instead of " << expected;
    810                     if (!(flags & FLAG_FORCE)) {
    811                         fts_set(fts, p, FTS_SKIP);
    812                     }
    813                 }
    814             }
    815         }
    816         fts_close(fts);
    817         ATRACE_END();
    818     }
    819     return ok();
    820 }
    821 
    822 static int32_t copy_directory_recursive(const char* from, const char* to) {
    823     char *argv[] = {
    824         (char*) kCpPath,
    825         (char*) "-F", /* delete any existing destination file first (--remove-destination) */
    826         (char*) "-p", /* preserve timestamps, ownership, and permissions */
    827         (char*) "-R", /* recurse into subdirectories (DEST must be a directory) */
    828         (char*) "-P", /* Do not follow symlinks [default] */
    829         (char*) "-d", /* don't dereference symlinks */
    830         (char*) from,
    831         (char*) to
    832     };
    833 
    834     LOG(DEBUG) << "Copying " << from << " to " << to;
    835     return android_fork_execvp(ARRAY_SIZE(argv), argv, nullptr, false, true);
    836 }
    837 
    838 binder::Status InstalldNativeService::snapshotAppData(
    839         const std::unique_ptr<std::string>& volumeUuid,
    840         const std::string& packageName, int32_t user, int32_t snapshotId,
    841         int32_t storageFlags, int64_t* _aidl_return) {
    842     ENFORCE_UID(AID_SYSTEM);
    843     CHECK_ARGUMENT_UUID_IS_TEST_OR_NULL(volumeUuid);
    844     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
    845     std::lock_guard<std::recursive_mutex> lock(mLock);
    846 
    847     const char* volume_uuid = volumeUuid ? volumeUuid->c_str() : nullptr;
    848     const char* package_name = packageName.c_str();
    849 
    850     binder::Status res = ok();
    851     // Default result to 0, it will be populated with inode of ce data snapshot
    852     // if FLAG_STORAGE_CE has been passed.
    853     if (_aidl_return != nullptr) *_aidl_return = 0;
    854 
    855     bool clear_ce_on_exit = false;
    856     bool clear_de_on_exit = false;
    857 
    858     auto deleter = [&clear_ce_on_exit, &clear_de_on_exit, &volume_uuid, &user, &package_name,
    859             &snapshotId] {
    860         if (clear_de_on_exit) {
    861             auto to = create_data_misc_de_rollback_package_path(volume_uuid, user, snapshotId,
    862                     package_name);
    863             if (delete_dir_contents(to.c_str(), 1, nullptr) != 0) {
    864                 LOG(WARNING) << "Failed to delete app data snapshot: " << to;
    865             }
    866         }
    867 
    868         if (clear_ce_on_exit) {
    869             auto to = create_data_misc_ce_rollback_package_path(volume_uuid, user, snapshotId,
    870                     package_name);
    871             if (delete_dir_contents(to.c_str(), 1, nullptr) != 0) {
    872                 LOG(WARNING) << "Failed to delete app data snapshot: " << to;
    873             }
    874         }
    875     };
    876 
    877     auto scope_guard = android::base::make_scope_guard(deleter);
    878 
    879     // The app may not have any data at all, in which case it's OK to skip here.
    880     auto from_ce = create_data_user_ce_package_path(volume_uuid, user, package_name);
    881     if (access(from_ce.c_str(), F_OK) != 0) {
    882         LOG(INFO) << "Missing source " << from_ce;
    883         return ok();
    884     }
    885 
    886     // ce_data_inode is not needed when FLAG_CLEAR_CACHE_ONLY is set.
    887     binder::Status clear_cache_result = clearAppData(volumeUuid, packageName, user,
    888             storageFlags | FLAG_CLEAR_CACHE_ONLY, 0);
    889     if (!clear_cache_result.isOk()) {
    890         // It should be fine to continue snapshot if we for some reason failed
    891         // to clear cache.
    892         LOG(WARNING) << "Failed to clear cache of app " << packageName;
    893     }
    894 
    895     // ce_data_inode is not needed when FLAG_CLEAR_CODE_CACHE_ONLY is set.
    896     binder::Status clear_code_cache_result = clearAppData(volumeUuid, packageName, user,
    897             storageFlags | FLAG_CLEAR_CODE_CACHE_ONLY, 0);
    898     if (!clear_code_cache_result.isOk()) {
    899         // It should be fine to continue snapshot if we for some reason failed
    900         // to clear code_cache.
    901         LOG(WARNING) << "Failed to clear code_cache of app " << packageName;
    902     }
    903 
    904     if (storageFlags & FLAG_STORAGE_DE) {
    905         auto from = create_data_user_de_package_path(volume_uuid, user, package_name);
    906         auto to = create_data_misc_de_rollback_path(volume_uuid, user, snapshotId);
    907         auto rollback_package_path = create_data_misc_de_rollback_package_path(volume_uuid, user,
    908             snapshotId, package_name);
    909 
    910         int rc = create_dir_if_needed(to.c_str(), kRollbackFolderMode);
    911         if (rc != 0) {
    912             return error(rc, "Failed to create folder " + to);
    913         }
    914 
    915         rc = delete_dir_contents(rollback_package_path, true /* ignore_if_missing */);
    916         if (rc != 0) {
    917             return error(rc, "Failed clearing existing snapshot " + rollback_package_path);
    918         }
    919 
    920         rc = copy_directory_recursive(from.c_str(), to.c_str());
    921         if (rc != 0) {
    922             res = error(rc, "Failed copying " + from + " to " + to);
    923             clear_de_on_exit = true;
    924             return res;
    925         }
    926     }
    927 
    928     if (storageFlags & FLAG_STORAGE_CE) {
    929         auto from = create_data_user_ce_package_path(volume_uuid, user, package_name);
    930         auto to = create_data_misc_ce_rollback_path(volume_uuid, user, snapshotId);
    931         auto rollback_package_path = create_data_misc_ce_rollback_package_path(volume_uuid, user,
    932             snapshotId, package_name);
    933 
    934         int rc = create_dir_if_needed(to.c_str(), kRollbackFolderMode);
    935         if (rc != 0) {
    936             return error(rc, "Failed to create folder " + to);
    937         }
    938 
    939         rc = delete_dir_contents(rollback_package_path, true /* ignore_if_missing */);
    940         if (rc != 0) {
    941             return error(rc, "Failed clearing existing snapshot " + rollback_package_path);
    942         }
    943 
    944         rc = copy_directory_recursive(from.c_str(), to.c_str());
    945         if (rc != 0) {
    946             res = error(rc, "Failed copying " + from + " to " + to);
    947             clear_ce_on_exit = true;
    948             return res;
    949         }
    950         if (_aidl_return != nullptr) {
    951             auto ce_snapshot_path = create_data_misc_ce_rollback_package_path(volume_uuid, user,
    952                     snapshotId, package_name);
    953             rc = get_path_inode(ce_snapshot_path, reinterpret_cast<ino_t*>(_aidl_return));
    954             if (rc != 0) {
    955                 res = error(rc, "Failed to get_path_inode for " + ce_snapshot_path);
    956                 clear_ce_on_exit = true;
    957                 return res;
    958             }
    959         }
    960     }
    961 
    962     return res;
    963 }
    964 
    965 binder::Status InstalldNativeService::restoreAppDataSnapshot(
    966         const std::unique_ptr<std::string>& volumeUuid, const std::string& packageName,
    967         const int32_t appId, const std::string& seInfo, const int32_t user,
    968         const int32_t snapshotId, int32_t storageFlags) {
    969     ENFORCE_UID(AID_SYSTEM);
    970     CHECK_ARGUMENT_UUID_IS_TEST_OR_NULL(volumeUuid);
    971     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
    972     std::lock_guard<std::recursive_mutex> lock(mLock);
    973 
    974     const char* volume_uuid = volumeUuid ? volumeUuid->c_str() : nullptr;
    975     const char* package_name = packageName.c_str();
    976 
    977     auto from_ce = create_data_misc_ce_rollback_package_path(volume_uuid,
    978             user, snapshotId, package_name);
    979     auto from_de = create_data_misc_de_rollback_package_path(volume_uuid,
    980             user, snapshotId, package_name);
    981 
    982     const bool needs_ce_rollback = (storageFlags & FLAG_STORAGE_CE) &&
    983         (access(from_ce.c_str(), F_OK) == 0);
    984     const bool needs_de_rollback = (storageFlags & FLAG_STORAGE_DE) &&
    985         (access(from_de.c_str(), F_OK) == 0);
    986 
    987     if (!needs_ce_rollback && !needs_de_rollback) {
    988         return ok();
    989     }
    990 
    991     // We know we're going to rollback one of the CE or DE data, so we clear
    992     // application data first. Note that it's possible that we're asked to
    993     // restore both CE & DE data but that one of the restores fail. Leaving the
    994     // app with no data in those cases is arguably better than leaving the app
    995     // with mismatched / stale data.
    996     LOG(INFO) << "Clearing app data for " << packageName << " to restore snapshot.";
    997     // It's fine to pass 0 as ceDataInode here, because restoreAppDataSnapshot
    998     // can only be called when user unlocks the phone, meaning that CE user data
    999     // is decrypted.
   1000     binder::Status res = clearAppData(volumeUuid, packageName, user, storageFlags,
   1001             0 /* ceDataInode */);
   1002     if (!res.isOk()) {
   1003         return res;
   1004     }
   1005 
   1006     if (needs_ce_rollback) {
   1007         auto to_ce = create_data_user_ce_path(volume_uuid, user);
   1008         int rc = copy_directory_recursive(from_ce.c_str(), to_ce.c_str());
   1009         if (rc != 0) {
   1010             res = error(rc, "Failed copying " + from_ce + " to " + to_ce);
   1011             return res;
   1012         }
   1013     }
   1014 
   1015     if (needs_de_rollback) {
   1016         auto to_de = create_data_user_de_path(volume_uuid, user);
   1017         int rc = copy_directory_recursive(from_de.c_str(), to_de.c_str());
   1018         if (rc != 0) {
   1019             if (needs_ce_rollback) {
   1020                 auto ce_data = create_data_user_ce_package_path(volume_uuid, user, package_name);
   1021                 LOG(WARNING) << "de_data rollback failed. Erasing rolled back ce_data " << ce_data;
   1022                 if (delete_dir_contents(ce_data.c_str(), 1, nullptr) != 0) {
   1023                     LOG(WARNING) << "Failed to delete rolled back ce_data " << ce_data;
   1024                 }
   1025             }
   1026             res = error(rc, "Failed copying " + from_de + " to " + to_de);
   1027             return res;
   1028         }
   1029     }
   1030 
   1031     // Finally, restore the SELinux label on the app data.
   1032     return restoreconAppData(volumeUuid, packageName, user, storageFlags, appId, seInfo);
   1033 }
   1034 
   1035 binder::Status InstalldNativeService::destroyAppDataSnapshot(
   1036         const std::unique_ptr<std::string> &volumeUuid, const std::string& packageName,
   1037         const int32_t user, const int64_t ceSnapshotInode, const int32_t snapshotId,
   1038         int32_t storageFlags) {
   1039     ENFORCE_UID(AID_SYSTEM);
   1040     CHECK_ARGUMENT_UUID_IS_TEST_OR_NULL(volumeUuid);
   1041     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
   1042     std::lock_guard<std::recursive_mutex> lock(mLock);
   1043 
   1044     const char* volume_uuid = volumeUuid ? volumeUuid->c_str() : nullptr;
   1045     const char* package_name = packageName.c_str();
   1046 
   1047     if (storageFlags & FLAG_STORAGE_DE) {
   1048         auto de_snapshot_path = create_data_misc_de_rollback_package_path(volume_uuid,
   1049                 user, snapshotId, package_name);
   1050 
   1051         int res = delete_dir_contents_and_dir(de_snapshot_path, true /* ignore_if_missing */);
   1052         if (res != 0) {
   1053             return error(res, "Failed clearing snapshot " + de_snapshot_path);
   1054         }
   1055     }
   1056 
   1057     if (storageFlags & FLAG_STORAGE_CE) {
   1058         auto ce_snapshot_path = create_data_misc_ce_rollback_package_path(volume_uuid,
   1059                 user, snapshotId, package_name, ceSnapshotInode);
   1060         int res = delete_dir_contents_and_dir(ce_snapshot_path, true /* ignore_if_missing */);
   1061         if (res != 0) {
   1062             return error(res, "Failed clearing snapshot " + ce_snapshot_path);
   1063         }
   1064     }
   1065     return ok();
   1066 }
   1067 
   1068 
   1069 binder::Status InstalldNativeService::moveCompleteApp(const std::unique_ptr<std::string>& fromUuid,
   1070         const std::unique_ptr<std::string>& toUuid, const std::string& packageName,
   1071         const std::string& dataAppName, int32_t appId, const std::string& seInfo,
   1072         int32_t targetSdkVersion) {
   1073     ENFORCE_UID(AID_SYSTEM);
   1074     CHECK_ARGUMENT_UUID(fromUuid);
   1075     CHECK_ARGUMENT_UUID(toUuid);
   1076     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
   1077     std::lock_guard<std::recursive_mutex> lock(mLock);
   1078 
   1079     const char* from_uuid = fromUuid ? fromUuid->c_str() : nullptr;
   1080     const char* to_uuid = toUuid ? toUuid->c_str() : nullptr;
   1081     const char* package_name = packageName.c_str();
   1082     const char* data_app_name = dataAppName.c_str();
   1083 
   1084     binder::Status res = ok();
   1085     std::vector<userid_t> users = get_known_users(from_uuid);
   1086 
   1087     // Copy app
   1088     {
   1089         auto from = create_data_app_package_path(from_uuid, data_app_name);
   1090         auto to = create_data_app_package_path(to_uuid, data_app_name);
   1091         auto to_parent = create_data_app_path(to_uuid);
   1092 
   1093         int rc = copy_directory_recursive(from.c_str(), to_parent.c_str());
   1094         if (rc != 0) {
   1095             res = error(rc, "Failed copying " + from + " to " + to);
   1096             goto fail;
   1097         }
   1098 
   1099         if (selinux_android_restorecon(to.c_str(), SELINUX_ANDROID_RESTORECON_RECURSE) != 0) {
   1100             res = error("Failed to restorecon " + to);
   1101             goto fail;
   1102         }
   1103     }
   1104 
   1105     // Copy private data for all known users
   1106     for (auto user : users) {
   1107 
   1108         // Data source may not exist for all users; that's okay
   1109         auto from_ce = create_data_user_ce_package_path(from_uuid, user, package_name);
   1110         if (access(from_ce.c_str(), F_OK) != 0) {
   1111             LOG(INFO) << "Missing source " << from_ce;
   1112             continue;
   1113         }
   1114 
   1115         if (!createAppData(toUuid, packageName, user, FLAG_STORAGE_CE | FLAG_STORAGE_DE, appId,
   1116                 seInfo, targetSdkVersion, nullptr).isOk()) {
   1117             res = error("Failed to create package target");
   1118             goto fail;
   1119         }
   1120 
   1121         {
   1122             auto from = create_data_user_de_package_path(from_uuid, user, package_name);
   1123             auto to = create_data_user_de_path(to_uuid, user);
   1124 
   1125             int rc = copy_directory_recursive(from.c_str(), to.c_str());
   1126             if (rc != 0) {
   1127                 res = error(rc, "Failed copying " + from + " to " + to);
   1128                 goto fail;
   1129             }
   1130         }
   1131         {
   1132             auto from = create_data_user_ce_package_path(from_uuid, user, package_name);
   1133             auto to = create_data_user_ce_path(to_uuid, user);
   1134 
   1135             int rc = copy_directory_recursive(from.c_str(), to.c_str());
   1136             if (rc != 0) {
   1137                 res = error(rc, "Failed copying " + from + " to " + to);
   1138                 goto fail;
   1139             }
   1140         }
   1141 
   1142         if (!restoreconAppData(toUuid, packageName, user, FLAG_STORAGE_CE | FLAG_STORAGE_DE,
   1143                 appId, seInfo).isOk()) {
   1144             res = error("Failed to restorecon");
   1145             goto fail;
   1146         }
   1147     }
   1148 
   1149     // We let the framework scan the new location and persist that before
   1150     // deleting the data in the old location; this ordering ensures that
   1151     // we can recover from things like battery pulls.
   1152     return ok();
   1153 
   1154 fail:
   1155     // Nuke everything we might have already copied
   1156     {
   1157         auto to = create_data_app_package_path(to_uuid, data_app_name);
   1158         if (delete_dir_contents(to.c_str(), 1, nullptr) != 0) {
   1159             LOG(WARNING) << "Failed to rollback " << to;
   1160         }
   1161     }
   1162     for (auto user : users) {
   1163         {
   1164             auto to = create_data_user_de_package_path(to_uuid, user, package_name);
   1165             if (delete_dir_contents(to.c_str(), 1, nullptr) != 0) {
   1166                 LOG(WARNING) << "Failed to rollback " << to;
   1167             }
   1168         }
   1169         {
   1170             auto to = create_data_user_ce_package_path(to_uuid, user, package_name);
   1171             if (delete_dir_contents(to.c_str(), 1, nullptr) != 0) {
   1172                 LOG(WARNING) << "Failed to rollback " << to;
   1173             }
   1174         }
   1175     }
   1176     return res;
   1177 }
   1178 
   1179 binder::Status InstalldNativeService::createUserData(const std::unique_ptr<std::string>& uuid,
   1180         int32_t userId, int32_t userSerial ATTRIBUTE_UNUSED, int32_t flags) {
   1181     ENFORCE_UID(AID_SYSTEM);
   1182     CHECK_ARGUMENT_UUID(uuid);
   1183     std::lock_guard<std::recursive_mutex> lock(mLock);
   1184 
   1185     const char* uuid_ = uuid ? uuid->c_str() : nullptr;
   1186     if (flags & FLAG_STORAGE_DE) {
   1187         if (uuid_ == nullptr) {
   1188             if (ensure_config_user_dirs(userId) != 0) {
   1189                 return error(StringPrintf("Failed to ensure dirs for %d", userId));
   1190             }
   1191         }
   1192     }
   1193 
   1194     return ok();
   1195 }
   1196 
   1197 binder::Status InstalldNativeService::destroyUserData(const std::unique_ptr<std::string>& uuid,
   1198         int32_t userId, int32_t flags) {
   1199     ENFORCE_UID(AID_SYSTEM);
   1200     CHECK_ARGUMENT_UUID(uuid);
   1201     std::lock_guard<std::recursive_mutex> lock(mLock);
   1202 
   1203     const char* uuid_ = uuid ? uuid->c_str() : nullptr;
   1204     binder::Status res = ok();
   1205     if (flags & FLAG_STORAGE_DE) {
   1206         auto path = create_data_user_de_path(uuid_, userId);
   1207         if (delete_dir_contents_and_dir(path, true) != 0) {
   1208             res = error("Failed to delete " + path);
   1209         }
   1210         if (uuid_ == nullptr) {
   1211             path = create_data_misc_legacy_path(userId);
   1212             if (delete_dir_contents_and_dir(path, true) != 0) {
   1213                 res = error("Failed to delete " + path);
   1214             }
   1215             path = create_primary_cur_profile_dir_path(userId);
   1216             if (delete_dir_contents_and_dir(path, true) != 0) {
   1217                 res = error("Failed to delete " + path);
   1218             }
   1219         }
   1220     }
   1221     if (flags & FLAG_STORAGE_CE) {
   1222         auto path = create_data_user_ce_path(uuid_, userId);
   1223         if (delete_dir_contents_and_dir(path, true) != 0) {
   1224             res = error("Failed to delete " + path);
   1225         }
   1226         path = findDataMediaPath(uuid, userId);
   1227         if (delete_dir_contents_and_dir(path, true) != 0) {
   1228             res = error("Failed to delete " + path);
   1229         }
   1230     }
   1231     return res;
   1232 }
   1233 
   1234 binder::Status InstalldNativeService::freeCache(const std::unique_ptr<std::string>& uuid,
   1235         int64_t targetFreeBytes, int64_t cacheReservedBytes, int32_t flags) {
   1236     ENFORCE_UID(AID_SYSTEM);
   1237     CHECK_ARGUMENT_UUID(uuid);
   1238     std::lock_guard<std::recursive_mutex> lock(mLock);
   1239 
   1240     auto uuidString = uuid ? *uuid : "";
   1241     const char* uuid_ = uuid ? uuid->c_str() : nullptr;
   1242     auto data_path = create_data_path(uuid_);
   1243     auto noop = (flags & FLAG_FREE_CACHE_NOOP);
   1244 
   1245     int64_t free = data_disk_free(data_path);
   1246     if (free < 0) {
   1247         return error("Failed to determine free space for " + data_path);
   1248     }
   1249 
   1250     int64_t cleared = 0;
   1251     int64_t needed = targetFreeBytes - free;
   1252     LOG(DEBUG) << "Device " << data_path << " has " << free << " free; requested "
   1253             << targetFreeBytes << "; needed " << needed;
   1254 
   1255     if (free >= targetFreeBytes) {
   1256         return ok();
   1257     }
   1258 
   1259     if (flags & FLAG_FREE_CACHE_V2) {
   1260         // This new cache strategy fairly removes files from UIDs by deleting
   1261         // files from the UIDs which are most over their allocated quota
   1262 
   1263         // 1. Create trackers for every known UID
   1264         ATRACE_BEGIN("create");
   1265         std::unordered_map<uid_t, std::shared_ptr<CacheTracker>> trackers;
   1266         for (auto user : get_known_users(uuid_)) {
   1267             FTS *fts;
   1268             FTSENT *p;
   1269             auto ce_path = create_data_user_ce_path(uuid_, user);
   1270             auto de_path = create_data_user_de_path(uuid_, user);
   1271             auto media_path = findDataMediaPath(uuid, user) + "/Android/data/";
   1272             char *argv[] = { (char*) ce_path.c_str(), (char*) de_path.c_str(),
   1273                     (char*) media_path.c_str(), nullptr };
   1274             if (!(fts = fts_open(argv, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, nullptr))) {
   1275                 return error("Failed to fts_open");
   1276             }
   1277             while ((p = fts_read(fts)) != nullptr) {
   1278                 if (p->fts_info == FTS_D && p->fts_level == 1) {
   1279                     uid_t uid = p->fts_statp->st_uid;
   1280                     if (multiuser_get_app_id(uid) == AID_MEDIA_RW) {
   1281                         uid = (multiuser_get_app_id(p->fts_statp->st_gid) - AID_EXT_GID_START)
   1282                                 + AID_APP_START;
   1283                     }
   1284                     auto search = trackers.find(uid);
   1285                     if (search != trackers.end()) {
   1286                         search->second->addDataPath(p->fts_path);
   1287                     } else {
   1288                         auto tracker = std::shared_ptr<CacheTracker>(new CacheTracker(
   1289                                 multiuser_get_user_id(uid), multiuser_get_app_id(uid), uuidString));
   1290                         tracker->addDataPath(p->fts_path);
   1291                         {
   1292                             std::lock_guard<std::recursive_mutex> lock(mQuotasLock);
   1293                             tracker->cacheQuota = mCacheQuotas[uid];
   1294                         }
   1295                         if (tracker->cacheQuota == 0) {
   1296 #if MEASURE_DEBUG
   1297                             LOG(WARNING) << "UID " << uid << " has no cache quota; assuming 64MB";
   1298 #endif
   1299                             tracker->cacheQuota = 67108864;
   1300                         }
   1301                         trackers[uid] = tracker;
   1302                     }
   1303                     fts_set(fts, p, FTS_SKIP);
   1304                 }
   1305             }
   1306             fts_close(fts);
   1307         }
   1308         ATRACE_END();
   1309 
   1310         // 2. Populate tracker stats and insert into priority queue
   1311         ATRACE_BEGIN("populate");
   1312         int64_t cacheTotal = 0;
   1313         auto cmp = [](std::shared_ptr<CacheTracker> left, std::shared_ptr<CacheTracker> right) {
   1314             return (left->getCacheRatio() < right->getCacheRatio());
   1315         };
   1316         std::priority_queue<std::shared_ptr<CacheTracker>,
   1317                 std::vector<std::shared_ptr<CacheTracker>>, decltype(cmp)> queue(cmp);
   1318         for (const auto& it : trackers) {
   1319             it.second->loadStats();
   1320             queue.push(it.second);
   1321             cacheTotal += it.second->cacheUsed;
   1322         }
   1323         ATRACE_END();
   1324 
   1325         // 3. Bounce across the queue, freeing items from whichever tracker is
   1326         // the most over their assigned quota
   1327         ATRACE_BEGIN("bounce");
   1328         std::shared_ptr<CacheTracker> active;
   1329         while (active || !queue.empty()) {
   1330             // Only look at apps under quota when explicitly requested
   1331             if (active && (active->getCacheRatio() < 10000)
   1332                     && !(flags & FLAG_FREE_CACHE_V2_DEFY_QUOTA)) {
   1333                 LOG(DEBUG) << "Active ratio " << active->getCacheRatio()
   1334                         << " isn't over quota, and defy not requested";
   1335                 break;
   1336             }
   1337 
   1338             // Only keep clearing when we haven't pushed into reserved area
   1339             if (cacheReservedBytes > 0 && cleared >= (cacheTotal - cacheReservedBytes)) {
   1340                 LOG(DEBUG) << "Refusing to clear cached data in reserved space";
   1341                 break;
   1342             }
   1343 
   1344             // Find the best tracker to work with; this might involve swapping
   1345             // if the active tracker is no longer the most over quota
   1346             bool nextBetter = active && !queue.empty()
   1347                     && active->getCacheRatio() < queue.top()->getCacheRatio();
   1348             if (!active || nextBetter) {
   1349                 if (active) {
   1350                     // Current tracker still has items, so we'll consider it
   1351                     // again later once it bubbles up to surface
   1352                     queue.push(active);
   1353                 }
   1354                 active = queue.top(); queue.pop();
   1355                 active->ensureItems();
   1356                 continue;
   1357             }
   1358 
   1359             // If no items remain, go find another tracker
   1360             if (active->items.empty()) {
   1361                 active = nullptr;
   1362                 continue;
   1363             } else {
   1364                 auto item = active->items.back();
   1365                 active->items.pop_back();
   1366 
   1367                 LOG(DEBUG) << "Purging " << item->toString() << " from " << active->toString();
   1368                 if (!noop) {
   1369                     item->purge();
   1370                 }
   1371                 active->cacheUsed -= item->size;
   1372                 needed -= item->size;
   1373                 cleared += item->size;
   1374             }
   1375 
   1376             // Verify that we're actually done before bailing, since sneaky
   1377             // apps might be using hardlinks
   1378             if (needed <= 0) {
   1379                 free = data_disk_free(data_path);
   1380                 needed = targetFreeBytes - free;
   1381                 if (needed <= 0) {
   1382                     break;
   1383                 } else {
   1384                     LOG(WARNING) << "Expected to be done but still need " << needed;
   1385                 }
   1386             }
   1387         }
   1388         ATRACE_END();
   1389 
   1390     } else {
   1391         return error("Legacy cache logic no longer supported");
   1392     }
   1393 
   1394     free = data_disk_free(data_path);
   1395     if (free >= targetFreeBytes) {
   1396         return ok();
   1397     } else {
   1398         return error(StringPrintf("Failed to free up %" PRId64 " on %s; final free space %" PRId64,
   1399                 targetFreeBytes, data_path.c_str(), free));
   1400     }
   1401 }
   1402 
   1403 binder::Status InstalldNativeService::rmdex(const std::string& codePath,
   1404         const std::string& instructionSet) {
   1405     ENFORCE_UID(AID_SYSTEM);
   1406     CHECK_ARGUMENT_PATH(codePath);
   1407     std::lock_guard<std::recursive_mutex> lock(mLock);
   1408 
   1409     char dex_path[PKG_PATH_MAX];
   1410 
   1411     const char* path = codePath.c_str();
   1412     const char* instruction_set = instructionSet.c_str();
   1413 
   1414     if (validate_apk_path(path) && validate_system_app_path(path)) {
   1415         return error("Invalid path " + codePath);
   1416     }
   1417 
   1418     if (!create_cache_path(dex_path, path, instruction_set)) {
   1419         return error("Failed to create cache path for " + codePath);
   1420     }
   1421 
   1422     ALOGV("unlink %s\n", dex_path);
   1423     if (unlink(dex_path) < 0) {
   1424         // It's ok if we don't have a dalvik cache path. Report error only when the path exists
   1425         // but could not be unlinked.
   1426         if (errno != ENOENT) {
   1427             return error(StringPrintf("Failed to unlink %s", dex_path));
   1428         }
   1429     }
   1430     return ok();
   1431 }
   1432 
   1433 struct stats {
   1434     int64_t codeSize;
   1435     int64_t dataSize;
   1436     int64_t cacheSize;
   1437 };
   1438 
   1439 #if MEASURE_DEBUG
   1440 static std::string toString(std::vector<int64_t> values) {
   1441     std::stringstream res;
   1442     res << "[";
   1443     for (size_t i = 0; i < values.size(); i++) {
   1444         res << values[i];
   1445         if (i < values.size() - 1) {
   1446             res << ",";
   1447         }
   1448     }
   1449     res << "]";
   1450     return res.str();
   1451 }
   1452 #endif
   1453 
   1454 static void collectQuotaStats(const std::string& uuid, int32_t userId,
   1455         int32_t appId, struct stats* stats, struct stats* extStats) {
   1456     int64_t space;
   1457     if (stats != nullptr) {
   1458         uid_t uid = multiuser_get_uid(userId, appId);
   1459         if ((space = GetOccupiedSpaceForUid(uuid, uid)) != -1) {
   1460             stats->dataSize += space;
   1461         }
   1462 
   1463         int cacheGid = multiuser_get_cache_gid(userId, appId);
   1464         if (cacheGid != -1) {
   1465             if ((space = GetOccupiedSpaceForGid(uuid, cacheGid)) != -1) {
   1466                 stats->cacheSize += space;
   1467             }
   1468         }
   1469 
   1470         int sharedGid = multiuser_get_shared_gid(0, appId);
   1471         if (sharedGid != -1) {
   1472             if ((space = GetOccupiedSpaceForGid(uuid, sharedGid)) != -1) {
   1473                 stats->codeSize += space;
   1474             }
   1475         }
   1476     }
   1477 
   1478     if (extStats != nullptr) {
   1479         int extGid = multiuser_get_ext_gid(userId, appId);
   1480         if (extGid != -1) {
   1481             if ((space = GetOccupiedSpaceForGid(uuid, extGid)) != -1) {
   1482                 extStats->dataSize += space;
   1483             }
   1484         }
   1485 
   1486         int extCacheGid = multiuser_get_ext_cache_gid(userId, appId);
   1487         if (extCacheGid != -1) {
   1488             if ((space = GetOccupiedSpaceForGid(uuid, extCacheGid)) != -1) {
   1489                 extStats->dataSize += space;
   1490                 extStats->cacheSize += space;
   1491             }
   1492         }
   1493     }
   1494 }
   1495 
   1496 static void collectManualStats(const std::string& path, struct stats* stats) {
   1497     DIR *d;
   1498     int dfd;
   1499     struct dirent *de;
   1500     struct stat s;
   1501 
   1502     d = opendir(path.c_str());
   1503     if (d == nullptr) {
   1504         if (errno != ENOENT) {
   1505             PLOG(WARNING) << "Failed to open " << path;
   1506         }
   1507         return;
   1508     }
   1509     dfd = dirfd(d);
   1510     while ((de = readdir(d))) {
   1511         const char *name = de->d_name;
   1512 
   1513         int64_t size = 0;
   1514         if (fstatat(dfd, name, &s, AT_SYMLINK_NOFOLLOW) == 0) {
   1515             size = s.st_blocks * 512;
   1516         }
   1517 
   1518         if (de->d_type == DT_DIR) {
   1519             if (!strcmp(name, ".")) {
   1520                 // Don't recurse, but still count node size
   1521             } else if (!strcmp(name, "..")) {
   1522                 // Don't recurse or count node size
   1523                 continue;
   1524             } else {
   1525                 // Measure all children nodes
   1526                 size = 0;
   1527                 calculate_tree_size(StringPrintf("%s/%s", path.c_str(), name), &size);
   1528             }
   1529 
   1530             if (!strcmp(name, "cache") || !strcmp(name, "code_cache")) {
   1531                 stats->cacheSize += size;
   1532             }
   1533         }
   1534 
   1535         // Legacy symlink isn't owned by app
   1536         if (de->d_type == DT_LNK && !strcmp(name, "lib")) {
   1537             continue;
   1538         }
   1539 
   1540         // Everything found inside is considered data
   1541         stats->dataSize += size;
   1542     }
   1543     closedir(d);
   1544 }
   1545 
   1546 static void collectManualStatsForUser(const std::string& path, struct stats* stats,
   1547         bool exclude_apps = false) {
   1548     DIR *d;
   1549     int dfd;
   1550     struct dirent *de;
   1551     struct stat s;
   1552 
   1553     d = opendir(path.c_str());
   1554     if (d == nullptr) {
   1555         if (errno != ENOENT) {
   1556             PLOG(WARNING) << "Failed to open " << path;
   1557         }
   1558         return;
   1559     }
   1560     dfd = dirfd(d);
   1561     while ((de = readdir(d))) {
   1562         if (de->d_type == DT_DIR) {
   1563             const char *name = de->d_name;
   1564             if (fstatat(dfd, name, &s, AT_SYMLINK_NOFOLLOW) != 0) {
   1565                 continue;
   1566             }
   1567             int32_t user_uid = multiuser_get_app_id(s.st_uid);
   1568             if (!strcmp(name, ".") || !strcmp(name, "..")) {
   1569                 continue;
   1570             } else if (exclude_apps && (user_uid >= AID_APP_START && user_uid <= AID_APP_END)) {
   1571                 continue;
   1572             } else {
   1573                 collectManualStats(StringPrintf("%s/%s", path.c_str(), name), stats);
   1574             }
   1575         }
   1576     }
   1577     closedir(d);
   1578 }
   1579 
   1580 static void collectManualExternalStatsForUser(const std::string& path, struct stats* stats) {
   1581     FTS *fts;
   1582     FTSENT *p;
   1583     char *argv[] = { (char*) path.c_str(), nullptr };
   1584     if (!(fts = fts_open(argv, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, nullptr))) {
   1585         PLOG(ERROR) << "Failed to fts_open " << path;
   1586         return;
   1587     }
   1588     while ((p = fts_read(fts)) != nullptr) {
   1589         p->fts_number = p->fts_parent->fts_number;
   1590         switch (p->fts_info) {
   1591         case FTS_D:
   1592             if (p->fts_level == 4
   1593                     && !strcmp(p->fts_name, "cache")
   1594                     && !strcmp(p->fts_parent->fts_parent->fts_name, "data")
   1595                     && !strcmp(p->fts_parent->fts_parent->fts_parent->fts_name, "Android")) {
   1596                 p->fts_number = 1;
   1597             }
   1598             [[fallthrough]]; // to count the directory
   1599         case FTS_DEFAULT:
   1600         case FTS_F:
   1601         case FTS_SL:
   1602         case FTS_SLNONE:
   1603             int64_t size = (p->fts_statp->st_blocks * 512);
   1604             if (p->fts_number == 1) {
   1605                 stats->cacheSize += size;
   1606             }
   1607             stats->dataSize += size;
   1608             break;
   1609         }
   1610     }
   1611     fts_close(fts);
   1612 }
   1613 
   1614 binder::Status InstalldNativeService::getAppSize(const std::unique_ptr<std::string>& uuid,
   1615         const std::vector<std::string>& packageNames, int32_t userId, int32_t flags,
   1616         int32_t appId, const std::vector<int64_t>& ceDataInodes,
   1617         const std::vector<std::string>& codePaths, std::vector<int64_t>* _aidl_return) {
   1618     ENFORCE_UID(AID_SYSTEM);
   1619     CHECK_ARGUMENT_UUID(uuid);
   1620     for (const auto& packageName : packageNames) {
   1621         CHECK_ARGUMENT_PACKAGE_NAME(packageName);
   1622     }
   1623     for (const auto& codePath : codePaths) {
   1624         CHECK_ARGUMENT_PATH(codePath);
   1625     }
   1626     // NOTE: Locking is relaxed on this method, since it's limited to
   1627     // read-only measurements without mutation.
   1628 
   1629     // When modifying this logic, always verify using tests:
   1630     // runtest -x frameworks/base/services/tests/servicestests/src/com/android/server/pm/InstallerTest.java -m testGetAppSize
   1631 
   1632 #if MEASURE_DEBUG
   1633     LOG(INFO) << "Measuring user " << userId << " app " << appId;
   1634 #endif
   1635 
   1636     // Here's a summary of the common storage locations across the platform,
   1637     // and how they're each tagged:
   1638     //
   1639     // /data/app/com.example                           UID system
   1640     // /data/app/com.example/oat                       UID system
   1641     // /data/user/0/com.example                        UID u0_a10      GID u0_a10
   1642     // /data/user/0/com.example/cache                  UID u0_a10      GID u0_a10_cache
   1643     // /data/media/0/foo.txt                           UID u0_media_rw
   1644     // /data/media/0/bar.jpg                           UID u0_media_rw GID u0_media_image
   1645     // /data/media/0/Android/data/com.example          UID u0_media_rw GID u0_a10_ext
   1646     // /data/media/0/Android/data/com.example/cache    UID u0_media_rw GID u0_a10_ext_cache
   1647     // /data/media/obb/com.example                     UID system
   1648 
   1649     struct stats stats;
   1650     struct stats extStats;
   1651     memset(&stats, 0, sizeof(stats));
   1652     memset(&extStats, 0, sizeof(extStats));
   1653 
   1654     auto uuidString = uuid ? *uuid : "";
   1655     const char* uuid_ = uuid ? uuid->c_str() : nullptr;
   1656 
   1657     if (!IsQuotaSupported(uuidString)) {
   1658         flags &= ~FLAG_USE_QUOTA;
   1659     }
   1660 
   1661     ATRACE_BEGIN("obb");
   1662     for (const auto& packageName : packageNames) {
   1663         auto obbCodePath = create_data_media_package_path(uuid_, userId,
   1664                 "obb", packageName.c_str());
   1665         calculate_tree_size(obbCodePath, &extStats.codeSize);
   1666     }
   1667     ATRACE_END();
   1668 
   1669     if (flags & FLAG_USE_QUOTA && appId >= AID_APP_START) {
   1670         ATRACE_BEGIN("code");
   1671         for (const auto& codePath : codePaths) {
   1672             calculate_tree_size(codePath, &stats.codeSize, -1,
   1673                     multiuser_get_shared_gid(0, appId));
   1674         }
   1675         ATRACE_END();
   1676 
   1677         ATRACE_BEGIN("quota");
   1678         collectQuotaStats(uuidString, userId, appId, &stats, &extStats);
   1679         ATRACE_END();
   1680     } else {
   1681         ATRACE_BEGIN("code");
   1682         for (const auto& codePath : codePaths) {
   1683             calculate_tree_size(codePath, &stats.codeSize);
   1684         }
   1685         ATRACE_END();
   1686 
   1687         for (size_t i = 0; i < packageNames.size(); i++) {
   1688             const char* pkgname = packageNames[i].c_str();
   1689 
   1690             ATRACE_BEGIN("data");
   1691             auto cePath = create_data_user_ce_package_path(uuid_, userId, pkgname, ceDataInodes[i]);
   1692             collectManualStats(cePath, &stats);
   1693             auto dePath = create_data_user_de_package_path(uuid_, userId, pkgname);
   1694             collectManualStats(dePath, &stats);
   1695             ATRACE_END();
   1696 
   1697             if (!uuid) {
   1698                 ATRACE_BEGIN("profiles");
   1699                 calculate_tree_size(
   1700                         create_primary_current_profile_package_dir_path(userId, pkgname),
   1701                         &stats.dataSize);
   1702                 calculate_tree_size(
   1703                         create_primary_reference_profile_package_dir_path(pkgname),
   1704                         &stats.codeSize);
   1705                 ATRACE_END();
   1706             }
   1707 
   1708             ATRACE_BEGIN("external");
   1709             auto extPath = create_data_media_package_path(uuid_, userId, "data", pkgname);
   1710             collectManualStats(extPath, &extStats);
   1711             auto mediaPath = create_data_media_package_path(uuid_, userId, "media", pkgname);
   1712             calculate_tree_size(mediaPath, &extStats.dataSize);
   1713             ATRACE_END();
   1714         }
   1715 
   1716         if (!uuid) {
   1717             ATRACE_BEGIN("dalvik");
   1718             int32_t sharedGid = multiuser_get_shared_gid(0, appId);
   1719             if (sharedGid != -1) {
   1720                 calculate_tree_size(create_data_dalvik_cache_path(), &stats.codeSize,
   1721                         sharedGid, -1);
   1722             }
   1723             ATRACE_END();
   1724         }
   1725     }
   1726 
   1727     std::vector<int64_t> ret;
   1728     ret.push_back(stats.codeSize);
   1729     ret.push_back(stats.dataSize);
   1730     ret.push_back(stats.cacheSize);
   1731     ret.push_back(extStats.codeSize);
   1732     ret.push_back(extStats.dataSize);
   1733     ret.push_back(extStats.cacheSize);
   1734 #if MEASURE_DEBUG
   1735     LOG(DEBUG) << "Final result " << toString(ret);
   1736 #endif
   1737     *_aidl_return = ret;
   1738     return ok();
   1739 }
   1740 
   1741 binder::Status InstalldNativeService::getUserSize(const std::unique_ptr<std::string>& uuid,
   1742         int32_t userId, int32_t flags, const std::vector<int32_t>& appIds,
   1743         std::vector<int64_t>* _aidl_return) {
   1744     ENFORCE_UID(AID_SYSTEM);
   1745     CHECK_ARGUMENT_UUID(uuid);
   1746     // NOTE: Locking is relaxed on this method, since it's limited to
   1747     // read-only measurements without mutation.
   1748 
   1749     // When modifying this logic, always verify using tests:
   1750     // runtest -x frameworks/base/services/tests/servicestests/src/com/android/server/pm/InstallerTest.java -m testGetUserSize
   1751 
   1752 #if MEASURE_DEBUG
   1753     LOG(INFO) << "Measuring user " << userId;
   1754 #endif
   1755 
   1756     struct stats stats;
   1757     struct stats extStats;
   1758     memset(&stats, 0, sizeof(stats));
   1759     memset(&extStats, 0, sizeof(extStats));
   1760 
   1761     auto uuidString = uuid ? *uuid : "";
   1762     const char* uuid_ = uuid ? uuid->c_str() : nullptr;
   1763 
   1764     if (!IsQuotaSupported(uuidString)) {
   1765         flags &= ~FLAG_USE_QUOTA;
   1766     }
   1767 
   1768     if (flags & FLAG_USE_QUOTA) {
   1769         int64_t space;
   1770 
   1771         ATRACE_BEGIN("obb");
   1772         if ((space = GetOccupiedSpaceForGid(uuidString, AID_MEDIA_OBB)) != -1) {
   1773             extStats.codeSize += space;
   1774         }
   1775         ATRACE_END();
   1776 
   1777         ATRACE_BEGIN("code");
   1778         calculate_tree_size(create_data_app_path(uuid_), &stats.codeSize, -1, -1, true);
   1779         ATRACE_END();
   1780 
   1781         ATRACE_BEGIN("data");
   1782         auto cePath = create_data_user_ce_path(uuid_, userId);
   1783         collectManualStatsForUser(cePath, &stats, true);
   1784         auto dePath = create_data_user_de_path(uuid_, userId);
   1785         collectManualStatsForUser(dePath, &stats, true);
   1786         ATRACE_END();
   1787 
   1788         if (!uuid) {
   1789             ATRACE_BEGIN("profile");
   1790             auto userProfilePath = create_primary_cur_profile_dir_path(userId);
   1791             calculate_tree_size(userProfilePath, &stats.dataSize, -1, -1, true);
   1792             auto refProfilePath = create_primary_ref_profile_dir_path();
   1793             calculate_tree_size(refProfilePath, &stats.codeSize, -1, -1, true);
   1794             ATRACE_END();
   1795         }
   1796 
   1797         ATRACE_BEGIN("external");
   1798         uid_t uid = multiuser_get_uid(userId, AID_MEDIA_RW);
   1799         if ((space = GetOccupiedSpaceForUid(uuidString, uid)) != -1) {
   1800             extStats.dataSize += space;
   1801         }
   1802         ATRACE_END();
   1803 
   1804         if (!uuid) {
   1805             ATRACE_BEGIN("dalvik");
   1806             calculate_tree_size(create_data_dalvik_cache_path(), &stats.codeSize,
   1807                     -1, -1, true);
   1808             calculate_tree_size(create_primary_cur_profile_dir_path(userId), &stats.dataSize,
   1809                     -1, -1, true);
   1810             ATRACE_END();
   1811         }
   1812 
   1813         ATRACE_BEGIN("quota");
   1814         int64_t dataSize = extStats.dataSize;
   1815         for (auto appId : appIds) {
   1816             if (appId >= AID_APP_START) {
   1817                 collectQuotaStats(uuidString, userId, appId, &stats, &extStats);
   1818 
   1819 #if MEASURE_DEBUG
   1820                 // Sleep to make sure we don't lose logs
   1821                 usleep(1);
   1822 #endif
   1823             }
   1824         }
   1825         extStats.dataSize = dataSize;
   1826         ATRACE_END();
   1827     } else {
   1828         ATRACE_BEGIN("obb");
   1829         auto obbPath = create_data_path(uuid_) + "/media/obb";
   1830         calculate_tree_size(obbPath, &extStats.codeSize);
   1831         ATRACE_END();
   1832 
   1833         ATRACE_BEGIN("code");
   1834         calculate_tree_size(create_data_app_path(uuid_), &stats.codeSize);
   1835         ATRACE_END();
   1836 
   1837         ATRACE_BEGIN("data");
   1838         auto cePath = create_data_user_ce_path(uuid_, userId);
   1839         collectManualStatsForUser(cePath, &stats);
   1840         auto dePath = create_data_user_de_path(uuid_, userId);
   1841         collectManualStatsForUser(dePath, &stats);
   1842         ATRACE_END();
   1843 
   1844         if (!uuid) {
   1845             ATRACE_BEGIN("profile");
   1846             auto userProfilePath = create_primary_cur_profile_dir_path(userId);
   1847             calculate_tree_size(userProfilePath, &stats.dataSize);
   1848             auto refProfilePath = create_primary_ref_profile_dir_path();
   1849             calculate_tree_size(refProfilePath, &stats.codeSize);
   1850             ATRACE_END();
   1851         }
   1852 
   1853         ATRACE_BEGIN("external");
   1854         auto dataMediaPath = create_data_media_path(uuid_, userId);
   1855         collectManualExternalStatsForUser(dataMediaPath, &extStats);
   1856 #if MEASURE_DEBUG
   1857         LOG(DEBUG) << "Measured external data " << extStats.dataSize << " cache "
   1858                 << extStats.cacheSize;
   1859 #endif
   1860         ATRACE_END();
   1861 
   1862         if (!uuid) {
   1863             ATRACE_BEGIN("dalvik");
   1864             calculate_tree_size(create_data_dalvik_cache_path(), &stats.codeSize);
   1865             calculate_tree_size(create_primary_cur_profile_dir_path(userId), &stats.dataSize);
   1866             ATRACE_END();
   1867         }
   1868     }
   1869 
   1870     std::vector<int64_t> ret;
   1871     ret.push_back(stats.codeSize);
   1872     ret.push_back(stats.dataSize);
   1873     ret.push_back(stats.cacheSize);
   1874     ret.push_back(extStats.codeSize);
   1875     ret.push_back(extStats.dataSize);
   1876     ret.push_back(extStats.cacheSize);
   1877 #if MEASURE_DEBUG
   1878     LOG(DEBUG) << "Final result " << toString(ret);
   1879 #endif
   1880     *_aidl_return = ret;
   1881     return ok();
   1882 }
   1883 
   1884 binder::Status InstalldNativeService::getExternalSize(const std::unique_ptr<std::string>& uuid,
   1885         int32_t userId, int32_t flags, const std::vector<int32_t>& appIds,
   1886         std::vector<int64_t>* _aidl_return) {
   1887     ENFORCE_UID(AID_SYSTEM);
   1888     CHECK_ARGUMENT_UUID(uuid);
   1889     // NOTE: Locking is relaxed on this method, since it's limited to
   1890     // read-only measurements without mutation.
   1891 
   1892     // When modifying this logic, always verify using tests:
   1893     // runtest -x frameworks/base/services/tests/servicestests/src/com/android/server/pm/InstallerTest.java -m testGetExternalSize
   1894 
   1895 #if MEASURE_DEBUG
   1896     LOG(INFO) << "Measuring external " << userId;
   1897 #endif
   1898 
   1899     auto uuidString = uuid ? *uuid : "";
   1900     const char* uuid_ = uuid ? uuid->c_str() : nullptr;
   1901 
   1902     int64_t totalSize = 0;
   1903     int64_t audioSize = 0;
   1904     int64_t videoSize = 0;
   1905     int64_t imageSize = 0;
   1906     int64_t appSize = 0;
   1907     int64_t obbSize = 0;
   1908 
   1909     if (!IsQuotaSupported(uuidString)) {
   1910         flags &= ~FLAG_USE_QUOTA;
   1911     }
   1912 
   1913     if (flags & FLAG_USE_QUOTA) {
   1914         int64_t space;
   1915 
   1916         ATRACE_BEGIN("quota");
   1917         uid_t uid = multiuser_get_uid(userId, AID_MEDIA_RW);
   1918         if ((space = GetOccupiedSpaceForUid(uuidString, uid)) != -1) {
   1919             totalSize = space;
   1920         }
   1921 
   1922         gid_t audioGid = multiuser_get_uid(userId, AID_MEDIA_AUDIO);
   1923         if ((space = GetOccupiedSpaceForGid(uuidString, audioGid)) != -1) {
   1924             audioSize = space;
   1925         }
   1926         gid_t videoGid = multiuser_get_uid(userId, AID_MEDIA_VIDEO);
   1927         if ((space = GetOccupiedSpaceForGid(uuidString, videoGid)) != -1) {
   1928             videoSize = space;
   1929         }
   1930         gid_t imageGid = multiuser_get_uid(userId, AID_MEDIA_IMAGE);
   1931         if ((space = GetOccupiedSpaceForGid(uuidString, imageGid)) != -1) {
   1932             imageSize = space;
   1933         }
   1934         if ((space = GetOccupiedSpaceForGid(uuidString, AID_MEDIA_OBB)) != -1) {
   1935             obbSize = space;
   1936         }
   1937         ATRACE_END();
   1938 
   1939         ATRACE_BEGIN("apps");
   1940         struct stats extStats;
   1941         memset(&extStats, 0, sizeof(extStats));
   1942         for (auto appId : appIds) {
   1943             if (appId >= AID_APP_START) {
   1944                 collectQuotaStats(uuidString, userId, appId, nullptr, &extStats);
   1945             }
   1946         }
   1947         appSize = extStats.dataSize;
   1948         ATRACE_END();
   1949     } else {
   1950         ATRACE_BEGIN("manual");
   1951         FTS *fts;
   1952         FTSENT *p;
   1953         auto path = create_data_media_path(uuid_, userId);
   1954         char *argv[] = { (char*) path.c_str(), nullptr };
   1955         if (!(fts = fts_open(argv, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, nullptr))) {
   1956             return error("Failed to fts_open " + path);
   1957         }
   1958         while ((p = fts_read(fts)) != nullptr) {
   1959             char* ext;
   1960             int64_t size = (p->fts_statp->st_blocks * 512);
   1961             switch (p->fts_info) {
   1962             case FTS_F:
   1963                 // Only categorize files not belonging to apps
   1964                 if (p->fts_parent->fts_number == 0) {
   1965                     ext = strrchr(p->fts_name, '.');
   1966                     if (ext != nullptr) {
   1967                         switch (MatchExtension(++ext)) {
   1968                         case AID_MEDIA_AUDIO: audioSize += size; break;
   1969                         case AID_MEDIA_VIDEO: videoSize += size; break;
   1970                         case AID_MEDIA_IMAGE: imageSize += size; break;
   1971                         }
   1972                     }
   1973                 }
   1974                 [[fallthrough]]; // always count against total
   1975             case FTS_D:
   1976                 // Ignore data belonging to specific apps
   1977                 p->fts_number = p->fts_parent->fts_number;
   1978                 if (p->fts_level == 1 && !strcmp(p->fts_name, "Android")) {
   1979                     p->fts_number = 1;
   1980                 }
   1981                 [[fallthrough]]; // always count against total
   1982             case FTS_DEFAULT:
   1983             case FTS_SL:
   1984             case FTS_SLNONE:
   1985                 if (p->fts_parent->fts_number == 1) {
   1986                     appSize += size;
   1987                 }
   1988                 totalSize += size;
   1989                 break;
   1990             }
   1991         }
   1992         fts_close(fts);
   1993         ATRACE_END();
   1994 
   1995         ATRACE_BEGIN("obb");
   1996         auto obbPath = StringPrintf("%s/Android/obb",
   1997                 create_data_media_path(uuid_, userId).c_str());
   1998         calculate_tree_size(obbPath, &obbSize);
   1999         ATRACE_END();
   2000     }
   2001 
   2002     std::vector<int64_t> ret;
   2003     ret.push_back(totalSize);
   2004     ret.push_back(audioSize);
   2005     ret.push_back(videoSize);
   2006     ret.push_back(imageSize);
   2007     ret.push_back(appSize);
   2008     ret.push_back(obbSize);
   2009 #if MEASURE_DEBUG
   2010     LOG(DEBUG) << "Final result " << toString(ret);
   2011 #endif
   2012     *_aidl_return = ret;
   2013     return ok();
   2014 }
   2015 
   2016 binder::Status InstalldNativeService::setAppQuota(const std::unique_ptr<std::string>& uuid,
   2017         int32_t userId, int32_t appId, int64_t cacheQuota) {
   2018     ENFORCE_UID(AID_SYSTEM);
   2019     CHECK_ARGUMENT_UUID(uuid);
   2020     std::lock_guard<std::recursive_mutex> lock(mQuotasLock);
   2021 
   2022     int32_t uid = multiuser_get_uid(userId, appId);
   2023     mCacheQuotas[uid] = cacheQuota;
   2024 
   2025     return ok();
   2026 }
   2027 
   2028 // Dumps the contents of a profile file, using pkgname's dex files for pretty
   2029 // printing the result.
   2030 binder::Status InstalldNativeService::dumpProfiles(int32_t uid, const std::string& packageName,
   2031         const std::string& profileName, const std::string& codePath, bool* _aidl_return) {
   2032     ENFORCE_UID(AID_SYSTEM);
   2033     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
   2034     CHECK_ARGUMENT_PATH(codePath);
   2035     std::lock_guard<std::recursive_mutex> lock(mLock);
   2036 
   2037     *_aidl_return = dump_profiles(uid, packageName, profileName, codePath);
   2038     return ok();
   2039 }
   2040 
   2041 // Copy the contents of a system profile over the data profile.
   2042 binder::Status InstalldNativeService::copySystemProfile(const std::string& systemProfile,
   2043         int32_t packageUid, const std::string& packageName, const std::string& profileName,
   2044         bool* _aidl_return) {
   2045     ENFORCE_UID(AID_SYSTEM);
   2046     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
   2047     std::lock_guard<std::recursive_mutex> lock(mLock);
   2048     *_aidl_return = copy_system_profile(systemProfile, packageUid, packageName, profileName);
   2049     return ok();
   2050 }
   2051 
   2052 // TODO: Consider returning error codes.
   2053 binder::Status InstalldNativeService::mergeProfiles(int32_t uid, const std::string& packageName,
   2054         const std::string& profileName, bool* _aidl_return) {
   2055     ENFORCE_UID(AID_SYSTEM);
   2056     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
   2057     std::lock_guard<std::recursive_mutex> lock(mLock);
   2058 
   2059     *_aidl_return = analyze_primary_profiles(uid, packageName, profileName);
   2060     return ok();
   2061 }
   2062 
   2063 binder::Status InstalldNativeService::createProfileSnapshot(int32_t appId,
   2064         const std::string& packageName, const std::string& profileName,
   2065         const std::string& classpath, bool* _aidl_return) {
   2066     ENFORCE_UID(AID_SYSTEM);
   2067     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
   2068     std::lock_guard<std::recursive_mutex> lock(mLock);
   2069 
   2070     *_aidl_return = create_profile_snapshot(appId, packageName, profileName, classpath);
   2071     return ok();
   2072 }
   2073 
   2074 binder::Status InstalldNativeService::destroyProfileSnapshot(const std::string& packageName,
   2075         const std::string& profileName) {
   2076     ENFORCE_UID(AID_SYSTEM);
   2077     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
   2078     std::lock_guard<std::recursive_mutex> lock(mLock);
   2079 
   2080     std::string snapshot = create_snapshot_profile_path(packageName, profileName);
   2081     if ((unlink(snapshot.c_str()) != 0) && (errno != ENOENT)) {
   2082         return error("Failed to destroy profile snapshot for " + packageName + ":" + profileName);
   2083     }
   2084     return ok();
   2085 }
   2086 
   2087 static const char* getCStr(const std::unique_ptr<std::string>& data,
   2088         const char* default_value = nullptr) {
   2089     return data == nullptr ? default_value : data->c_str();
   2090 }
   2091 binder::Status InstalldNativeService::dexopt(const std::string& apkPath, int32_t uid,
   2092         const std::unique_ptr<std::string>& packageName, const std::string& instructionSet,
   2093         int32_t dexoptNeeded, const std::unique_ptr<std::string>& outputPath, int32_t dexFlags,
   2094         const std::string& compilerFilter, const std::unique_ptr<std::string>& uuid,
   2095         const std::unique_ptr<std::string>& classLoaderContext,
   2096         const std::unique_ptr<std::string>& seInfo, bool downgrade, int32_t targetSdkVersion,
   2097         const std::unique_ptr<std::string>& profileName,
   2098         const std::unique_ptr<std::string>& dexMetadataPath,
   2099         const std::unique_ptr<std::string>& compilationReason) {
   2100     ENFORCE_UID(AID_SYSTEM);
   2101     CHECK_ARGUMENT_UUID(uuid);
   2102     CHECK_ARGUMENT_PATH(apkPath);
   2103     if (packageName && *packageName != "*") {
   2104         CHECK_ARGUMENT_PACKAGE_NAME(*packageName);
   2105     }
   2106     CHECK_ARGUMENT_PATH(outputPath);
   2107     CHECK_ARGUMENT_PATH(dexMetadataPath);
   2108     std::lock_guard<std::recursive_mutex> lock(mLock);
   2109 
   2110     const char* apk_path = apkPath.c_str();
   2111     const char* pkgname = getCStr(packageName, "*");
   2112     const char* instruction_set = instructionSet.c_str();
   2113     const char* oat_dir = getCStr(outputPath);
   2114     const char* compiler_filter = compilerFilter.c_str();
   2115     const char* volume_uuid = getCStr(uuid);
   2116     const char* class_loader_context = getCStr(classLoaderContext);
   2117     const char* se_info = getCStr(seInfo);
   2118     const char* profile_name = getCStr(profileName);
   2119     const char* dm_path = getCStr(dexMetadataPath);
   2120     const char* compilation_reason = getCStr(compilationReason);
   2121     std::string error_msg;
   2122     int res = android::installd::dexopt(apk_path, uid, pkgname, instruction_set, dexoptNeeded,
   2123             oat_dir, dexFlags, compiler_filter, volume_uuid, class_loader_context, se_info,
   2124             downgrade, targetSdkVersion, profile_name, dm_path, compilation_reason, &error_msg);
   2125     return res ? error(res, error_msg) : ok();
   2126 }
   2127 
   2128 binder::Status InstalldNativeService::compileLayouts(const std::string& apkPath,
   2129                                                      const std::string& packageName,
   2130                                                      const std ::string& outDexFile, int uid,
   2131                                                      bool* _aidl_return) {
   2132     const char* apk_path = apkPath.c_str();
   2133     const char* package_name = packageName.c_str();
   2134     const char* out_dex_file = outDexFile.c_str();
   2135     *_aidl_return = android::installd::view_compiler(apk_path, package_name, out_dex_file, uid);
   2136     return *_aidl_return ? ok() : error("viewcompiler failed");
   2137 }
   2138 
   2139 binder::Status InstalldNativeService::markBootComplete(const std::string& instructionSet) {
   2140     ENFORCE_UID(AID_SYSTEM);
   2141     std::lock_guard<std::recursive_mutex> lock(mLock);
   2142 
   2143     const char* instruction_set = instructionSet.c_str();
   2144 
   2145     char boot_marker_path[PKG_PATH_MAX];
   2146     sprintf(boot_marker_path,
   2147           "%s/%s/%s/.booting",
   2148           android_data_dir.c_str(),
   2149           DALVIK_CACHE,
   2150           instruction_set);
   2151 
   2152     ALOGV("mark_boot_complete : %s", boot_marker_path);
   2153     if (unlink(boot_marker_path) != 0) {
   2154         return error(StringPrintf("Failed to unlink %s", boot_marker_path));
   2155     }
   2156     return ok();
   2157 }
   2158 
   2159 binder::Status InstalldNativeService::linkNativeLibraryDirectory(
   2160         const std::unique_ptr<std::string>& uuid, const std::string& packageName,
   2161         const std::string& nativeLibPath32, int32_t userId) {
   2162     ENFORCE_UID(AID_SYSTEM);
   2163     CHECK_ARGUMENT_UUID(uuid);
   2164     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
   2165     CHECK_ARGUMENT_PATH(nativeLibPath32);
   2166     std::lock_guard<std::recursive_mutex> lock(mLock);
   2167 
   2168     const char* uuid_ = uuid ? uuid->c_str() : nullptr;
   2169     const char* pkgname = packageName.c_str();
   2170     const char* asecLibDir = nativeLibPath32.c_str();
   2171     struct stat s, libStat;
   2172     binder::Status res = ok();
   2173 
   2174     auto _pkgdir = create_data_user_ce_package_path(uuid_, userId, pkgname);
   2175     auto _libsymlink = _pkgdir + PKG_LIB_POSTFIX;
   2176 
   2177     const char* pkgdir = _pkgdir.c_str();
   2178     const char* libsymlink = _libsymlink.c_str();
   2179 
   2180     if (stat(pkgdir, &s) < 0) {
   2181         return error("Failed to stat " + _pkgdir);
   2182     }
   2183 
   2184     char *con = nullptr;
   2185     if (lgetfilecon(pkgdir, &con) < 0) {
   2186         return error("Failed to lgetfilecon " + _pkgdir);
   2187     }
   2188 
   2189     if (chown(pkgdir, AID_INSTALL, AID_INSTALL) < 0) {
   2190         res = error("Failed to chown " + _pkgdir);
   2191         goto out;
   2192     }
   2193 
   2194     if (chmod(pkgdir, 0700) < 0) {
   2195         res = error("Failed to chmod " + _pkgdir);
   2196         goto out;
   2197     }
   2198 
   2199     if (lstat(libsymlink, &libStat) < 0) {
   2200         if (errno != ENOENT) {
   2201             res = error("Failed to stat " + _libsymlink);
   2202             goto out;
   2203         }
   2204     } else {
   2205         if (S_ISDIR(libStat.st_mode)) {
   2206             if (delete_dir_contents(libsymlink, 1, nullptr) < 0) {
   2207                 res = error("Failed to delete " + _libsymlink);
   2208                 goto out;
   2209             }
   2210         } else if (S_ISLNK(libStat.st_mode)) {
   2211             if (unlink(libsymlink) < 0) {
   2212                 res = error("Failed to unlink " + _libsymlink);
   2213                 goto out;
   2214             }
   2215         }
   2216     }
   2217 
   2218     if (symlink(asecLibDir, libsymlink) < 0) {
   2219         res = error("Failed to symlink " + _libsymlink + " to " + nativeLibPath32);
   2220         goto out;
   2221     }
   2222 
   2223     if (lsetfilecon(libsymlink, con) < 0) {
   2224         res = error("Failed to lsetfilecon " + _libsymlink);
   2225         goto out;
   2226     }
   2227 
   2228 out:
   2229     free(con);
   2230     if (chmod(pkgdir, s.st_mode) < 0) {
   2231         auto msg = "Failed to cleanup chmod " + _pkgdir;
   2232         if (res.isOk()) {
   2233             res = error(msg);
   2234         } else {
   2235             PLOG(ERROR) << msg;
   2236         }
   2237     }
   2238 
   2239     if (chown(pkgdir, s.st_uid, s.st_gid) < 0) {
   2240         auto msg = "Failed to cleanup chown " + _pkgdir;
   2241         if (res.isOk()) {
   2242             res = error(msg);
   2243         } else {
   2244             PLOG(ERROR) << msg;
   2245         }
   2246     }
   2247 
   2248     return res;
   2249 }
   2250 
   2251 static void run_idmap(const char *target_apk, const char *overlay_apk, int idmap_fd)
   2252 {
   2253     execl(kIdMapPath, kIdMapPath, "--fd", target_apk, overlay_apk,
   2254             StringPrintf("%d", idmap_fd).c_str(), (char*)nullptr);
   2255     PLOG(ERROR) << "execl (" << kIdMapPath << ") failed";
   2256 }
   2257 
   2258 static void run_verify_idmap(const char *target_apk, const char *overlay_apk, int idmap_fd)
   2259 {
   2260     execl(kIdMapPath, kIdMapPath, "--verify", target_apk, overlay_apk,
   2261             StringPrintf("%d", idmap_fd).c_str(), (char*)nullptr);
   2262     PLOG(ERROR) << "execl (" << kIdMapPath << ") failed";
   2263 }
   2264 
   2265 static bool delete_stale_idmap(const char* target_apk, const char* overlay_apk,
   2266         const char* idmap_path, int32_t uid) {
   2267     int idmap_fd = open(idmap_path, O_RDWR);
   2268     if (idmap_fd < 0) {
   2269         PLOG(ERROR) << "idmap open failed: " << idmap_path;
   2270         unlink(idmap_path);
   2271         return true;
   2272     }
   2273 
   2274     pid_t pid;
   2275     pid = fork();
   2276     if (pid == 0) {
   2277         /* child -- drop privileges before continuing */
   2278         if (setgid(uid) != 0) {
   2279             LOG(ERROR) << "setgid(" << uid << ") failed during idmap";
   2280             exit(1);
   2281         }
   2282         if (setuid(uid) != 0) {
   2283             LOG(ERROR) << "setuid(" << uid << ") failed during idmap";
   2284             exit(1);
   2285         }
   2286         if (flock(idmap_fd, LOCK_EX | LOCK_NB) != 0) {
   2287             PLOG(ERROR) << "flock(" << idmap_path << ") failed during idmap";
   2288             exit(1);
   2289         }
   2290 
   2291         run_verify_idmap(target_apk, overlay_apk, idmap_fd);
   2292         exit(1); /* only if exec call to deleting stale idmap failed */
   2293     } else {
   2294         int status = wait_child(pid);
   2295         close(idmap_fd);
   2296 
   2297         if (status != 0) {
   2298             // Failed on verifying if idmap is made from target_apk and overlay_apk.
   2299             LOG(DEBUG) << "delete stale idmap: " << idmap_path;
   2300             unlink(idmap_path);
   2301             return true;
   2302         }
   2303     }
   2304     return false;
   2305 }
   2306 
   2307 // Transform string /a/b/c.apk to (prefix)/a@b (at) c.apk@(suffix)
   2308 // eg /a/b/c.apk to /data/resource-cache/a@b (at) c.apk@idmap
   2309 static int flatten_path(const char *prefix, const char *suffix,
   2310         const char *overlay_path, char *idmap_path, size_t N)
   2311 {
   2312     if (overlay_path == nullptr || idmap_path == nullptr) {
   2313         return -1;
   2314     }
   2315     const size_t len_overlay_path = strlen(overlay_path);
   2316     // will access overlay_path + 1 further below; requires absolute path
   2317     if (len_overlay_path < 2 || *overlay_path != '/') {
   2318         return -1;
   2319     }
   2320     const size_t len_idmap_root = strlen(prefix);
   2321     const size_t len_suffix = strlen(suffix);
   2322     if (SIZE_MAX - len_idmap_root < len_overlay_path ||
   2323             SIZE_MAX - (len_idmap_root + len_overlay_path) < len_suffix) {
   2324         // additions below would cause overflow
   2325         return -1;
   2326     }
   2327     if (N < len_idmap_root + len_overlay_path + len_suffix) {
   2328         return -1;
   2329     }
   2330     memset(idmap_path, 0, N);
   2331     snprintf(idmap_path, N, "%s%s%s", prefix, overlay_path + 1, suffix);
   2332     char *ch = idmap_path + len_idmap_root;
   2333     while (*ch != '\0') {
   2334         if (*ch == '/') {
   2335             *ch = '@';
   2336         }
   2337         ++ch;
   2338     }
   2339     return 0;
   2340 }
   2341 
   2342 binder::Status InstalldNativeService::idmap(const std::string& targetApkPath,
   2343         const std::string& overlayApkPath, int32_t uid) {
   2344     ENFORCE_UID(AID_SYSTEM);
   2345     CHECK_ARGUMENT_PATH(targetApkPath);
   2346     CHECK_ARGUMENT_PATH(overlayApkPath);
   2347     std::lock_guard<std::recursive_mutex> lock(mLock);
   2348 
   2349     const char* target_apk = targetApkPath.c_str();
   2350     const char* overlay_apk = overlayApkPath.c_str();
   2351     ALOGV("idmap target_apk=%s overlay_apk=%s uid=%d\n", target_apk, overlay_apk, uid);
   2352 
   2353     int idmap_fd = -1;
   2354     char idmap_path[PATH_MAX];
   2355     struct stat idmap_stat;
   2356     bool outdated = false;
   2357 
   2358     if (flatten_path(IDMAP_PREFIX, IDMAP_SUFFIX, overlay_apk,
   2359                 idmap_path, sizeof(idmap_path)) == -1) {
   2360         ALOGE("idmap cannot generate idmap path for overlay %s\n", overlay_apk);
   2361         goto fail;
   2362     }
   2363 
   2364     if (stat(idmap_path, &idmap_stat) < 0) {
   2365         outdated = true;
   2366     } else {
   2367         outdated = delete_stale_idmap(target_apk, overlay_apk, idmap_path, uid);
   2368     }
   2369 
   2370     if (outdated) {
   2371         idmap_fd = open(idmap_path, O_RDWR | O_CREAT | O_EXCL, 0644);
   2372     } else {
   2373         idmap_fd = open(idmap_path, O_RDWR);
   2374     }
   2375 
   2376     if (idmap_fd < 0) {
   2377         ALOGE("idmap cannot open '%s' for output: %s\n", idmap_path, strerror(errno));
   2378         goto fail;
   2379     }
   2380     if (fchown(idmap_fd, AID_SYSTEM, uid) < 0) {
   2381         ALOGE("idmap cannot chown '%s'\n", idmap_path);
   2382         goto fail;
   2383     }
   2384     if (fchmod(idmap_fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0) {
   2385         ALOGE("idmap cannot chmod '%s'\n", idmap_path);
   2386         goto fail;
   2387     }
   2388 
   2389     if (!outdated) {
   2390         close(idmap_fd);
   2391         return ok();
   2392     }
   2393 
   2394     pid_t pid;
   2395     pid = fork();
   2396     if (pid == 0) {
   2397         /* child -- drop privileges before continuing */
   2398         if (setgid(uid) != 0) {
   2399             ALOGE("setgid(%d) failed during idmap\n", uid);
   2400             exit(1);
   2401         }
   2402         if (setuid(uid) != 0) {
   2403             ALOGE("setuid(%d) failed during idmap\n", uid);
   2404             exit(1);
   2405         }
   2406         if (flock(idmap_fd, LOCK_EX | LOCK_NB) != 0) {
   2407             ALOGE("flock(%s) failed during idmap: %s\n", idmap_path, strerror(errno));
   2408             exit(1);
   2409         }
   2410 
   2411         run_idmap(target_apk, overlay_apk, idmap_fd);
   2412         exit(1); /* only if exec call to idmap failed */
   2413     } else {
   2414         int status = wait_child(pid);
   2415         if (status != 0) {
   2416             ALOGE("idmap failed, status=0x%04x\n", status);
   2417             goto fail;
   2418         }
   2419     }
   2420 
   2421     close(idmap_fd);
   2422     return ok();
   2423 fail:
   2424     if (idmap_fd >= 0) {
   2425         close(idmap_fd);
   2426         unlink(idmap_path);
   2427     }
   2428     return error();
   2429 }
   2430 
   2431 binder::Status InstalldNativeService::removeIdmap(const std::string& overlayApkPath) {
   2432     ENFORCE_UID(AID_SYSTEM);
   2433     CHECK_ARGUMENT_PATH(overlayApkPath);
   2434     std::lock_guard<std::recursive_mutex> lock(mLock);
   2435 
   2436     const char* overlay_apk = overlayApkPath.c_str();
   2437     char idmap_path[PATH_MAX];
   2438 
   2439     if (flatten_path(IDMAP_PREFIX, IDMAP_SUFFIX, overlay_apk,
   2440                 idmap_path, sizeof(idmap_path)) == -1) {
   2441         ALOGE("idmap cannot generate idmap path for overlay %s\n", overlay_apk);
   2442         return error();
   2443     }
   2444     if (unlink(idmap_path) < 0) {
   2445         ALOGE("couldn't unlink idmap file %s\n", idmap_path);
   2446         return error();
   2447     }
   2448     return ok();
   2449 }
   2450 
   2451 binder::Status InstalldNativeService::restoreconAppData(const std::unique_ptr<std::string>& uuid,
   2452         const std::string& packageName, int32_t userId, int32_t flags, int32_t appId,
   2453         const std::string& seInfo) {
   2454     ENFORCE_UID(AID_SYSTEM);
   2455     CHECK_ARGUMENT_UUID(uuid);
   2456     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
   2457     std::lock_guard<std::recursive_mutex> lock(mLock);
   2458 
   2459     binder::Status res = ok();
   2460 
   2461     // SELINUX_ANDROID_RESTORECON_DATADATA flag is set by libselinux. Not needed here.
   2462     unsigned int seflags = SELINUX_ANDROID_RESTORECON_RECURSE;
   2463     const char* uuid_ = uuid ? uuid->c_str() : nullptr;
   2464     const char* pkgName = packageName.c_str();
   2465     const char* seinfo = seInfo.c_str();
   2466 
   2467     uid_t uid = multiuser_get_uid(userId, appId);
   2468     if (flags & FLAG_STORAGE_CE) {
   2469         auto path = create_data_user_ce_package_path(uuid_, userId, pkgName);
   2470         if (selinux_android_restorecon_pkgdir(path.c_str(), seinfo, uid, seflags) < 0) {
   2471             res = error("restorecon failed for " + path);
   2472         }
   2473     }
   2474     if (flags & FLAG_STORAGE_DE) {
   2475         auto path = create_data_user_de_package_path(uuid_, userId, pkgName);
   2476         if (selinux_android_restorecon_pkgdir(path.c_str(), seinfo, uid, seflags) < 0) {
   2477             res = error("restorecon failed for " + path);
   2478         }
   2479     }
   2480     return res;
   2481 }
   2482 
   2483 binder::Status InstalldNativeService::createOatDir(const std::string& oatDir,
   2484         const std::string& instructionSet) {
   2485     ENFORCE_UID(AID_SYSTEM);
   2486     CHECK_ARGUMENT_PATH(oatDir);
   2487     std::lock_guard<std::recursive_mutex> lock(mLock);
   2488 
   2489     const char* oat_dir = oatDir.c_str();
   2490     const char* instruction_set = instructionSet.c_str();
   2491     char oat_instr_dir[PKG_PATH_MAX];
   2492 
   2493     if (validate_apk_path(oat_dir)) {
   2494         return error("Invalid path " + oatDir);
   2495     }
   2496     if (fs_prepare_dir(oat_dir, S_IRWXU | S_IRWXG | S_IXOTH, AID_SYSTEM, AID_INSTALL)) {
   2497         return error("Failed to prepare " + oatDir);
   2498     }
   2499     if (selinux_android_restorecon(oat_dir, 0)) {
   2500         return error("Failed to restorecon " + oatDir);
   2501     }
   2502     snprintf(oat_instr_dir, PKG_PATH_MAX, "%s/%s", oat_dir, instruction_set);
   2503     if (fs_prepare_dir(oat_instr_dir, S_IRWXU | S_IRWXG | S_IXOTH, AID_SYSTEM, AID_INSTALL)) {
   2504         return error(StringPrintf("Failed to prepare %s", oat_instr_dir));
   2505     }
   2506     return ok();
   2507 }
   2508 
   2509 binder::Status InstalldNativeService::rmPackageDir(const std::string& packageDir) {
   2510     ENFORCE_UID(AID_SYSTEM);
   2511     CHECK_ARGUMENT_PATH(packageDir);
   2512     std::lock_guard<std::recursive_mutex> lock(mLock);
   2513 
   2514     if (validate_apk_path(packageDir.c_str())) {
   2515         return error("Invalid path " + packageDir);
   2516     }
   2517     if (rm_package_dir(packageDir) != 0) {
   2518         return error("Failed to delete " + packageDir);
   2519     }
   2520     return ok();
   2521 }
   2522 
   2523 binder::Status InstalldNativeService::linkFile(const std::string& relativePath,
   2524         const std::string& fromBase, const std::string& toBase) {
   2525     ENFORCE_UID(AID_SYSTEM);
   2526     CHECK_ARGUMENT_PATH(fromBase);
   2527     CHECK_ARGUMENT_PATH(toBase);
   2528     std::lock_guard<std::recursive_mutex> lock(mLock);
   2529 
   2530     const char* relative_path = relativePath.c_str();
   2531     const char* from_base = fromBase.c_str();
   2532     const char* to_base = toBase.c_str();
   2533     char from_path[PKG_PATH_MAX];
   2534     char to_path[PKG_PATH_MAX];
   2535     snprintf(from_path, PKG_PATH_MAX, "%s/%s", from_base, relative_path);
   2536     snprintf(to_path, PKG_PATH_MAX, "%s/%s", to_base, relative_path);
   2537 
   2538     if (validate_apk_path_subdirs(from_path)) {
   2539         return error(StringPrintf("Invalid from path %s", from_path));
   2540     }
   2541 
   2542     if (validate_apk_path_subdirs(to_path)) {
   2543         return error(StringPrintf("Invalid to path %s", to_path));
   2544     }
   2545 
   2546     if (link(from_path, to_path) < 0) {
   2547         return error(StringPrintf("Failed to link from %s to %s", from_path, to_path));
   2548     }
   2549 
   2550     return ok();
   2551 }
   2552 
   2553 binder::Status InstalldNativeService::moveAb(const std::string& apkPath,
   2554         const std::string& instructionSet, const std::string& outputPath) {
   2555     ENFORCE_UID(AID_SYSTEM);
   2556     CHECK_ARGUMENT_PATH(apkPath);
   2557     CHECK_ARGUMENT_PATH(outputPath);
   2558     std::lock_guard<std::recursive_mutex> lock(mLock);
   2559 
   2560     const char* apk_path = apkPath.c_str();
   2561     const char* instruction_set = instructionSet.c_str();
   2562     const char* oat_dir = outputPath.c_str();
   2563 
   2564     bool success = move_ab(apk_path, instruction_set, oat_dir);
   2565     return success ? ok() : error();
   2566 }
   2567 
   2568 binder::Status InstalldNativeService::deleteOdex(const std::string& apkPath,
   2569         const std::string& instructionSet, const std::unique_ptr<std::string>& outputPath) {
   2570     ENFORCE_UID(AID_SYSTEM);
   2571     CHECK_ARGUMENT_PATH(apkPath);
   2572     CHECK_ARGUMENT_PATH(outputPath);
   2573     std::lock_guard<std::recursive_mutex> lock(mLock);
   2574 
   2575     const char* apk_path = apkPath.c_str();
   2576     const char* instruction_set = instructionSet.c_str();
   2577     const char* oat_dir = outputPath ? outputPath->c_str() : nullptr;
   2578 
   2579     bool res = delete_odex(apk_path, instruction_set, oat_dir);
   2580     return res ? ok() : error();
   2581 }
   2582 
   2583 // This kernel feature is experimental.
   2584 // TODO: remove local definition once upstreamed
   2585 #ifndef FS_IOC_ENABLE_VERITY
   2586 
   2587 #define FS_IOC_ENABLE_VERITY           _IO('f', 133)
   2588 #define FS_IOC_SET_VERITY_MEASUREMENT  _IOW('f', 134, struct fsverity_measurement)
   2589 
   2590 #define FS_VERITY_ALG_SHA256           1
   2591 
   2592 struct fsverity_measurement {
   2593     __u16 digest_algorithm;
   2594     __u16 digest_size;
   2595     __u32 reserved1;
   2596     __u64 reserved2[3];
   2597     __u8 digest[];
   2598 };
   2599 
   2600 #endif
   2601 
   2602 binder::Status InstalldNativeService::installApkVerity(const std::string& filePath,
   2603         const ::android::base::unique_fd& verityInputAshmem, int32_t contentSize) {
   2604     ENFORCE_UID(AID_SYSTEM);
   2605     CHECK_ARGUMENT_PATH(filePath);
   2606     std::lock_guard<std::recursive_mutex> lock(mLock);
   2607 
   2608     if (!android::base::GetBoolProperty(kPropApkVerityMode, false)) {
   2609         return ok();
   2610     }
   2611 #ifndef NDEBUG
   2612     ASSERT_PAGE_SIZE_4K();
   2613 #endif
   2614     // TODO: also check fsverity support in the current file system if compiled with DEBUG.
   2615     // TODO: change ashmem to some temporary file to support huge apk.
   2616     if (!ashmem_valid(verityInputAshmem.get())) {
   2617         return error("FD is not an ashmem");
   2618     }
   2619 
   2620     // 1. Seek to the next page boundary beyond the end of the file.
   2621     ::android::base::unique_fd wfd(open(filePath.c_str(), O_WRONLY));
   2622     if (wfd.get() < 0) {
   2623         return error("Failed to open " + filePath);
   2624     }
   2625     struct stat st;
   2626     if (fstat(wfd.get(), &st) < 0) {
   2627         return error("Failed to stat " + filePath);
   2628     }
   2629     // fsverity starts from the block boundary.
   2630     off_t padding = kVerityPageSize - st.st_size % kVerityPageSize;
   2631     if (padding == kVerityPageSize) {
   2632         padding = 0;
   2633     }
   2634     if (lseek(wfd.get(), st.st_size + padding, SEEK_SET) < 0) {
   2635         return error("Failed to lseek " + filePath);
   2636     }
   2637 
   2638     // 2. Write everything in the ashmem to the file.  Note that allocated
   2639     //    ashmem size is multiple of page size, which is different from the
   2640     //    actual content size.
   2641     int shmSize = ashmem_get_size_region(verityInputAshmem.get());
   2642     if (shmSize < 0) {
   2643         return error("Failed to get ashmem size: " + std::to_string(shmSize));
   2644     }
   2645     if (contentSize < 0) {
   2646         return error("Invalid content size: " + std::to_string(contentSize));
   2647     }
   2648     if (contentSize > shmSize) {
   2649         return error("Content size overflow: " + std::to_string(contentSize) + " > " +
   2650                      std::to_string(shmSize));
   2651     }
   2652     auto data = std::unique_ptr<void, std::function<void (void *)>>(
   2653         mmap(nullptr, contentSize, PROT_READ, MAP_SHARED, verityInputAshmem.get(), 0),
   2654         [contentSize] (void* ptr) {
   2655           if (ptr != MAP_FAILED) {
   2656             munmap(ptr, contentSize);
   2657           }
   2658         });
   2659 
   2660     if (data.get() == MAP_FAILED) {
   2661         return error("Failed to mmap the ashmem");
   2662     }
   2663     char* cursor = reinterpret_cast<char*>(data.get());
   2664     int remaining = contentSize;
   2665     while (remaining > 0) {
   2666         int ret = TEMP_FAILURE_RETRY(write(wfd.get(), cursor, remaining));
   2667         if (ret < 0) {
   2668             return error("Failed to write to " + filePath + " (" + std::to_string(remaining) +
   2669                          + "/" + std::to_string(contentSize) + ")");
   2670         }
   2671         cursor += ret;
   2672         remaining -= ret;
   2673     }
   2674     wfd.reset();
   2675 
   2676     // 3. Enable fsverity (needs readonly fd. Once it's done, the file becomes immutable.
   2677     ::android::base::unique_fd rfd(open(filePath.c_str(), O_RDONLY));
   2678     if (ioctl(rfd.get(), FS_IOC_ENABLE_VERITY, nullptr) < 0) {
   2679         return error("Failed to enable fsverity on " + filePath);
   2680     }
   2681     return ok();
   2682 }
   2683 
   2684 binder::Status InstalldNativeService::assertFsverityRootHashMatches(const std::string& filePath,
   2685         const std::vector<uint8_t>& expectedHash) {
   2686     ENFORCE_UID(AID_SYSTEM);
   2687     CHECK_ARGUMENT_PATH(filePath);
   2688     std::lock_guard<std::recursive_mutex> lock(mLock);
   2689 
   2690     if (!android::base::GetBoolProperty(kPropApkVerityMode, false)) {
   2691         return ok();
   2692     }
   2693     // TODO: also check fsverity support in the current file system if compiled with DEBUG.
   2694     if (expectedHash.size() != kSha256Size) {
   2695         return error("verity hash size should be " + std::to_string(kSha256Size) + " but is " +
   2696                      std::to_string(expectedHash.size()));
   2697     }
   2698 
   2699     ::android::base::unique_fd fd(open(filePath.c_str(), O_RDONLY));
   2700     if (fd.get() < 0) {
   2701         return error("Failed to open " + filePath + ": " + strerror(errno));
   2702     }
   2703 
   2704     unsigned int buffer_size = sizeof(fsverity_measurement) + kSha256Size;
   2705     std::vector<char> buffer(buffer_size, 0);
   2706 
   2707     fsverity_measurement* config = reinterpret_cast<fsverity_measurement*>(buffer.data());
   2708     config->digest_algorithm = FS_VERITY_ALG_SHA256;
   2709     config->digest_size = kSha256Size;
   2710     memcpy(config->digest, expectedHash.data(), kSha256Size);
   2711     if (ioctl(fd.get(), FS_IOC_SET_VERITY_MEASUREMENT, config) < 0) {
   2712         // This includes an expected failure case with no FSVerity setup. It normally happens when
   2713         // the apk does not contains the Merkle tree root hash.
   2714         return error("Failed to measure fsverity on " + filePath + ": " + strerror(errno));
   2715     }
   2716     return ok();  // hashes match
   2717 }
   2718 
   2719 binder::Status InstalldNativeService::reconcileSecondaryDexFile(
   2720         const std::string& dexPath, const std::string& packageName, int32_t uid,
   2721         const std::vector<std::string>& isas, const std::unique_ptr<std::string>& volumeUuid,
   2722         int32_t storage_flag, bool* _aidl_return) {
   2723     ENFORCE_UID(AID_SYSTEM);
   2724     CHECK_ARGUMENT_UUID(volumeUuid);
   2725     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
   2726     CHECK_ARGUMENT_PATH(dexPath);
   2727     std::lock_guard<std::recursive_mutex> lock(mLock);
   2728 
   2729     bool result = android::installd::reconcile_secondary_dex_file(
   2730             dexPath, packageName, uid, isas, volumeUuid, storage_flag, _aidl_return);
   2731     return result ? ok() : error();
   2732 }
   2733 
   2734 binder::Status InstalldNativeService::hashSecondaryDexFile(
   2735         const std::string& dexPath, const std::string& packageName, int32_t uid,
   2736         const std::unique_ptr<std::string>& volumeUuid, int32_t storageFlag,
   2737         std::vector<uint8_t>* _aidl_return) {
   2738     ENFORCE_UID(AID_SYSTEM);
   2739     CHECK_ARGUMENT_UUID(volumeUuid);
   2740     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
   2741     CHECK_ARGUMENT_PATH(dexPath);
   2742 
   2743     // mLock is not taken here since we will never modify the file system.
   2744     // If a file is modified just as we are reading it this may result in an
   2745     // anomalous hash, but that's ok.
   2746     bool result = android::installd::hash_secondary_dex_file(
   2747         dexPath, packageName, uid, volumeUuid, storageFlag, _aidl_return);
   2748     return result ? ok() : error();
   2749 }
   2750 
   2751 binder::Status InstalldNativeService::invalidateMounts() {
   2752     ENFORCE_UID(AID_SYSTEM);
   2753     std::lock_guard<std::recursive_mutex> lock(mMountsLock);
   2754 
   2755     mStorageMounts.clear();
   2756 
   2757 #if !BYPASS_QUOTA
   2758     if (!InvalidateQuotaMounts()) {
   2759         return error("Failed to read mounts");
   2760     }
   2761 #endif
   2762 
   2763     std::ifstream in("/proc/mounts");
   2764     if (!in.is_open()) {
   2765         return error("Failed to read mounts");
   2766     }
   2767 
   2768     std::string source;
   2769     std::string target;
   2770     std::string ignored;
   2771     while (!in.eof()) {
   2772         std::getline(in, source, ' ');
   2773         std::getline(in, target, ' ');
   2774         std::getline(in, ignored);
   2775 
   2776 #if !BYPASS_SDCARDFS
   2777         if (target.compare(0, 21, "/mnt/runtime/default/") == 0) {
   2778             LOG(DEBUG) << "Found storage mount " << source << " at " << target;
   2779             mStorageMounts[source] = target;
   2780         }
   2781 #endif
   2782     }
   2783     return ok();
   2784 }
   2785 
   2786 std::string InstalldNativeService::findDataMediaPath(
   2787         const std::unique_ptr<std::string>& uuid, userid_t userid) {
   2788     std::lock_guard<std::recursive_mutex> lock(mMountsLock);
   2789     const char* uuid_ = uuid ? uuid->c_str() : nullptr;
   2790     auto path = StringPrintf("%s/media", create_data_path(uuid_).c_str());
   2791     auto resolved = mStorageMounts[path];
   2792     if (resolved.empty()) {
   2793         LOG(WARNING) << "Failed to find storage mount for " << path;
   2794         resolved = path;
   2795     }
   2796     return StringPrintf("%s/%u", resolved.c_str(), userid);
   2797 }
   2798 
   2799 binder::Status InstalldNativeService::isQuotaSupported(
   2800         const std::unique_ptr<std::string>& uuid, bool* _aidl_return) {
   2801     auto uuidString = uuid ? *uuid : "";
   2802     *_aidl_return = IsQuotaSupported(uuidString);
   2803     return ok();
   2804 }
   2805 
   2806 binder::Status InstalldNativeService::prepareAppProfile(const std::string& packageName,
   2807         int32_t userId, int32_t appId, const std::string& profileName, const std::string& codePath,
   2808         const std::unique_ptr<std::string>& dexMetadata, bool* _aidl_return) {
   2809     ENFORCE_UID(AID_SYSTEM);
   2810     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
   2811     CHECK_ARGUMENT_PATH(codePath);
   2812     std::lock_guard<std::recursive_mutex> lock(mLock);
   2813 
   2814     *_aidl_return = prepare_app_profile(packageName, userId, appId, profileName, codePath,
   2815         dexMetadata);
   2816     return ok();
   2817 }
   2818 
   2819 binder::Status InstalldNativeService::migrateLegacyObbData() {
   2820     ENFORCE_UID(AID_SYSTEM);
   2821     // NOTE: The lint warning doesn't apply to the use of system(3) with
   2822     // absolute parse and no command line arguments.
   2823     if (system("/system/bin/migrate_legacy_obb_data.sh") != 0) { // NOLINT(cert-env33-c)
   2824         LOG(ERROR) << "Unable to migrate legacy obb data";
   2825     }
   2826 
   2827     return ok();
   2828 }
   2829 
   2830 }  // namespace installd
   2831 }  // namespace android
   2832