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 "utils.h"
     18 
     19 #include <errno.h>
     20 #include <fcntl.h>
     21 #include <fts.h>
     22 #include <stdlib.h>
     23 #include <sys/stat.h>
     24 #include <sys/wait.h>
     25 #include <sys/xattr.h>
     26 #include <sys/statvfs.h>
     27 
     28 #include <android-base/logging.h>
     29 #include <android-base/strings.h>
     30 #include <android-base/stringprintf.h>
     31 #include <android-base/unique_fd.h>
     32 #include <cutils/fs.h>
     33 #include <cutils/properties.h>
     34 #include <log/log.h>
     35 #include <private/android_filesystem_config.h>
     36 
     37 #include "globals.h"  // extern variables.
     38 
     39 #ifndef LOG_TAG
     40 #define LOG_TAG "installd"
     41 #endif
     42 
     43 #define DEBUG_XATTRS 0
     44 
     45 using android::base::EndsWith;
     46 using android::base::StringPrintf;
     47 using android::base::unique_fd;
     48 
     49 namespace android {
     50 namespace installd {
     51 
     52 /**
     53  * Check that given string is valid filename, and that it attempts no
     54  * parent or child directory traversal.
     55  */
     56 bool is_valid_filename(const std::string& name) {
     57     if (name.empty() || (name == ".") || (name == "..")
     58             || (name.find('/') != std::string::npos)) {
     59         return false;
     60     } else {
     61         return true;
     62     }
     63 }
     64 
     65 static void check_package_name(const char* package_name) {
     66     CHECK(is_valid_filename(package_name));
     67     CHECK(is_valid_package_name(package_name));
     68 }
     69 
     70 /**
     71  * Create the path name where package app contents should be stored for
     72  * the given volume UUID and package name.  An empty UUID is assumed to
     73  * be internal storage.
     74  */
     75 std::string create_data_app_package_path(const char* volume_uuid,
     76         const char* package_name) {
     77     check_package_name(package_name);
     78     return StringPrintf("%s/%s",
     79             create_data_app_path(volume_uuid).c_str(), package_name);
     80 }
     81 
     82 /**
     83  * Create the path name where package data should be stored for the given
     84  * volume UUID, package name, and user ID. An empty UUID is assumed to be
     85  * internal storage.
     86  */
     87 std::string create_data_user_ce_package_path(const char* volume_uuid,
     88         userid_t user, const char* package_name) {
     89     check_package_name(package_name);
     90     return StringPrintf("%s/%s",
     91             create_data_user_ce_path(volume_uuid, user).c_str(), package_name);
     92 }
     93 
     94 /**
     95  * Create the path name where package data should be stored for the given
     96  * volume UUID, package name, and user ID. An empty UUID is assumed to be
     97  * internal storage.
     98  * Compared to create_data_user_ce_package_path this method always return the
     99  * ".../user/..." directory.
    100  */
    101 std::string create_data_user_ce_package_path_as_user_link(
    102         const char* volume_uuid, userid_t userid, const char* package_name) {
    103     check_package_name(package_name);
    104     std::string data(create_data_path(volume_uuid));
    105     return StringPrintf("%s/user/%u/%s", data.c_str(), userid, package_name);
    106 }
    107 
    108 std::string create_data_user_ce_package_path(const char* volume_uuid, userid_t user,
    109         const char* package_name, ino_t ce_data_inode) {
    110     // For testing purposes, rely on the inode when defined; this could be
    111     // optimized to use access() in the future.
    112     auto fallback = create_data_user_ce_package_path(volume_uuid, user, package_name);
    113     if (ce_data_inode != 0) {
    114         auto user_path = create_data_user_ce_path(volume_uuid, user);
    115         DIR* dir = opendir(user_path.c_str());
    116         if (dir == nullptr) {
    117             PLOG(ERROR) << "Failed to opendir " << user_path;
    118             return fallback;
    119         }
    120 
    121         struct dirent* ent;
    122         while ((ent = readdir(dir))) {
    123             if (ent->d_ino == ce_data_inode) {
    124                 auto resolved = StringPrintf("%s/%s", user_path.c_str(), ent->d_name);
    125 #if DEBUG_XATTRS
    126                 if (resolved != fallback) {
    127                     LOG(DEBUG) << "Resolved path " << resolved << " for inode " << ce_data_inode
    128                             << " instead of " << fallback;
    129                 }
    130 #endif
    131                 closedir(dir);
    132                 return resolved;
    133             }
    134         }
    135         LOG(WARNING) << "Failed to resolve inode " << ce_data_inode << "; using " << fallback;
    136         closedir(dir);
    137         return fallback;
    138     } else {
    139         return fallback;
    140     }
    141 }
    142 
    143 std::string create_data_user_de_package_path(const char* volume_uuid,
    144         userid_t user, const char* package_name) {
    145     check_package_name(package_name);
    146     return StringPrintf("%s/%s",
    147             create_data_user_de_path(volume_uuid, user).c_str(), package_name);
    148 }
    149 
    150 std::string create_data_path(const char* volume_uuid) {
    151     if (volume_uuid == nullptr) {
    152         return "/data";
    153     } else if (!strcmp(volume_uuid, "TEST")) {
    154         CHECK(property_get_bool("ro.debuggable", false));
    155         return "/data/local/tmp";
    156     } else {
    157         CHECK(is_valid_filename(volume_uuid));
    158         return StringPrintf("/mnt/expand/%s", volume_uuid);
    159     }
    160 }
    161 
    162 /**
    163  * Create the path name for app data.
    164  */
    165 std::string create_data_app_path(const char* volume_uuid) {
    166     return StringPrintf("%s/app", create_data_path(volume_uuid).c_str());
    167 }
    168 
    169 /**
    170  * Create the path name for user data for a certain userid.
    171  * Keep same implementation as vold to minimize path walking overhead
    172  */
    173 std::string create_data_user_ce_path(const char* volume_uuid, userid_t userid) {
    174     std::string data(create_data_path(volume_uuid));
    175     if (volume_uuid == nullptr && userid == 0) {
    176         std::string legacy = StringPrintf("%s/data", data.c_str());
    177         struct stat sb;
    178         if (lstat(legacy.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode)) {
    179             /* /data/data is dir, return /data/data for legacy system */
    180             return legacy;
    181         }
    182     }
    183     return StringPrintf("%s/user/%u", data.c_str(), userid);
    184 }
    185 
    186 /**
    187  * Create the path name for device encrypted user data for a certain userid.
    188  */
    189 std::string create_data_user_de_path(const char* volume_uuid, userid_t userid) {
    190     std::string data(create_data_path(volume_uuid));
    191     return StringPrintf("%s/user_de/%u", data.c_str(), userid);
    192 }
    193 
    194 /**
    195  * Create the path name for media for a certain userid.
    196  */
    197 std::string create_data_media_path(const char* volume_uuid, userid_t userid) {
    198     return StringPrintf("%s/media/%u", create_data_path(volume_uuid).c_str(), userid);
    199 }
    200 
    201 std::string create_data_media_obb_path(const char* volume_uuid, const char* package_name) {
    202     return StringPrintf("%s/media/obb/%s", create_data_path(volume_uuid).c_str(), package_name);
    203 }
    204 
    205 std::string create_data_media_package_path(const char* volume_uuid, userid_t userid,
    206         const char* data_type, const char* package_name) {
    207     return StringPrintf("%s/Android/%s/%s", create_data_media_path(volume_uuid, userid).c_str(),
    208             data_type, package_name);
    209 }
    210 
    211 std::string create_data_misc_legacy_path(userid_t userid) {
    212     return StringPrintf("%s/misc/user/%u", create_data_path(nullptr).c_str(), userid);
    213 }
    214 
    215 std::string create_primary_cur_profile_dir_path(userid_t userid) {
    216     return StringPrintf("%s/cur/%u", android_profiles_dir.c_str(), userid);
    217 }
    218 
    219 std::string create_primary_current_profile_package_dir_path(userid_t user,
    220         const std::string& package_name) {
    221     check_package_name(package_name.c_str());
    222     return StringPrintf("%s/%s",
    223             create_primary_cur_profile_dir_path(user).c_str(), package_name.c_str());
    224 }
    225 
    226 std::string create_primary_ref_profile_dir_path() {
    227     return StringPrintf("%s/ref", android_profiles_dir.c_str());
    228 }
    229 
    230 std::string create_primary_reference_profile_package_dir_path(const std::string& package_name) {
    231     check_package_name(package_name.c_str());
    232     return StringPrintf("%s/ref/%s", android_profiles_dir.c_str(), package_name.c_str());
    233 }
    234 
    235 std::string create_data_dalvik_cache_path() {
    236     return "/data/dalvik-cache";
    237 }
    238 
    239 // Keep profile paths in sync with ActivityThread and LoadedApk.
    240 const std::string PROFILE_EXT = ".prof";
    241 const std::string CURRENT_PROFILE_EXT = ".cur";
    242 const std::string SNAPSHOT_PROFILE_EXT = ".snapshot";
    243 
    244 // Gets the parent directory and the file name for the given secondary dex path.
    245 // Returns true on success, false on failure (if the dex_path does not have the expected
    246 // structure).
    247 static bool get_secondary_dex_location(const std::string& dex_path,
    248         std::string* out_dir_name, std::string* out_file_name) {
    249    size_t dirIndex = dex_path.rfind('/');
    250    if (dirIndex == std::string::npos) {
    251         return false;
    252    }
    253    if (dirIndex == dex_path.size() - 1) {
    254         return false;
    255    }
    256    *out_dir_name = dex_path.substr(0, dirIndex);
    257    *out_file_name = dex_path.substr(dirIndex + 1);
    258 
    259    return true;
    260 }
    261 
    262 std::string create_current_profile_path(userid_t user, const std::string& package_name,
    263         const std::string& location, bool is_secondary_dex) {
    264     if (is_secondary_dex) {
    265         // Secondary dex current profiles are stored next to the dex files under the oat folder.
    266         std::string dex_dir;
    267         std::string dex_name;
    268         CHECK(get_secondary_dex_location(location, &dex_dir, &dex_name))
    269                 << "Unexpected dir structure for secondary dex " << location;
    270         return StringPrintf("%s/oat/%s%s%s",
    271                 dex_dir.c_str(), dex_name.c_str(), CURRENT_PROFILE_EXT.c_str(),
    272                 PROFILE_EXT.c_str());
    273     } else {
    274         // Profiles for primary apks are under /data/misc/profiles/cur.
    275         std::string profile_dir = create_primary_current_profile_package_dir_path(
    276                 user, package_name);
    277         return StringPrintf("%s/%s", profile_dir.c_str(), location.c_str());
    278     }
    279 }
    280 
    281 std::string create_reference_profile_path(const std::string& package_name,
    282         const std::string& location, bool is_secondary_dex) {
    283     if (is_secondary_dex) {
    284         // Secondary dex reference profiles are stored next to the dex files under the oat folder.
    285         std::string dex_dir;
    286         std::string dex_name;
    287         CHECK(get_secondary_dex_location(location, &dex_dir, &dex_name))
    288                 << "Unexpected dir structure for secondary dex " << location;
    289         return StringPrintf("%s/oat/%s%s",
    290                 dex_dir.c_str(), dex_name.c_str(), PROFILE_EXT.c_str());
    291     } else {
    292         // Reference profiles for primary apks are stored in /data/misc/profile/ref.
    293         std::string profile_dir = create_primary_reference_profile_package_dir_path(package_name);
    294         return StringPrintf("%s/%s", profile_dir.c_str(), location.c_str());
    295     }
    296 }
    297 
    298 std::string create_snapshot_profile_path(const std::string& package,
    299         const std::string& profile_name) {
    300     std::string ref_profile = create_reference_profile_path(package, profile_name,
    301             /*is_secondary_dex*/ false);
    302     return ref_profile + SNAPSHOT_PROFILE_EXT;
    303 }
    304 
    305 std::vector<userid_t> get_known_users(const char* volume_uuid) {
    306     std::vector<userid_t> users;
    307 
    308     // We always have an owner
    309     users.push_back(0);
    310 
    311     std::string path(create_data_path(volume_uuid) + "/" + SECONDARY_USER_PREFIX);
    312     DIR* dir = opendir(path.c_str());
    313     if (dir == NULL) {
    314         // Unable to discover other users, but at least return owner
    315         PLOG(ERROR) << "Failed to opendir " << path;
    316         return users;
    317     }
    318 
    319     struct dirent* ent;
    320     while ((ent = readdir(dir))) {
    321         if (ent->d_type != DT_DIR) {
    322             continue;
    323         }
    324 
    325         char* end;
    326         userid_t user = strtol(ent->d_name, &end, 10);
    327         if (*end == '\0' && user != 0) {
    328             LOG(DEBUG) << "Found valid user " << user;
    329             users.push_back(user);
    330         }
    331     }
    332     closedir(dir);
    333 
    334     return users;
    335 }
    336 
    337 int calculate_tree_size(const std::string& path, int64_t* size,
    338         int32_t include_gid, int32_t exclude_gid, bool exclude_apps) {
    339     FTS *fts;
    340     FTSENT *p;
    341     int64_t matchedSize = 0;
    342     char *argv[] = { (char*) path.c_str(), nullptr };
    343     if (!(fts = fts_open(argv, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, NULL))) {
    344         if (errno != ENOENT) {
    345             PLOG(ERROR) << "Failed to fts_open " << path;
    346         }
    347         return -1;
    348     }
    349     while ((p = fts_read(fts)) != NULL) {
    350         switch (p->fts_info) {
    351         case FTS_D:
    352         case FTS_DEFAULT:
    353         case FTS_F:
    354         case FTS_SL:
    355         case FTS_SLNONE:
    356             int32_t uid = p->fts_statp->st_uid;
    357             int32_t gid = p->fts_statp->st_gid;
    358             int32_t user_uid = multiuser_get_app_id(uid);
    359             int32_t user_gid = multiuser_get_app_id(gid);
    360             if (exclude_apps && ((user_uid >= AID_APP_START && user_uid <= AID_APP_END)
    361                     || (user_gid >= AID_CACHE_GID_START && user_gid <= AID_CACHE_GID_END)
    362                     || (user_gid >= AID_SHARED_GID_START && user_gid <= AID_SHARED_GID_END))) {
    363                 // Don't traverse inside or measure
    364                 fts_set(fts, p, FTS_SKIP);
    365                 break;
    366             }
    367             if (include_gid != -1 && gid != include_gid) {
    368                 break;
    369             }
    370             if (exclude_gid != -1 && gid == exclude_gid) {
    371                 break;
    372             }
    373             matchedSize += (p->fts_statp->st_blocks * 512);
    374             break;
    375         }
    376     }
    377     fts_close(fts);
    378 #if MEASURE_DEBUG
    379     if ((include_gid == -1) && (exclude_gid == -1)) {
    380         LOG(DEBUG) << "Measured " << path << " size " << matchedSize;
    381     } else {
    382         LOG(DEBUG) << "Measured " << path << " size " << matchedSize << "; include " << include_gid
    383                 << " exclude " << exclude_gid;
    384     }
    385 #endif
    386     *size += matchedSize;
    387     return 0;
    388 }
    389 
    390 /**
    391  * Checks whether the package name is valid. Returns -1 on error and
    392  * 0 on success.
    393  */
    394 bool is_valid_package_name(const std::string& packageName) {
    395     // This logic is borrowed from PackageParser.java
    396     bool hasSep = false;
    397     bool front = true;
    398 
    399     auto it = packageName.begin();
    400     for (; it != packageName.end() && *it != '-'; it++) {
    401         char c = *it;
    402         if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
    403             front = false;
    404             continue;
    405         }
    406         if (!front) {
    407             if ((c >= '0' && c <= '9') || c == '_') {
    408                 continue;
    409             }
    410         }
    411         if (c == '.') {
    412             hasSep = true;
    413             front = true;
    414             continue;
    415         }
    416         LOG(WARNING) << "Bad package character " << c << " in " << packageName;
    417         return false;
    418     }
    419 
    420     if (front) {
    421         LOG(WARNING) << "Missing separator in " << packageName;
    422         return false;
    423     }
    424 
    425     for (; it != packageName.end(); it++) {
    426         char c = *it;
    427         if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) continue;
    428         if ((c >= '0' && c <= '9') || c == '_' || c == '-' || c == '=') continue;
    429         LOG(WARNING) << "Bad suffix character " << c << " in " << packageName;
    430         return false;
    431     }
    432 
    433     return true;
    434 }
    435 
    436 static int _delete_dir_contents(DIR *d,
    437                                 int (*exclusion_predicate)(const char *name, const int is_dir))
    438 {
    439     int result = 0;
    440     struct dirent *de;
    441     int dfd;
    442 
    443     dfd = dirfd(d);
    444 
    445     if (dfd < 0) return -1;
    446 
    447     while ((de = readdir(d))) {
    448         const char *name = de->d_name;
    449 
    450             /* check using the exclusion predicate, if provided */
    451         if (exclusion_predicate && exclusion_predicate(name, (de->d_type == DT_DIR))) {
    452             continue;
    453         }
    454 
    455         if (de->d_type == DT_DIR) {
    456             int subfd;
    457             DIR *subdir;
    458 
    459                 /* always skip "." and ".." */
    460             if (name[0] == '.') {
    461                 if (name[1] == 0) continue;
    462                 if ((name[1] == '.') && (name[2] == 0)) continue;
    463             }
    464 
    465             subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC);
    466             if (subfd < 0) {
    467                 ALOGE("Couldn't openat %s: %s\n", name, strerror(errno));
    468                 result = -1;
    469                 continue;
    470             }
    471             subdir = fdopendir(subfd);
    472             if (subdir == NULL) {
    473                 ALOGE("Couldn't fdopendir %s: %s\n", name, strerror(errno));
    474                 close(subfd);
    475                 result = -1;
    476                 continue;
    477             }
    478             if (_delete_dir_contents(subdir, exclusion_predicate)) {
    479                 result = -1;
    480             }
    481             closedir(subdir);
    482             if (unlinkat(dfd, name, AT_REMOVEDIR) < 0) {
    483                 ALOGE("Couldn't unlinkat %s: %s\n", name, strerror(errno));
    484                 result = -1;
    485             }
    486         } else {
    487             if (unlinkat(dfd, name, 0) < 0) {
    488                 ALOGE("Couldn't unlinkat %s: %s\n", name, strerror(errno));
    489                 result = -1;
    490             }
    491         }
    492     }
    493 
    494     return result;
    495 }
    496 
    497 int delete_dir_contents(const std::string& pathname, bool ignore_if_missing) {
    498     return delete_dir_contents(pathname.c_str(), 0, NULL, ignore_if_missing);
    499 }
    500 
    501 int delete_dir_contents_and_dir(const std::string& pathname, bool ignore_if_missing) {
    502     return delete_dir_contents(pathname.c_str(), 1, NULL, ignore_if_missing);
    503 }
    504 
    505 int delete_dir_contents(const char *pathname,
    506                         int also_delete_dir,
    507                         int (*exclusion_predicate)(const char*, const int),
    508                         bool ignore_if_missing)
    509 {
    510     int res = 0;
    511     DIR *d;
    512 
    513     d = opendir(pathname);
    514     if (d == NULL) {
    515         if (ignore_if_missing && (errno == ENOENT)) {
    516             return 0;
    517         }
    518         ALOGE("Couldn't opendir %s: %s\n", pathname, strerror(errno));
    519         return -errno;
    520     }
    521     res = _delete_dir_contents(d, exclusion_predicate);
    522     closedir(d);
    523     if (also_delete_dir) {
    524         if (rmdir(pathname)) {
    525             ALOGE("Couldn't rmdir %s: %s\n", pathname, strerror(errno));
    526             res = -1;
    527         }
    528     }
    529     return res;
    530 }
    531 
    532 int delete_dir_contents_fd(int dfd, const char *name)
    533 {
    534     int fd, res;
    535     DIR *d;
    536 
    537     fd = openat(dfd, name, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC);
    538     if (fd < 0) {
    539         ALOGE("Couldn't openat %s: %s\n", name, strerror(errno));
    540         return -1;
    541     }
    542     d = fdopendir(fd);
    543     if (d == NULL) {
    544         ALOGE("Couldn't fdopendir %s: %s\n", name, strerror(errno));
    545         close(fd);
    546         return -1;
    547     }
    548     res = _delete_dir_contents(d, 0);
    549     closedir(d);
    550     return res;
    551 }
    552 
    553 static int _copy_owner_permissions(int srcfd, int dstfd)
    554 {
    555     struct stat st;
    556     if (fstat(srcfd, &st) != 0) {
    557         return -1;
    558     }
    559     if (fchmod(dstfd, st.st_mode) != 0) {
    560         return -1;
    561     }
    562     return 0;
    563 }
    564 
    565 static int _copy_dir_files(int sdfd, int ddfd, uid_t owner, gid_t group)
    566 {
    567     int result = 0;
    568     if (_copy_owner_permissions(sdfd, ddfd) != 0) {
    569         ALOGE("_copy_dir_files failed to copy dir permissions\n");
    570     }
    571     if (fchown(ddfd, owner, group) != 0) {
    572         ALOGE("_copy_dir_files failed to change dir owner\n");
    573     }
    574 
    575     DIR *ds = fdopendir(sdfd);
    576     if (ds == NULL) {
    577         ALOGE("Couldn't fdopendir: %s\n", strerror(errno));
    578         return -1;
    579     }
    580     struct dirent *de;
    581     while ((de = readdir(ds))) {
    582         if (de->d_type != DT_REG) {
    583             continue;
    584         }
    585 
    586         const char *name = de->d_name;
    587         int fsfd = openat(sdfd, name, O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
    588         int fdfd = openat(ddfd, name, O_WRONLY | O_NOFOLLOW | O_CLOEXEC | O_CREAT, 0600);
    589         if (fsfd == -1 || fdfd == -1) {
    590             ALOGW("Couldn't copy %s: %s\n", name, strerror(errno));
    591         } else {
    592             if (_copy_owner_permissions(fsfd, fdfd) != 0) {
    593                 ALOGE("Failed to change file permissions\n");
    594             }
    595             if (fchown(fdfd, owner, group) != 0) {
    596                 ALOGE("Failed to change file owner\n");
    597             }
    598 
    599             char buf[8192];
    600             ssize_t size;
    601             while ((size = read(fsfd, buf, sizeof(buf))) > 0) {
    602                 write(fdfd, buf, size);
    603             }
    604             if (size < 0) {
    605                 ALOGW("Couldn't copy %s: %s\n", name, strerror(errno));
    606                 result = -1;
    607             }
    608         }
    609         close(fdfd);
    610         close(fsfd);
    611     }
    612 
    613     return result;
    614 }
    615 
    616 int copy_dir_files(const char *srcname,
    617                    const char *dstname,
    618                    uid_t owner,
    619                    uid_t group)
    620 {
    621     int res = 0;
    622     DIR *ds = NULL;
    623     DIR *dd = NULL;
    624 
    625     ds = opendir(srcname);
    626     if (ds == NULL) {
    627         ALOGE("Couldn't opendir %s: %s\n", srcname, strerror(errno));
    628         return -errno;
    629     }
    630 
    631     mkdir(dstname, 0600);
    632     dd = opendir(dstname);
    633     if (dd == NULL) {
    634         ALOGE("Couldn't opendir %s: %s\n", dstname, strerror(errno));
    635         closedir(ds);
    636         return -errno;
    637     }
    638 
    639     int sdfd = dirfd(ds);
    640     int ddfd = dirfd(dd);
    641     if (sdfd != -1 && ddfd != -1) {
    642         res = _copy_dir_files(sdfd, ddfd, owner, group);
    643     } else {
    644         res = -errno;
    645     }
    646     closedir(dd);
    647     closedir(ds);
    648     return res;
    649 }
    650 
    651 int64_t data_disk_free(const std::string& data_path) {
    652     struct statvfs sfs;
    653     if (statvfs(data_path.c_str(), &sfs) == 0) {
    654         return static_cast<int64_t>(sfs.f_bavail) * sfs.f_frsize;
    655     } else {
    656         PLOG(ERROR) << "Couldn't statvfs " << data_path;
    657         return -1;
    658     }
    659 }
    660 
    661 int get_path_inode(const std::string& path, ino_t *inode) {
    662     struct stat buf;
    663     memset(&buf, 0, sizeof(buf));
    664     if (stat(path.c_str(), &buf) != 0) {
    665         PLOG(WARNING) << "Failed to stat " << path;
    666         return -1;
    667     } else {
    668         *inode = buf.st_ino;
    669         return 0;
    670     }
    671 }
    672 
    673 /**
    674  * Write the inode of a specific child file into the given xattr on the
    675  * parent directory. This allows you to find the child later, even if its
    676  * name is encrypted.
    677  */
    678 int write_path_inode(const std::string& parent, const char* name, const char* inode_xattr) {
    679     ino_t inode = 0;
    680     uint64_t inode_raw = 0;
    681     auto path = StringPrintf("%s/%s", parent.c_str(), name);
    682 
    683     if (get_path_inode(path, &inode) != 0) {
    684         // Path probably doesn't exist yet; ignore
    685         return 0;
    686     }
    687 
    688     // Check to see if already set correctly
    689     if (getxattr(parent.c_str(), inode_xattr, &inode_raw, sizeof(inode_raw)) == sizeof(inode_raw)) {
    690         if (inode_raw == inode) {
    691             // Already set correctly; skip writing
    692             return 0;
    693         } else {
    694             PLOG(WARNING) << "Mismatched inode value; found " << inode
    695                     << " on disk but marked value was " << inode_raw << "; overwriting";
    696         }
    697     }
    698 
    699     inode_raw = inode;
    700     if (setxattr(parent.c_str(), inode_xattr, &inode_raw, sizeof(inode_raw), 0) != 0 && errno != EOPNOTSUPP) {
    701         PLOG(ERROR) << "Failed to write xattr " << inode_xattr << " at " << parent;
    702         return -1;
    703     } else {
    704         return 0;
    705     }
    706 }
    707 
    708 /**
    709  * Read the inode of a specific child file from the given xattr on the
    710  * parent directory. Returns a currently valid path for that child, which
    711  * might have an encrypted name.
    712  */
    713 std::string read_path_inode(const std::string& parent, const char* name, const char* inode_xattr) {
    714     ino_t inode = 0;
    715     uint64_t inode_raw = 0;
    716     auto fallback = StringPrintf("%s/%s", parent.c_str(), name);
    717 
    718     // Lookup the inode value written earlier
    719     if (getxattr(parent.c_str(), inode_xattr, &inode_raw, sizeof(inode_raw)) == sizeof(inode_raw)) {
    720         inode = inode_raw;
    721     }
    722 
    723     // For testing purposes, rely on the inode when defined; this could be
    724     // optimized to use access() in the future.
    725     if (inode != 0) {
    726         DIR* dir = opendir(parent.c_str());
    727         if (dir == nullptr) {
    728             PLOG(ERROR) << "Failed to opendir " << parent;
    729             return fallback;
    730         }
    731 
    732         struct dirent* ent;
    733         while ((ent = readdir(dir))) {
    734             if (ent->d_ino == inode) {
    735                 auto resolved = StringPrintf("%s/%s", parent.c_str(), ent->d_name);
    736 #if DEBUG_XATTRS
    737                 if (resolved != fallback) {
    738                     LOG(DEBUG) << "Resolved path " << resolved << " for inode " << inode
    739                             << " instead of " << fallback;
    740                 }
    741 #endif
    742                 closedir(dir);
    743                 return resolved;
    744             }
    745         }
    746         LOG(WARNING) << "Failed to resolve inode " << inode << "; using " << fallback;
    747         closedir(dir);
    748         return fallback;
    749     } else {
    750         return fallback;
    751     }
    752 }
    753 
    754 void remove_path_xattr(const std::string& path, const char* inode_xattr) {
    755     if (removexattr(path.c_str(), inode_xattr) && errno != ENODATA) {
    756         PLOG(ERROR) << "Failed to remove xattr " << inode_xattr << " at " << path;
    757     }
    758 }
    759 
    760 /**
    761  * Validate that the path is valid in the context of the provided directory.
    762  * The path is allowed to have at most one subdirectory and no indirections
    763  * to top level directories (i.e. have "..").
    764  */
    765 static int validate_path(const std::string& dir, const std::string& path, int maxSubdirs) {
    766     // Argument sanity checking
    767     if (dir.find('/') != 0 || dir.rfind('/') != dir.size() - 1
    768             || dir.find("..") != std::string::npos) {
    769         LOG(ERROR) << "Invalid directory " << dir;
    770         return -1;
    771     }
    772     if (path.find("..") != std::string::npos) {
    773         LOG(ERROR) << "Invalid path " << path;
    774         return -1;
    775     }
    776 
    777     if (path.compare(0, dir.size(), dir) != 0) {
    778         // Common case, path isn't under directory
    779         return -1;
    780     }
    781 
    782     // Count number of subdirectories
    783     auto pos = path.find('/', dir.size());
    784     int count = 0;
    785     while (pos != std::string::npos) {
    786         auto next = path.find('/', pos + 1);
    787         if (next > pos + 1) {
    788             count++;
    789         }
    790         pos = next;
    791     }
    792 
    793     if (count > maxSubdirs) {
    794         LOG(ERROR) << "Invalid path depth " << path << " when tested against " << dir;
    795         return -1;
    796     }
    797 
    798     return 0;
    799 }
    800 
    801 /**
    802  * Checks whether a path points to a system app (.apk file). Returns 0
    803  * if it is a system app or -1 if it is not.
    804  */
    805 int validate_system_app_path(const char* path) {
    806     std::string path_ = path;
    807     for (const auto& dir : android_system_dirs) {
    808         if (validate_path(dir, path, 1) == 0) {
    809             return 0;
    810         }
    811     }
    812     return -1;
    813 }
    814 
    815 bool validate_secondary_dex_path(const std::string& pkgname, const std::string& dex_path,
    816         const char* volume_uuid, int uid, int storage_flag) {
    817     CHECK(storage_flag == FLAG_STORAGE_CE || storage_flag == FLAG_STORAGE_DE);
    818 
    819     // Empty paths are not allowed.
    820     if (dex_path.empty()) { return false; }
    821     // First character should always be '/'. No relative paths.
    822     if (dex_path[0] != '/') { return false; }
    823     // The last character should not be '/'.
    824     if (dex_path[dex_path.size() - 1] == '/') { return false; }
    825     // There should be no '.' after the directory marker.
    826     if (dex_path.find("/.") != std::string::npos) { return false; }
    827     // The path should be at most PKG_PATH_MAX long.
    828     if (dex_path.size() > PKG_PATH_MAX) { return false; }
    829 
    830     // The dex_path should be under the app data directory.
    831     std::string app_private_dir = storage_flag == FLAG_STORAGE_CE
    832             ? create_data_user_ce_package_path(
    833                     volume_uuid, multiuser_get_user_id(uid), pkgname.c_str())
    834             : create_data_user_de_package_path(
    835                     volume_uuid, multiuser_get_user_id(uid), pkgname.c_str());
    836 
    837     if (strncmp(dex_path.c_str(), app_private_dir.c_str(), app_private_dir.size()) != 0) {
    838         // The check above might fail if the dex file is accessed via the /data/user/0 symlink.
    839         // If that's the case, attempt to validate against the user data link.
    840         std::string app_private_dir_symlink = create_data_user_ce_package_path_as_user_link(
    841                 volume_uuid, multiuser_get_user_id(uid), pkgname.c_str());
    842         if (strncmp(dex_path.c_str(), app_private_dir_symlink.c_str(),
    843                 app_private_dir_symlink.size()) != 0) {
    844             return false;
    845         }
    846     }
    847 
    848     // If we got here we have a valid path.
    849     return true;
    850 }
    851 
    852 /**
    853  * Check whether path points to a valid path for an APK file. The path must
    854  * begin with a whitelisted prefix path and must be no deeper than |maxSubdirs| within
    855  * that path. Returns -1 when an invalid path is encountered and 0 when a valid path
    856  * is encountered.
    857  */
    858 static int validate_apk_path_internal(const std::string& path, int maxSubdirs) {
    859     if (validate_path(android_app_dir, path, maxSubdirs) == 0) {
    860         return 0;
    861     } else if (validate_path(android_app_private_dir, path, maxSubdirs) == 0) {
    862         return 0;
    863     } else if (validate_path(android_app_ephemeral_dir, path, maxSubdirs) == 0) {
    864         return 0;
    865     } else if (validate_path(android_asec_dir, path, maxSubdirs) == 0) {
    866         return 0;
    867     } else if (android::base::StartsWith(path, android_mnt_expand_dir)) {
    868         // Rewrite the path as if it were on internal storage, and test that
    869         size_t end = path.find('/', android_mnt_expand_dir.size() + 1);
    870         if (end != std::string::npos) {
    871             auto modified = path;
    872             modified.replace(0, end + 1, android_data_dir);
    873             return validate_apk_path_internal(modified, maxSubdirs);
    874         }
    875     }
    876     return -1;
    877 }
    878 
    879 int validate_apk_path(const char* path) {
    880     return validate_apk_path_internal(path, 1 /* maxSubdirs */);
    881 }
    882 
    883 int validate_apk_path_subdirs(const char* path) {
    884     return validate_apk_path_internal(path, 3 /* maxSubdirs */);
    885 }
    886 
    887 int ensure_config_user_dirs(userid_t userid) {
    888     // writable by system, readable by any app within the same user
    889     const int uid = multiuser_get_uid(userid, AID_SYSTEM);
    890     const int gid = multiuser_get_uid(userid, AID_EVERYBODY);
    891 
    892     // Ensure /data/misc/user/<userid> exists
    893     auto path = create_data_misc_legacy_path(userid);
    894     return fs_prepare_dir(path.c_str(), 0750, uid, gid);
    895 }
    896 
    897 int wait_child(pid_t pid)
    898 {
    899     int status;
    900     pid_t got_pid;
    901 
    902     while (1) {
    903         got_pid = waitpid(pid, &status, 0);
    904         if (got_pid == -1 && errno == EINTR) {
    905             printf("waitpid interrupted, retrying\n");
    906         } else {
    907             break;
    908         }
    909     }
    910     if (got_pid != pid) {
    911         ALOGW("waitpid failed: wanted %d, got %d: %s\n",
    912             (int) pid, (int) got_pid, strerror(errno));
    913         return 1;
    914     }
    915 
    916     if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
    917         return 0;
    918     } else {
    919         return status;      /* always nonzero */
    920     }
    921 }
    922 
    923 /**
    924  * Prepare an app cache directory, which offers to fix-up the GID and
    925  * directory mode flags during a platform upgrade.
    926  * The app cache directory path will be 'parent'/'name'.
    927  */
    928 int prepare_app_cache_dir(const std::string& parent, const char* name, mode_t target_mode,
    929         uid_t uid, gid_t gid) {
    930     auto path = StringPrintf("%s/%s", parent.c_str(), name);
    931     struct stat st;
    932     if (stat(path.c_str(), &st) != 0) {
    933         if (errno == ENOENT) {
    934             // This is fine, just create it
    935             if (fs_prepare_dir_strict(path.c_str(), target_mode, uid, gid) != 0) {
    936                 PLOG(ERROR) << "Failed to prepare " << path;
    937                 return -1;
    938             } else {
    939                 return 0;
    940             }
    941         } else {
    942             PLOG(ERROR) << "Failed to stat " << path;
    943             return -1;
    944         }
    945     }
    946 
    947     mode_t actual_mode = st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO | S_ISGID);
    948     if (st.st_uid != uid) {
    949         // Mismatched UID is real trouble; we can't recover
    950         LOG(ERROR) << "Mismatched UID at " << path << ": found " << st.st_uid
    951                 << " but expected " << uid;
    952         return -1;
    953     } else if (st.st_gid == gid && actual_mode == target_mode) {
    954         // Everything looks good!
    955         return 0;
    956     } else {
    957         // Mismatched GID/mode is recoverable; fall through to update
    958         LOG(DEBUG) << "Mismatched cache GID/mode at " << path << ": found " << st.st_gid
    959                 << "/" << actual_mode << " but expected " << gid << "/" << target_mode;
    960     }
    961 
    962     // Directory is owned correctly, but GID or mode mismatch means it's
    963     // probably a platform upgrade so we need to fix them
    964     FTS *fts;
    965     FTSENT *p;
    966     char *argv[] = { (char*) path.c_str(), nullptr };
    967     if (!(fts = fts_open(argv, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, NULL))) {
    968         PLOG(ERROR) << "Failed to fts_open " << path;
    969         return -1;
    970     }
    971     while ((p = fts_read(fts)) != NULL) {
    972         switch (p->fts_info) {
    973         case FTS_DP:
    974             if (chmod(p->fts_path, target_mode) != 0) {
    975                 PLOG(WARNING) << "Failed to chmod " << p->fts_path;
    976             }
    977             // Intentional fall through to also set GID
    978         case FTS_F:
    979             if (chown(p->fts_path, -1, gid) != 0) {
    980                 PLOG(WARNING) << "Failed to chown " << p->fts_path;
    981             }
    982             break;
    983         case FTS_SL:
    984         case FTS_SLNONE:
    985             if (lchown(p->fts_path, -1, gid) != 0) {
    986                 PLOG(WARNING) << "Failed to chown " << p->fts_path;
    987             }
    988             break;
    989         }
    990     }
    991     fts_close(fts);
    992     return 0;
    993 }
    994 
    995 // Collect all non empty profiles from the given directory and puts then into profile_paths.
    996 // The profiles are identified based on PROFILE_EXT extension.
    997 // If a subdirectory or profile file cannot be opened the method logs a warning and moves on.
    998 // It returns true if there were no errors at all, and false otherwise.
    999 static bool collect_profiles(DIR* d,
   1000                              const std::string& current_path,
   1001                              std::vector<std::string>* profiles_paths) {
   1002     int32_t dir_fd = dirfd(d);
   1003     if (dir_fd < 0) {
   1004         return false;
   1005     }
   1006 
   1007     bool result = true;
   1008     struct dirent* dir_entry;
   1009     while ((dir_entry = readdir(d))) {
   1010         std::string name = dir_entry->d_name;
   1011         std::string local_path = current_path + "/" + name;
   1012 
   1013         if (dir_entry->d_type == DT_REG) {
   1014             // Check if this is a non empty profile file.
   1015             if (EndsWith(name, PROFILE_EXT)) {
   1016                 struct stat st;
   1017                 if (stat(local_path.c_str(), &st) != 0) {
   1018                     PLOG(WARNING) << "Cannot stat local path " << local_path;
   1019                     result = false;
   1020                     continue;
   1021                 } else if (st.st_size > 0) {
   1022                     profiles_paths->push_back(local_path);
   1023                 }
   1024             }
   1025         } else if (dir_entry->d_type == DT_DIR) {
   1026             // always skip "." and ".."
   1027             if (name == "." || name == "..") {
   1028                 continue;
   1029             }
   1030 
   1031             unique_fd subdir_fd(openat(dir_fd, name.c_str(),
   1032                     O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC));
   1033             if (subdir_fd < 0) {
   1034                 PLOG(WARNING) << "Could not open dir path " << local_path;
   1035                 result = false;
   1036                 continue;
   1037             }
   1038 
   1039             DIR* subdir = fdopendir(subdir_fd);
   1040             if (subdir == NULL) {
   1041                 PLOG(WARNING) << "Could not open dir path " << local_path;
   1042                 result = false;
   1043                 continue;
   1044             }
   1045             bool new_result = collect_profiles(subdir, local_path, profiles_paths);
   1046             result = result && new_result;
   1047             if (closedir(subdir) != 0) {
   1048                 PLOG(WARNING) << "Could not close dir path " << local_path;
   1049             }
   1050         }
   1051     }
   1052 
   1053     return result;
   1054 }
   1055 
   1056 bool collect_profiles(std::vector<std::string>* profiles_paths) {
   1057     DIR* d = opendir(android_profiles_dir.c_str());
   1058     if (d == NULL) {
   1059         return false;
   1060     } else {
   1061         return collect_profiles(d, android_profiles_dir, profiles_paths);
   1062     }
   1063 }
   1064 
   1065 }  // namespace installd
   1066 }  // namespace android
   1067