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 "installd.h"
     18 
     19 #define CACHE_NOISY(x) //x
     20 
     21 int create_pkg_path_in_dir(char path[PKG_PATH_MAX],
     22                                 const dir_rec_t* dir,
     23                                 const char* pkgname,
     24                                 const char* postfix)
     25 {
     26      const size_t postfix_len = strlen(postfix);
     27 
     28      const size_t pkgname_len = strlen(pkgname);
     29      if (pkgname_len > PKG_NAME_MAX) {
     30          return -1;
     31      }
     32 
     33      if (is_valid_package_name(pkgname) < 0) {
     34          return -1;
     35      }
     36 
     37      if ((pkgname_len + dir->len + postfix_len) >= PKG_PATH_MAX) {
     38          return -1;
     39      }
     40 
     41      char *dst = path;
     42      size_t dst_size = PKG_PATH_MAX;
     43 
     44      if (append_and_increment(&dst, dir->path, &dst_size) < 0
     45              || append_and_increment(&dst, pkgname, &dst_size) < 0
     46              || append_and_increment(&dst, postfix, &dst_size) < 0) {
     47          ALOGE("Error building APK path");
     48          return -1;
     49      }
     50 
     51      return 0;
     52 }
     53 
     54 /**
     55  * Create the package path name for a given package name with a postfix for
     56  * a certain userid. Returns 0 on success, and -1 on failure.
     57  */
     58 int create_pkg_path(char path[PKG_PATH_MAX],
     59                     const char *pkgname,
     60                     const char *postfix,
     61                     userid_t userid)
     62 {
     63     size_t userid_len;
     64     char* userid_prefix;
     65     if (userid == 0) {
     66         userid_prefix = PRIMARY_USER_PREFIX;
     67         userid_len = 0;
     68     } else {
     69         userid_prefix = SECONDARY_USER_PREFIX;
     70         userid_len = snprintf(NULL, 0, "%d", userid);
     71     }
     72 
     73     const size_t prefix_len = android_data_dir.len + strlen(userid_prefix)
     74             + userid_len + 1 /*slash*/;
     75     char prefix[prefix_len + 1];
     76 
     77     char *dst = prefix;
     78     size_t dst_size = sizeof(prefix);
     79 
     80     if (append_and_increment(&dst, android_data_dir.path, &dst_size) < 0
     81             || append_and_increment(&dst, userid_prefix, &dst_size) < 0) {
     82         ALOGE("Error building prefix for APK path");
     83         return -1;
     84     }
     85 
     86     if (userid != 0) {
     87         int ret = snprintf(dst, dst_size, "%d/", userid);
     88         if (ret < 0 || (size_t) ret != userid_len + 1) {
     89             ALOGW("Error appending UID to APK path");
     90             return -1;
     91         }
     92     }
     93 
     94     dir_rec_t dir;
     95     dir.path = prefix;
     96     dir.len = prefix_len;
     97 
     98     return create_pkg_path_in_dir(path, &dir, pkgname, postfix);
     99 }
    100 
    101 /**
    102  * Create the path name for user data for a certain userid.
    103  * Returns 0 on success, and -1 on failure.
    104  */
    105 int create_user_path(char path[PKG_PATH_MAX],
    106                     userid_t userid)
    107 {
    108     size_t userid_len;
    109     char* userid_prefix;
    110     if (userid == 0) {
    111         userid_prefix = PRIMARY_USER_PREFIX;
    112         userid_len = 0;
    113     } else {
    114         userid_prefix = SECONDARY_USER_PREFIX;
    115         userid_len = snprintf(NULL, 0, "%d/", userid);
    116     }
    117 
    118     char *dst = path;
    119     size_t dst_size = PKG_PATH_MAX;
    120 
    121     if (append_and_increment(&dst, android_data_dir.path, &dst_size) < 0
    122             || append_and_increment(&dst, userid_prefix, &dst_size) < 0) {
    123         ALOGE("Error building prefix for user path");
    124         return -1;
    125     }
    126 
    127     if (userid != 0) {
    128         if (dst_size < userid_len + 1) {
    129             ALOGE("Error building user path");
    130             return -1;
    131         }
    132         int ret = snprintf(dst, dst_size, "%d/", userid);
    133         if (ret < 0 || (size_t) ret != userid_len) {
    134             ALOGE("Error appending userid to path");
    135             return -1;
    136         }
    137     }
    138     return 0;
    139 }
    140 
    141 /**
    142  * Create the path name for media for a certain userid.
    143  * Returns 0 on success, and -1 on failure.
    144  */
    145 int create_user_media_path(char path[PATH_MAX], userid_t userid) {
    146     if (snprintf(path, PATH_MAX, "%s%d", android_media_dir.path, userid) > PATH_MAX) {
    147         return -1;
    148     }
    149     return 0;
    150 }
    151 
    152 /**
    153  * Create the path name for config for a certain userid.
    154  * Returns 0 on success, and -1 on failure.
    155  */
    156 int create_user_config_path(char path[PATH_MAX], userid_t userid) {
    157     if (snprintf(path, PATH_MAX, "%s%d", "/data/misc/user/", userid) > PATH_MAX) {
    158         return -1;
    159     }
    160     return 0;
    161 }
    162 
    163 int create_move_path(char path[PKG_PATH_MAX],
    164     const char* pkgname,
    165     const char* leaf,
    166     userid_t userid)
    167 {
    168     if ((android_data_dir.len + strlen(PRIMARY_USER_PREFIX) + strlen(pkgname) + strlen(leaf) + 1)
    169             >= PKG_PATH_MAX) {
    170         return -1;
    171     }
    172 
    173     sprintf(path, "%s%s%s/%s", android_data_dir.path, PRIMARY_USER_PREFIX, pkgname, leaf);
    174     return 0;
    175 }
    176 
    177 /**
    178  * Checks whether the package name is valid. Returns -1 on error and
    179  * 0 on success.
    180  */
    181 int is_valid_package_name(const char* pkgname) {
    182     const char *x = pkgname;
    183     int alpha = -1;
    184 
    185     while (*x) {
    186         if (isalnum(*x) || (*x == '_')) {
    187                 /* alphanumeric or underscore are fine */
    188         } else if (*x == '.') {
    189             if ((x == pkgname) || (x[1] == '.') || (x[1] == 0)) {
    190                     /* periods must not be first, last, or doubled */
    191                 ALOGE("invalid package name '%s'\n", pkgname);
    192                 return -1;
    193             }
    194         } else if (*x == '-') {
    195             /* Suffix -X is fine to let versioning of packages.
    196                But whatever follows should be alphanumeric.*/
    197             alpha = 1;
    198         } else {
    199                 /* anything not A-Z, a-z, 0-9, _, or . is invalid */
    200             ALOGE("invalid package name '%s'\n", pkgname);
    201             return -1;
    202         }
    203 
    204         x++;
    205     }
    206 
    207     if (alpha == 1) {
    208         // Skip current character
    209         x++;
    210         while (*x) {
    211             if (!isalnum(*x)) {
    212                 ALOGE("invalid package name '%s' should include only numbers after -\n", pkgname);
    213                 return -1;
    214             }
    215             x++;
    216         }
    217     }
    218 
    219     return 0;
    220 }
    221 
    222 static int _delete_dir_contents(DIR *d,
    223                                 int (*exclusion_predicate)(const char *name, const int is_dir))
    224 {
    225     int result = 0;
    226     struct dirent *de;
    227     int dfd;
    228 
    229     dfd = dirfd(d);
    230 
    231     if (dfd < 0) return -1;
    232 
    233     while ((de = readdir(d))) {
    234         const char *name = de->d_name;
    235 
    236             /* check using the exclusion predicate, if provided */
    237         if (exclusion_predicate && exclusion_predicate(name, (de->d_type == DT_DIR))) {
    238             continue;
    239         }
    240 
    241         if (de->d_type == DT_DIR) {
    242             int r, subfd;
    243             DIR *subdir;
    244 
    245                 /* always skip "." and ".." */
    246             if (name[0] == '.') {
    247                 if (name[1] == 0) continue;
    248                 if ((name[1] == '.') && (name[2] == 0)) continue;
    249             }
    250 
    251             subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY);
    252             if (subfd < 0) {
    253                 ALOGE("Couldn't openat %s: %s\n", name, strerror(errno));
    254                 result = -1;
    255                 continue;
    256             }
    257             subdir = fdopendir(subfd);
    258             if (subdir == NULL) {
    259                 ALOGE("Couldn't fdopendir %s: %s\n", name, strerror(errno));
    260                 close(subfd);
    261                 result = -1;
    262                 continue;
    263             }
    264             if (_delete_dir_contents(subdir, exclusion_predicate)) {
    265                 result = -1;
    266             }
    267             closedir(subdir);
    268             if (unlinkat(dfd, name, AT_REMOVEDIR) < 0) {
    269                 ALOGE("Couldn't unlinkat %s: %s\n", name, strerror(errno));
    270                 result = -1;
    271             }
    272         } else {
    273             if (unlinkat(dfd, name, 0) < 0) {
    274                 ALOGE("Couldn't unlinkat %s: %s\n", name, strerror(errno));
    275                 result = -1;
    276             }
    277         }
    278     }
    279 
    280     return result;
    281 }
    282 
    283 int delete_dir_contents(const char *pathname,
    284                         int also_delete_dir,
    285                         int (*exclusion_predicate)(const char*, const int))
    286 {
    287     int res = 0;
    288     DIR *d;
    289 
    290     d = opendir(pathname);
    291     if (d == NULL) {
    292         ALOGE("Couldn't opendir %s: %s\n", pathname, strerror(errno));
    293         return -errno;
    294     }
    295     res = _delete_dir_contents(d, exclusion_predicate);
    296     closedir(d);
    297     if (also_delete_dir) {
    298         if (rmdir(pathname)) {
    299             ALOGE("Couldn't rmdir %s: %s\n", pathname, strerror(errno));
    300             res = -1;
    301         }
    302     }
    303     return res;
    304 }
    305 
    306 int delete_dir_contents_fd(int dfd, const char *name)
    307 {
    308     int fd, res;
    309     DIR *d;
    310 
    311     fd = openat(dfd, name, O_RDONLY | O_DIRECTORY);
    312     if (fd < 0) {
    313         ALOGE("Couldn't openat %s: %s\n", name, strerror(errno));
    314         return -1;
    315     }
    316     d = fdopendir(fd);
    317     if (d == NULL) {
    318         ALOGE("Couldn't fdopendir %s: %s\n", name, strerror(errno));
    319         close(fd);
    320         return -1;
    321     }
    322     res = _delete_dir_contents(d, 0);
    323     closedir(d);
    324     return res;
    325 }
    326 
    327 static int _copy_owner_permissions(int srcfd, int dstfd)
    328 {
    329     struct stat st;
    330     if (fstat(srcfd, &st) != 0) {
    331         return -1;
    332     }
    333     if (fchmod(dstfd, st.st_mode) != 0) {
    334         return -1;
    335     }
    336     return 0;
    337 }
    338 
    339 static int _copy_dir_files(int sdfd, int ddfd, uid_t owner, gid_t group)
    340 {
    341     int result = 0;
    342     if (_copy_owner_permissions(sdfd, ddfd) != 0) {
    343         ALOGE("_copy_dir_files failed to copy dir permissions\n");
    344     }
    345     if (fchown(ddfd, owner, group) != 0) {
    346         ALOGE("_copy_dir_files failed to change dir owner\n");
    347     }
    348 
    349     DIR *ds = fdopendir(sdfd);
    350     if (ds == NULL) {
    351         ALOGE("Couldn't fdopendir: %s\n", strerror(errno));
    352         return -1;
    353     }
    354     struct dirent *de;
    355     while ((de = readdir(ds))) {
    356         if (de->d_type != DT_REG) {
    357             continue;
    358         }
    359 
    360         const char *name = de->d_name;
    361         int fsfd = openat(sdfd, name, O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
    362         int fdfd = openat(ddfd, name, O_WRONLY | O_NOFOLLOW | O_CLOEXEC | O_CREAT, 0600);
    363         if (fsfd == -1 || fdfd == -1) {
    364             ALOGW("Couldn't copy %s: %s\n", name, strerror(errno));
    365         } else {
    366             if (_copy_owner_permissions(fsfd, fdfd) != 0) {
    367                 ALOGE("Failed to change file permissions\n");
    368             }
    369             if (fchown(fdfd, owner, group) != 0) {
    370                 ALOGE("Failed to change file owner\n");
    371             }
    372 
    373             char buf[8192];
    374             ssize_t size;
    375             while ((size = read(fsfd, buf, sizeof(buf))) > 0) {
    376                 write(fdfd, buf, size);
    377             }
    378             if (size < 0) {
    379                 ALOGW("Couldn't copy %s: %s\n", name, strerror(errno));
    380                 result = -1;
    381             }
    382         }
    383         close(fdfd);
    384         close(fsfd);
    385     }
    386 
    387     return result;
    388 }
    389 
    390 int copy_dir_files(const char *srcname,
    391                    const char *dstname,
    392                    uid_t owner,
    393                    uid_t group)
    394 {
    395     int res = 0;
    396     DIR *ds = NULL;
    397     DIR *dd = NULL;
    398 
    399     ds = opendir(srcname);
    400     if (ds == NULL) {
    401         ALOGE("Couldn't opendir %s: %s\n", srcname, strerror(errno));
    402         return -errno;
    403     }
    404 
    405     mkdir(dstname, 0600);
    406     dd = opendir(dstname);
    407     if (dd == NULL) {
    408         ALOGE("Couldn't opendir %s: %s\n", dstname, strerror(errno));
    409         closedir(ds);
    410         return -errno;
    411     }
    412 
    413     int sdfd = dirfd(ds);
    414     int ddfd = dirfd(dd);
    415     if (sdfd != -1 && ddfd != -1) {
    416         res = _copy_dir_files(sdfd, ddfd, owner, group);
    417     } else {
    418         res = -errno;
    419     }
    420     closedir(dd);
    421     closedir(ds);
    422     return res;
    423 }
    424 
    425 int lookup_media_dir(char basepath[PATH_MAX], const char *dir)
    426 {
    427     DIR *d;
    428     struct dirent *de;
    429     struct stat s;
    430     char* dirpos = basepath + strlen(basepath);
    431 
    432     if ((*(dirpos-1)) != '/') {
    433         *dirpos = '/';
    434         dirpos++;
    435     }
    436 
    437     CACHE_NOISY(ALOGI("Looking up %s in %s\n", dir, basepath));
    438     // Verify the path won't extend beyond our buffer, to avoid
    439     // repeated checking later.
    440     if ((dirpos-basepath+strlen(dir)) >= (PATH_MAX-1)) {
    441         ALOGW("Path exceeds limit: %s%s", basepath, dir);
    442         return -1;
    443     }
    444 
    445     // First, can we find this directory with the case that is given?
    446     strcpy(dirpos, dir);
    447     if (stat(basepath, &s) >= 0) {
    448         CACHE_NOISY(ALOGI("Found direct: %s\n", basepath));
    449         return 0;
    450     }
    451 
    452     // Not found with that case...  search through all entries to find
    453     // one that matches regardless of case.
    454     *dirpos = 0;
    455 
    456     d = opendir(basepath);
    457     if (d == NULL) {
    458         return -1;
    459     }
    460 
    461     while ((de = readdir(d))) {
    462         if (strcasecmp(de->d_name, dir) == 0) {
    463             strcpy(dirpos, de->d_name);
    464             closedir(d);
    465             CACHE_NOISY(ALOGI("Found search: %s\n", basepath));
    466             return 0;
    467         }
    468     }
    469 
    470     ALOGW("Couldn't find %s in %s", dir, basepath);
    471     closedir(d);
    472     return -1;
    473 }
    474 
    475 int64_t data_disk_free()
    476 {
    477     struct statfs sfs;
    478     if (statfs(android_data_dir.path, &sfs) == 0) {
    479         return sfs.f_bavail * sfs.f_bsize;
    480     } else {
    481         ALOGE("Couldn't statfs %s: %s\n", android_data_dir.path, strerror(errno));
    482         return -1;
    483     }
    484 }
    485 
    486 cache_t* start_cache_collection()
    487 {
    488     cache_t* cache = (cache_t*)calloc(1, sizeof(cache_t));
    489     return cache;
    490 }
    491 
    492 #define CACHE_BLOCK_SIZE (512*1024)
    493 
    494 static void* _cache_malloc(cache_t* cache, size_t len)
    495 {
    496     len = (len+3)&~3;
    497     if (len > (CACHE_BLOCK_SIZE/2)) {
    498         // It doesn't make sense to try to put this allocation into one
    499         // of our blocks, because it is so big.  Instead, make a new dedicated
    500         // block for it.
    501         int8_t* res = (int8_t*)malloc(len+sizeof(void*));
    502         if (res == NULL) {
    503             return NULL;
    504         }
    505         CACHE_NOISY(ALOGI("Allocated large cache mem block: %p size %d", res, len));
    506         // Link it into our list of blocks, not disrupting the current one.
    507         if (cache->memBlocks == NULL) {
    508             *(void**)res = NULL;
    509             cache->memBlocks = res;
    510         } else {
    511             *(void**)res = *(void**)cache->memBlocks;
    512             *(void**)cache->memBlocks = res;
    513         }
    514         return res + sizeof(void*);
    515     }
    516     int8_t* res = cache->curMemBlockAvail;
    517     int8_t* nextPos = res + len;
    518     if (cache->memBlocks == NULL || nextPos > cache->curMemBlockEnd) {
    519         int8_t* newBlock = malloc(CACHE_BLOCK_SIZE);
    520         if (newBlock == NULL) {
    521             return NULL;
    522         }
    523         CACHE_NOISY(ALOGI("Allocated new cache mem block: %p", newBlock));
    524         *(void**)newBlock = cache->memBlocks;
    525         cache->memBlocks = newBlock;
    526         res = cache->curMemBlockAvail = newBlock + sizeof(void*);
    527         cache->curMemBlockEnd = newBlock + CACHE_BLOCK_SIZE;
    528         nextPos = res + len;
    529     }
    530     CACHE_NOISY(ALOGI("cache_malloc: ret %p size %d, block=%p, nextPos=%p",
    531             res, len, cache->memBlocks, nextPos));
    532     cache->curMemBlockAvail = nextPos;
    533     return res;
    534 }
    535 
    536 static void* _cache_realloc(cache_t* cache, void* cur, size_t origLen, size_t len)
    537 {
    538     // This isn't really a realloc, but it is good enough for our purposes here.
    539     void* alloc = _cache_malloc(cache, len);
    540     if (alloc != NULL && cur != NULL) {
    541         memcpy(alloc, cur, origLen < len ? origLen : len);
    542     }
    543     return alloc;
    544 }
    545 
    546 static void _inc_num_cache_collected(cache_t* cache)
    547 {
    548     cache->numCollected++;
    549     if ((cache->numCollected%20000) == 0) {
    550         ALOGI("Collected cache so far: %zd directories, %zd files",
    551             cache->numDirs, cache->numFiles);
    552     }
    553 }
    554 
    555 static cache_dir_t* _add_cache_dir_t(cache_t* cache, cache_dir_t* parent, const char *name)
    556 {
    557     size_t nameLen = strlen(name);
    558     cache_dir_t* dir = (cache_dir_t*)_cache_malloc(cache, sizeof(cache_dir_t)+nameLen+1);
    559     if (dir != NULL) {
    560         dir->parent = parent;
    561         dir->childCount = 0;
    562         dir->hiddenCount = 0;
    563         dir->deleted = 0;
    564         strcpy(dir->name, name);
    565         if (cache->numDirs >= cache->availDirs) {
    566             size_t newAvail = cache->availDirs < 1000 ? 1000 : cache->availDirs*2;
    567             cache_dir_t** newDirs = (cache_dir_t**)_cache_realloc(cache, cache->dirs,
    568                     cache->availDirs*sizeof(cache_dir_t*), newAvail*sizeof(cache_dir_t*));
    569             if (newDirs == NULL) {
    570                 ALOGE("Failure growing cache dirs array for %s\n", name);
    571                 return NULL;
    572             }
    573             cache->availDirs = newAvail;
    574             cache->dirs = newDirs;
    575         }
    576         cache->dirs[cache->numDirs] = dir;
    577         cache->numDirs++;
    578         if (parent != NULL) {
    579             parent->childCount++;
    580         }
    581         _inc_num_cache_collected(cache);
    582     } else {
    583         ALOGE("Failure allocating cache_dir_t for %s\n", name);
    584     }
    585     return dir;
    586 }
    587 
    588 static cache_file_t* _add_cache_file_t(cache_t* cache, cache_dir_t* dir, time_t modTime,
    589         const char *name)
    590 {
    591     size_t nameLen = strlen(name);
    592     cache_file_t* file = (cache_file_t*)_cache_malloc(cache, sizeof(cache_file_t)+nameLen+1);
    593     if (file != NULL) {
    594         file->dir = dir;
    595         file->modTime = modTime;
    596         strcpy(file->name, name);
    597         if (cache->numFiles >= cache->availFiles) {
    598             size_t newAvail = cache->availFiles < 1000 ? 1000 : cache->availFiles*2;
    599             cache_file_t** newFiles = (cache_file_t**)_cache_realloc(cache, cache->files,
    600                     cache->availFiles*sizeof(cache_file_t*), newAvail*sizeof(cache_file_t*));
    601             if (newFiles == NULL) {
    602                 ALOGE("Failure growing cache file array for %s\n", name);
    603                 return NULL;
    604             }
    605             cache->availFiles = newAvail;
    606             cache->files = newFiles;
    607         }
    608         CACHE_NOISY(ALOGI("Setting file %p at position %d in array %p", file,
    609                 cache->numFiles, cache->files));
    610         cache->files[cache->numFiles] = file;
    611         cache->numFiles++;
    612         dir->childCount++;
    613         _inc_num_cache_collected(cache);
    614     } else {
    615         ALOGE("Failure allocating cache_file_t for %s\n", name);
    616     }
    617     return file;
    618 }
    619 
    620 static int _add_cache_files(cache_t *cache, cache_dir_t *parentDir, const char *dirName,
    621         DIR* dir, char *pathBase, char *pathPos, size_t pathAvailLen)
    622 {
    623     struct dirent *de;
    624     cache_dir_t* cacheDir = NULL;
    625     int dfd;
    626 
    627     CACHE_NOISY(ALOGI("_add_cache_files: parent=%p dirName=%s dir=%p pathBase=%s",
    628             parentDir, dirName, dir, pathBase));
    629 
    630     dfd = dirfd(dir);
    631 
    632     if (dfd < 0) return 0;
    633 
    634     // Sub-directories always get added to the data structure, so if they
    635     // are empty we will know about them to delete them later.
    636     cacheDir = _add_cache_dir_t(cache, parentDir, dirName);
    637 
    638     while ((de = readdir(dir))) {
    639         const char *name = de->d_name;
    640 
    641         if (de->d_type == DT_DIR) {
    642             int subfd;
    643             DIR *subdir;
    644 
    645                 /* always skip "." and ".." */
    646             if (name[0] == '.') {
    647                 if (name[1] == 0) continue;
    648                 if ((name[1] == '.') && (name[2] == 0)) continue;
    649             }
    650 
    651             subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY);
    652             if (subfd < 0) {
    653                 ALOGE("Couldn't openat %s: %s\n", name, strerror(errno));
    654                 continue;
    655             }
    656             subdir = fdopendir(subfd);
    657             if (subdir == NULL) {
    658                 ALOGE("Couldn't fdopendir %s: %s\n", name, strerror(errno));
    659                 close(subfd);
    660                 continue;
    661             }
    662             if (cacheDir == NULL) {
    663                 cacheDir = _add_cache_dir_t(cache, parentDir, dirName);
    664             }
    665             if (cacheDir != NULL) {
    666                 // Update pathBase for the new path...  this may change dirName
    667                 // if that is also pointing to the path, but we are done with it
    668                 // now.
    669                 size_t finallen = snprintf(pathPos, pathAvailLen, "/%s", name);
    670                 CACHE_NOISY(ALOGI("Collecting dir %s\n", pathBase));
    671                 if (finallen < pathAvailLen) {
    672                     _add_cache_files(cache, cacheDir, name, subdir, pathBase,
    673                             pathPos+finallen, pathAvailLen-finallen);
    674                 } else {
    675                     // Whoops, the final path is too long!  We'll just delete
    676                     // this directory.
    677                     ALOGW("Cache dir %s truncated in path %s; deleting dir\n",
    678                             name, pathBase);
    679                     _delete_dir_contents(subdir, NULL);
    680                     if (unlinkat(dfd, name, AT_REMOVEDIR) < 0) {
    681                         ALOGE("Couldn't unlinkat %s: %s\n", name, strerror(errno));
    682                     }
    683                 }
    684             }
    685             closedir(subdir);
    686         } else if (de->d_type == DT_REG) {
    687             // Skip files that start with '.'; they will be deleted if
    688             // their entire directory is deleted.  This allows for metadata
    689             // like ".nomedia" to remain in the directory until the entire
    690             // directory is deleted.
    691             if (cacheDir == NULL) {
    692                 cacheDir = _add_cache_dir_t(cache, parentDir, dirName);
    693             }
    694             if (name[0] == '.') {
    695                 cacheDir->hiddenCount++;
    696                 continue;
    697             }
    698             if (cacheDir != NULL) {
    699                 // Build final full path for file...  this may change dirName
    700                 // if that is also pointing to the path, but we are done with it
    701                 // now.
    702                 size_t finallen = snprintf(pathPos, pathAvailLen, "/%s", name);
    703                 CACHE_NOISY(ALOGI("Collecting file %s\n", pathBase));
    704                 if (finallen < pathAvailLen) {
    705                     struct stat s;
    706                     if (stat(pathBase, &s) >= 0) {
    707                         _add_cache_file_t(cache, cacheDir, s.st_mtime, name);
    708                     } else {
    709                         ALOGW("Unable to stat cache file %s; deleting\n", pathBase);
    710                         if (unlink(pathBase) < 0) {
    711                             ALOGE("Couldn't unlink %s: %s\n", pathBase, strerror(errno));
    712                         }
    713                     }
    714                 } else {
    715                     // Whoops, the final path is too long!  We'll just delete
    716                     // this file.
    717                     ALOGW("Cache file %s truncated in path %s; deleting\n",
    718                             name, pathBase);
    719                     if (unlinkat(dfd, name, 0) < 0) {
    720                         *pathPos = 0;
    721                         ALOGE("Couldn't unlinkat %s in %s: %s\n", name, pathBase,
    722                                 strerror(errno));
    723                     }
    724                 }
    725             }
    726         } else {
    727             cacheDir->hiddenCount++;
    728         }
    729     }
    730     return 0;
    731 }
    732 
    733 void add_cache_files(cache_t* cache, const char *basepath, const char *cachedir)
    734 {
    735     DIR *d;
    736     struct dirent *de;
    737     char dirname[PATH_MAX];
    738 
    739     CACHE_NOISY(ALOGI("add_cache_files: base=%s cachedir=%s\n", basepath, cachedir));
    740 
    741     d = opendir(basepath);
    742     if (d == NULL) {
    743         return;
    744     }
    745 
    746     while ((de = readdir(d))) {
    747         if (de->d_type == DT_DIR) {
    748             DIR* subdir;
    749             const char *name = de->d_name;
    750             char* pathpos;
    751 
    752                 /* always skip "." and ".." */
    753             if (name[0] == '.') {
    754                 if (name[1] == 0) continue;
    755                 if ((name[1] == '.') && (name[2] == 0)) continue;
    756             }
    757 
    758             strcpy(dirname, basepath);
    759             pathpos = dirname + strlen(dirname);
    760             if ((*(pathpos-1)) != '/') {
    761                 *pathpos = '/';
    762                 pathpos++;
    763                 *pathpos = 0;
    764             }
    765             if (cachedir != NULL) {
    766                 snprintf(pathpos, sizeof(dirname)-(pathpos-dirname), "%s/%s", name, cachedir);
    767             } else {
    768                 snprintf(pathpos, sizeof(dirname)-(pathpos-dirname), "%s", name);
    769             }
    770             CACHE_NOISY(ALOGI("Adding cache files from dir: %s\n", dirname));
    771             subdir = opendir(dirname);
    772             if (subdir != NULL) {
    773                 size_t dirnameLen = strlen(dirname);
    774                 _add_cache_files(cache, NULL, dirname, subdir, dirname, dirname+dirnameLen,
    775                         PATH_MAX - dirnameLen);
    776                 closedir(subdir);
    777             }
    778         }
    779     }
    780 
    781     closedir(d);
    782 }
    783 
    784 static char *create_dir_path(char path[PATH_MAX], cache_dir_t* dir)
    785 {
    786     char *pos = path;
    787     if (dir->parent != NULL) {
    788         pos = create_dir_path(path, dir->parent);
    789     }
    790     // Note that we don't need to worry about going beyond the buffer,
    791     // since when we were constructing the cache entries our maximum
    792     // buffer size for full paths was PATH_MAX.
    793     strcpy(pos, dir->name);
    794     pos += strlen(pos);
    795     *pos = '/';
    796     pos++;
    797     *pos = 0;
    798     return pos;
    799 }
    800 
    801 static void delete_cache_dir(char path[PATH_MAX], cache_dir_t* dir)
    802 {
    803     if (dir->parent != NULL) {
    804         create_dir_path(path, dir);
    805         ALOGI("DEL DIR %s\n", path);
    806         if (dir->hiddenCount <= 0) {
    807             if (rmdir(path)) {
    808                 ALOGE("Couldn't rmdir %s: %s\n", path, strerror(errno));
    809                 return;
    810             }
    811         } else {
    812             // The directory contains hidden files so we need to delete
    813             // them along with the directory itself.
    814             if (delete_dir_contents(path, 1, NULL)) {
    815                 return;
    816             }
    817         }
    818         dir->parent->childCount--;
    819         dir->deleted = 1;
    820         if (dir->parent->childCount <= 0) {
    821             delete_cache_dir(path, dir->parent);
    822         }
    823     } else if (dir->hiddenCount > 0) {
    824         // This is a root directory, but it has hidden files.  Get rid of
    825         // all of those files, but not the directory itself.
    826         create_dir_path(path, dir);
    827         ALOGI("DEL CONTENTS %s\n", path);
    828         delete_dir_contents(path, 0, NULL);
    829     }
    830 }
    831 
    832 static int cache_modtime_sort(const void *lhsP, const void *rhsP)
    833 {
    834     const cache_file_t *lhs = *(const cache_file_t**)lhsP;
    835     const cache_file_t *rhs = *(const cache_file_t**)rhsP;
    836     return lhs->modTime < rhs->modTime ? -1 : (lhs->modTime > rhs->modTime ? 1 : 0);
    837 }
    838 
    839 void clear_cache_files(cache_t* cache, int64_t free_size)
    840 {
    841     size_t i;
    842     int skip = 0;
    843     char path[PATH_MAX];
    844 
    845     ALOGI("Collected cache files: %zd directories, %zd files",
    846         cache->numDirs, cache->numFiles);
    847 
    848     CACHE_NOISY(ALOGI("Sorting files..."));
    849     qsort(cache->files, cache->numFiles, sizeof(cache_file_t*),
    850             cache_modtime_sort);
    851 
    852     CACHE_NOISY(ALOGI("Cleaning empty directories..."));
    853     for (i=cache->numDirs; i>0; i--) {
    854         cache_dir_t* dir = cache->dirs[i-1];
    855         if (dir->childCount <= 0 && !dir->deleted) {
    856             delete_cache_dir(path, dir);
    857         }
    858     }
    859 
    860     CACHE_NOISY(ALOGI("Trimming files..."));
    861     for (i=0; i<cache->numFiles; i++) {
    862         skip++;
    863         if (skip > 10) {
    864             if (data_disk_free() > free_size) {
    865                 return;
    866             }
    867             skip = 0;
    868         }
    869         cache_file_t* file = cache->files[i];
    870         strcpy(create_dir_path(path, file->dir), file->name);
    871         ALOGI("DEL (mod %d) %s\n", (int)file->modTime, path);
    872         if (unlink(path) < 0) {
    873             ALOGE("Couldn't unlink %s: %s\n", path, strerror(errno));
    874         }
    875         file->dir->childCount--;
    876         if (file->dir->childCount <= 0) {
    877             delete_cache_dir(path, file->dir);
    878         }
    879     }
    880 }
    881 
    882 void finish_cache_collection(cache_t* cache)
    883 {
    884     size_t i;
    885 
    886     CACHE_NOISY(ALOGI("clear_cache_files: %d dirs, %d files\n", cache->numDirs, cache->numFiles));
    887     CACHE_NOISY(
    888         for (i=0; i<cache->numDirs; i++) {
    889             cache_dir_t* dir = cache->dirs[i];
    890             ALOGI("dir #%d: %p %s parent=%p\n", i, dir, dir->name, dir->parent);
    891         })
    892     CACHE_NOISY(
    893         for (i=0; i<cache->numFiles; i++) {
    894             cache_file_t* file = cache->files[i];
    895             ALOGI("file #%d: %p %s time=%d dir=%p\n", i, file, file->name,
    896                     (int)file->modTime, file->dir);
    897         })
    898     void* block = cache->memBlocks;
    899     while (block != NULL) {
    900         void* nextBlock = *(void**)block;
    901         CACHE_NOISY(ALOGI("Freeing cache mem block: %p", block));
    902         free(block);
    903         block = nextBlock;
    904     }
    905     free(cache);
    906 }
    907 
    908 /**
    909  * Validate that the path is valid in the context of the provided directory.
    910  * The path is allowed to have at most one subdirectory and no indirections
    911  * to top level directories (i.e. have "..").
    912  */
    913 static int validate_path(const dir_rec_t* dir, const char* path) {
    914     size_t dir_len = dir->len;
    915     const char* subdir = strchr(path + dir_len, '/');
    916 
    917     // Only allow the path to have at most one subdirectory.
    918     if (subdir != NULL) {
    919         ++subdir;
    920         if (strchr(subdir, '/') != NULL) {
    921             ALOGE("invalid apk path '%s' (subdir?)\n", path);
    922             return -1;
    923         }
    924     }
    925 
    926     // Directories can't have a period directly after the directory markers to prevent "..".
    927     if ((path[dir_len] == '.') || ((subdir != NULL) && (*subdir == '.'))) {
    928         ALOGE("invalid apk path '%s' (trickery)\n", path);
    929         return -1;
    930     }
    931 
    932     return 0;
    933 }
    934 
    935 /**
    936  * Checks whether a path points to a system app (.apk file). Returns 0
    937  * if it is a system app or -1 if it is not.
    938  */
    939 int validate_system_app_path(const char* path) {
    940     size_t i;
    941 
    942     for (i = 0; i < android_system_dirs.count; i++) {
    943         const size_t dir_len = android_system_dirs.dirs[i].len;
    944         if (!strncmp(path, android_system_dirs.dirs[i].path, dir_len)) {
    945             return validate_path(android_system_dirs.dirs + i, path);
    946         }
    947     }
    948 
    949     return -1;
    950 }
    951 
    952 /**
    953  * Get the contents of a environment variable that contains a path. Caller
    954  * owns the string that is inserted into the directory record. Returns
    955  * 0 on success and -1 on error.
    956  */
    957 int get_path_from_env(dir_rec_t* rec, const char* var) {
    958     const char* path = getenv(var);
    959     int ret = get_path_from_string(rec, path);
    960     if (ret < 0) {
    961         ALOGW("Problem finding value for environment variable %s\n", var);
    962     }
    963     return ret;
    964 }
    965 
    966 /**
    967  * Puts the string into the record as a directory. Appends '/' to the end
    968  * of all paths. Caller owns the string that is inserted into the directory
    969  * record. A null value will result in an error.
    970  *
    971  * Returns 0 on success and -1 on error.
    972  */
    973 int get_path_from_string(dir_rec_t* rec, const char* path) {
    974     if (path == NULL) {
    975         return -1;
    976     } else {
    977         const size_t path_len = strlen(path);
    978         if (path_len <= 0) {
    979             return -1;
    980         }
    981 
    982         // Make sure path is absolute.
    983         if (path[0] != '/') {
    984             return -1;
    985         }
    986 
    987         if (path[path_len - 1] == '/') {
    988             // Path ends with a forward slash. Make our own copy.
    989 
    990             rec->path = strdup(path);
    991             if (rec->path == NULL) {
    992                 return -1;
    993             }
    994 
    995             rec->len = path_len;
    996         } else {
    997             // Path does not end with a slash. Generate a new string.
    998             char *dst;
    999 
   1000             // Add space for slash and terminating null.
   1001             size_t dst_size = path_len + 2;
   1002 
   1003             rec->path = malloc(dst_size);
   1004             if (rec->path == NULL) {
   1005                 return -1;
   1006             }
   1007 
   1008             dst = rec->path;
   1009 
   1010             if (append_and_increment(&dst, path, &dst_size) < 0
   1011                     || append_and_increment(&dst, "/", &dst_size)) {
   1012                 ALOGE("Error canonicalizing path");
   1013                 return -1;
   1014             }
   1015 
   1016             rec->len = dst - rec->path;
   1017         }
   1018     }
   1019     return 0;
   1020 }
   1021 
   1022 int copy_and_append(dir_rec_t* dst, const dir_rec_t* src, const char* suffix) {
   1023     dst->len = src->len + strlen(suffix);
   1024     const size_t dstSize = dst->len + 1;
   1025     dst->path = (char*) malloc(dstSize);
   1026 
   1027     if (dst->path == NULL
   1028             || snprintf(dst->path, dstSize, "%s%s", src->path, suffix)
   1029                     != (ssize_t) dst->len) {
   1030         ALOGE("Could not allocate memory to hold appended path; aborting\n");
   1031         return -1;
   1032     }
   1033 
   1034     return 0;
   1035 }
   1036 
   1037 /**
   1038  * Check whether path points to a valid path for an APK file. Only one level of
   1039  * subdirectory names is allowed. Returns -1 when an invalid path is encountered
   1040  * and 0 when a valid path is encountered.
   1041  */
   1042 int validate_apk_path(const char *path)
   1043 {
   1044     const dir_rec_t* dir = NULL;
   1045 
   1046     if (!strncmp(path, android_app_dir.path, android_app_dir.len)) {
   1047         dir = &android_app_dir;
   1048     } else if (!strncmp(path, android_app_private_dir.path, android_app_private_dir.len)) {
   1049         dir = &android_app_private_dir;
   1050     } else if (!strncmp(path, android_asec_dir.path, android_asec_dir.len)) {
   1051         dir = &android_asec_dir;
   1052     } else {
   1053         return -1;
   1054     }
   1055 
   1056     return validate_path(dir, path);
   1057 }
   1058 
   1059 int append_and_increment(char** dst, const char* src, size_t* dst_size) {
   1060     ssize_t ret = strlcpy(*dst, src, *dst_size);
   1061     if (ret < 0 || (size_t) ret >= *dst_size) {
   1062         return -1;
   1063     }
   1064     *dst += ret;
   1065     *dst_size -= ret;
   1066     return 0;
   1067 }
   1068 
   1069 char *build_string2(char *s1, char *s2) {
   1070     if (s1 == NULL || s2 == NULL) return NULL;
   1071 
   1072     int len_s1 = strlen(s1);
   1073     int len_s2 = strlen(s2);
   1074     int len = len_s1 + len_s2 + 1;
   1075     char *result = malloc(len);
   1076     if (result == NULL) return NULL;
   1077 
   1078     strcpy(result, s1);
   1079     strcpy(result + len_s1, s2);
   1080 
   1081     return result;
   1082 }
   1083 
   1084 char *build_string3(char *s1, char *s2, char *s3) {
   1085     if (s1 == NULL || s2 == NULL || s3 == NULL) return NULL;
   1086 
   1087     int len_s1 = strlen(s1);
   1088     int len_s2 = strlen(s2);
   1089     int len_s3 = strlen(s3);
   1090     int len = len_s1 + len_s2 + len_s3 + 1;
   1091     char *result = malloc(len);
   1092     if (result == NULL) return NULL;
   1093 
   1094     strcpy(result, s1);
   1095     strcpy(result + len_s1, s2);
   1096     strcpy(result + len_s1 + len_s2, s3);
   1097 
   1098     return result;
   1099 }
   1100 
   1101 /* Ensure that /data/media directories are prepared for given user. */
   1102 int ensure_media_user_dirs(userid_t userid) {
   1103     char media_user_path[PATH_MAX];
   1104     char path[PATH_MAX];
   1105 
   1106     // Ensure /data/media/<userid> exists
   1107     create_user_media_path(media_user_path, userid);
   1108     if (fs_prepare_dir(media_user_path, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) {
   1109         return -1;
   1110     }
   1111 
   1112     return 0;
   1113 }
   1114 
   1115 int ensure_config_user_dirs(userid_t userid) {
   1116     char config_user_path[PATH_MAX];
   1117     char path[PATH_MAX];
   1118 
   1119     // writable by system, readable by any app within the same user
   1120     const int uid = multiuser_get_uid(userid, AID_SYSTEM);
   1121     const int gid = multiuser_get_uid(userid, AID_EVERYBODY);
   1122 
   1123     // Ensure /data/misc/user/<userid> exists
   1124     create_user_config_path(config_user_path, userid);
   1125     if (fs_prepare_dir(config_user_path, 0750, uid, gid) == -1) {
   1126         return -1;
   1127     }
   1128 
   1129    return 0;
   1130 }
   1131 
   1132 int create_profile_file(const char *pkgname, gid_t gid) {
   1133     const char *profile_dir = DALVIK_CACHE_PREFIX "profiles";
   1134     char profile_file[PKG_PATH_MAX];
   1135 
   1136     snprintf(profile_file, sizeof(profile_file), "%s/%s", profile_dir, pkgname);
   1137 
   1138     // The 'system' user needs to be able to read the profile to determine if dex2oat
   1139     // needs to be run.  This is done in dalvik.system.DexFile.isDexOptNeededInternal().  So
   1140     // we assign ownership to AID_SYSTEM and ensure it's not world-readable.
   1141 
   1142     int fd = open(profile_file, O_WRONLY | O_CREAT | O_NOFOLLOW | O_CLOEXEC, 0660);
   1143 
   1144     // Always set the uid/gid/permissions. The file could have been previously created
   1145     // with different permissions.
   1146     if (fd >= 0) {
   1147         if (fchown(fd, AID_SYSTEM, gid) < 0) {
   1148             ALOGE("cannot chown profile file '%s': %s\n", profile_file, strerror(errno));
   1149             close(fd);
   1150             unlink(profile_file);
   1151             return -1;
   1152         }
   1153 
   1154         if (fchmod(fd, 0660) < 0) {
   1155             ALOGE("cannot chmod profile file '%s': %s\n", profile_file, strerror(errno));
   1156             close(fd);
   1157             unlink(profile_file);
   1158             return -1;
   1159         }
   1160         close(fd);
   1161     }
   1162     return 0;
   1163 }
   1164 
   1165 void remove_profile_file(const char *pkgname) {
   1166     char profile_file[PKG_PATH_MAX];
   1167     snprintf(profile_file, sizeof(profile_file), "%s/%s", DALVIK_CACHE_PREFIX "profiles", pkgname);
   1168     unlink(profile_file);
   1169 }
   1170