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