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 <sys/capability.h>
     18 #include "installd.h"
     19 #include <diskusage/dirsize.h>
     20 #include <selinux/android.h>
     21 
     22 /* Directory records that are used in execution of commands. */
     23 dir_rec_t android_data_dir;
     24 dir_rec_t android_asec_dir;
     25 dir_rec_t android_app_dir;
     26 dir_rec_t android_app_private_dir;
     27 dir_rec_t android_app_lib_dir;
     28 dir_rec_t android_media_dir;
     29 dir_rec_array_t android_system_dirs;
     30 
     31 int install(const char *pkgname, uid_t uid, gid_t gid, const char *seinfo)
     32 {
     33     char pkgdir[PKG_PATH_MAX];
     34     char libsymlink[PKG_PATH_MAX];
     35     char applibdir[PKG_PATH_MAX];
     36     struct stat libStat;
     37 
     38     if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) {
     39         ALOGE("invalid uid/gid: %d %d\n", uid, gid);
     40         return -1;
     41     }
     42 
     43     if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, 0)) {
     44         ALOGE("cannot create package path\n");
     45         return -1;
     46     }
     47 
     48     if (create_pkg_path(libsymlink, pkgname, PKG_LIB_POSTFIX, 0)) {
     49         ALOGE("cannot create package lib symlink origin path\n");
     50         return -1;
     51     }
     52 
     53     if (create_pkg_path_in_dir(applibdir, &android_app_lib_dir, pkgname, PKG_DIR_POSTFIX)) {
     54         ALOGE("cannot create package lib symlink dest path\n");
     55         return -1;
     56     }
     57 
     58     if (mkdir(pkgdir, 0751) < 0) {
     59         ALOGE("cannot create dir '%s': %s\n", pkgdir, strerror(errno));
     60         return -1;
     61     }
     62     if (chmod(pkgdir, 0751) < 0) {
     63         ALOGE("cannot chmod dir '%s': %s\n", pkgdir, strerror(errno));
     64         unlink(pkgdir);
     65         return -1;
     66     }
     67 
     68     if (lstat(libsymlink, &libStat) < 0) {
     69         if (errno != ENOENT) {
     70             ALOGE("couldn't stat lib dir: %s\n", strerror(errno));
     71             return -1;
     72         }
     73     } else {
     74         if (S_ISDIR(libStat.st_mode)) {
     75             if (delete_dir_contents(libsymlink, 1, 0) < 0) {
     76                 ALOGE("couldn't delete lib directory during install for: %s", libsymlink);
     77                 return -1;
     78             }
     79         } else if (S_ISLNK(libStat.st_mode)) {
     80             if (unlink(libsymlink) < 0) {
     81                 ALOGE("couldn't unlink lib directory during install for: %s", libsymlink);
     82                 return -1;
     83             }
     84         }
     85     }
     86 
     87     if (symlink(applibdir, libsymlink) < 0) {
     88         ALOGE("couldn't symlink directory '%s' -> '%s': %s\n", libsymlink, applibdir,
     89                 strerror(errno));
     90         unlink(pkgdir);
     91         return -1;
     92     }
     93 
     94     if (selinux_android_setfilecon2(pkgdir, pkgname, seinfo, uid) < 0) {
     95         ALOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno));
     96         unlink(libsymlink);
     97         unlink(pkgdir);
     98         return -errno;
     99     }
    100 
    101     if (chown(pkgdir, uid, gid) < 0) {
    102         ALOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno));
    103         unlink(libsymlink);
    104         unlink(pkgdir);
    105         return -1;
    106     }
    107 
    108     return 0;
    109 }
    110 
    111 int uninstall(const char *pkgname, userid_t userid)
    112 {
    113     char pkgdir[PKG_PATH_MAX];
    114 
    115     if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, userid))
    116         return -1;
    117 
    118     /* delete contents AND directory, no exceptions */
    119     return delete_dir_contents(pkgdir, 1, NULL);
    120 }
    121 
    122 int renamepkg(const char *oldpkgname, const char *newpkgname)
    123 {
    124     char oldpkgdir[PKG_PATH_MAX];
    125     char newpkgdir[PKG_PATH_MAX];
    126 
    127     if (create_pkg_path(oldpkgdir, oldpkgname, PKG_DIR_POSTFIX, 0))
    128         return -1;
    129     if (create_pkg_path(newpkgdir, newpkgname, PKG_DIR_POSTFIX, 0))
    130         return -1;
    131 
    132     if (rename(oldpkgdir, newpkgdir) < 0) {
    133         ALOGE("cannot rename dir '%s' to '%s': %s\n", oldpkgdir, newpkgdir, strerror(errno));
    134         return -errno;
    135     }
    136     return 0;
    137 }
    138 
    139 int fix_uid(const char *pkgname, uid_t uid, gid_t gid)
    140 {
    141     char pkgdir[PKG_PATH_MAX];
    142     struct stat s;
    143     int rc = 0;
    144 
    145     if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) {
    146         ALOGE("invalid uid/gid: %d %d\n", uid, gid);
    147         return -1;
    148     }
    149 
    150     if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, 0)) {
    151         ALOGE("cannot create package path\n");
    152         return -1;
    153     }
    154 
    155     if (stat(pkgdir, &s) < 0) return -1;
    156 
    157     if (s.st_uid != 0 || s.st_gid != 0) {
    158         ALOGE("fixing uid of non-root pkg: %s %lu %lu\n", pkgdir, s.st_uid, s.st_gid);
    159         return -1;
    160     }
    161 
    162     if (chmod(pkgdir, 0751) < 0) {
    163         ALOGE("cannot chmod dir '%s': %s\n", pkgdir, strerror(errno));
    164         unlink(pkgdir);
    165         return -errno;
    166     }
    167     if (chown(pkgdir, uid, gid) < 0) {
    168         ALOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno));
    169         unlink(pkgdir);
    170         return -errno;
    171     }
    172 
    173     return 0;
    174 }
    175 
    176 int delete_user_data(const char *pkgname, userid_t userid)
    177 {
    178     char pkgdir[PKG_PATH_MAX];
    179 
    180     if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, userid))
    181         return -1;
    182 
    183     /* delete contents, excluding "lib", but not the directory itself */
    184     return delete_dir_contents(pkgdir, 0, "lib");
    185 }
    186 
    187 int make_user_data(const char *pkgname, uid_t uid, userid_t userid)
    188 {
    189     char pkgdir[PKG_PATH_MAX];
    190     char applibdir[PKG_PATH_MAX];
    191     char libsymlink[PKG_PATH_MAX];
    192     struct stat libStat;
    193 
    194     // Create the data dir for the package
    195     if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, userid)) {
    196         return -1;
    197     }
    198     if (create_pkg_path(libsymlink, pkgname, PKG_LIB_POSTFIX, userid)) {
    199         ALOGE("cannot create package lib symlink origin path\n");
    200         return -1;
    201     }
    202     if (create_pkg_path_in_dir(applibdir, &android_app_lib_dir, pkgname, PKG_DIR_POSTFIX)) {
    203         ALOGE("cannot create package lib symlink dest path\n");
    204         return -1;
    205     }
    206 
    207     if (mkdir(pkgdir, 0751) < 0) {
    208         ALOGE("cannot create dir '%s': %s\n", pkgdir, strerror(errno));
    209         return -errno;
    210     }
    211     if (chmod(pkgdir, 0751) < 0) {
    212         ALOGE("cannot chmod dir '%s': %s\n", pkgdir, strerror(errno));
    213         unlink(pkgdir);
    214         return -errno;
    215     }
    216 
    217     if (lstat(libsymlink, &libStat) < 0) {
    218         if (errno != ENOENT) {
    219             ALOGE("couldn't stat lib dir for non-primary: %s\n", strerror(errno));
    220             unlink(pkgdir);
    221             return -1;
    222         }
    223     } else {
    224         if (S_ISDIR(libStat.st_mode)) {
    225             if (delete_dir_contents(libsymlink, 1, 0) < 0) {
    226                 ALOGE("couldn't delete lib directory during install for non-primary: %s",
    227                         libsymlink);
    228                 unlink(pkgdir);
    229                 return -1;
    230             }
    231         } else if (S_ISLNK(libStat.st_mode)) {
    232             if (unlink(libsymlink) < 0) {
    233                 ALOGE("couldn't unlink lib directory during install for non-primary: %s",
    234                         libsymlink);
    235                 unlink(pkgdir);
    236                 return -1;
    237             }
    238         }
    239     }
    240 
    241     if (symlink(applibdir, libsymlink) < 0) {
    242         ALOGE("couldn't symlink directory for non-primary '%s' -> '%s': %s\n", libsymlink,
    243                 applibdir, strerror(errno));
    244         unlink(pkgdir);
    245         return -1;
    246     }
    247 
    248     if (selinux_android_setfilecon(pkgdir, pkgname, uid) < 0) {
    249         ALOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno));
    250         unlink(libsymlink);
    251         unlink(pkgdir);
    252         return -errno;
    253     }
    254 
    255     if (chown(pkgdir, uid, uid) < 0) {
    256         ALOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno));
    257         unlink(libsymlink);
    258         unlink(pkgdir);
    259         return -errno;
    260     }
    261 
    262     return 0;
    263 }
    264 
    265 int delete_user(userid_t userid)
    266 {
    267     char data_path[PKG_PATH_MAX];
    268     if (create_user_path(data_path, userid)) {
    269         return -1;
    270     }
    271     if (delete_dir_contents(data_path, 1, NULL)) {
    272         return -1;
    273     }
    274 
    275     char media_path[PATH_MAX];
    276     if (create_user_media_path(media_path, userid) == -1) {
    277         return -1;
    278     }
    279     if (delete_dir_contents(media_path, 1, NULL) == -1) {
    280         return -1;
    281     }
    282 
    283     return 0;
    284 }
    285 
    286 int delete_cache(const char *pkgname, userid_t userid)
    287 {
    288     char cachedir[PKG_PATH_MAX];
    289 
    290     if (create_pkg_path(cachedir, pkgname, CACHE_DIR_POSTFIX, userid))
    291         return -1;
    292 
    293         /* delete contents, not the directory, no exceptions */
    294     return delete_dir_contents(cachedir, 0, 0);
    295 }
    296 
    297 /* Try to ensure free_size bytes of storage are available.
    298  * Returns 0 on success.
    299  * This is rather simple-minded because doing a full LRU would
    300  * be potentially memory-intensive, and without atime it would
    301  * also require that apps constantly modify file metadata even
    302  * when just reading from the cache, which is pretty awful.
    303  */
    304 int free_cache(int64_t free_size)
    305 {
    306     cache_t* cache;
    307     int64_t avail;
    308     DIR *d;
    309     struct dirent *de;
    310     char tmpdir[PATH_MAX];
    311     char *dirpos;
    312 
    313     avail = data_disk_free();
    314     if (avail < 0) return -1;
    315 
    316     ALOGI("free_cache(%" PRId64 ") avail %" PRId64 "\n", free_size, avail);
    317     if (avail >= free_size) return 0;
    318 
    319     cache = start_cache_collection();
    320 
    321     // Collect cache files for primary user.
    322     if (create_user_path(tmpdir, 0) == 0) {
    323         //ALOGI("adding cache files from %s\n", tmpdir);
    324         add_cache_files(cache, tmpdir, "cache");
    325     }
    326 
    327     // Search for other users and add any cache files from them.
    328     snprintf(tmpdir, sizeof(tmpdir), "%s%s", android_data_dir.path,
    329             SECONDARY_USER_PREFIX);
    330     dirpos = tmpdir + strlen(tmpdir);
    331     d = opendir(tmpdir);
    332     if (d != NULL) {
    333         while ((de = readdir(d))) {
    334             if (de->d_type == DT_DIR) {
    335                 const char *name = de->d_name;
    336                     /* always skip "." and ".." */
    337                 if (name[0] == '.') {
    338                     if (name[1] == 0) continue;
    339                     if ((name[1] == '.') && (name[2] == 0)) continue;
    340                 }
    341                 if ((strlen(name)+(dirpos-tmpdir)) < (sizeof(tmpdir)-1)) {
    342                     strcpy(dirpos, name);
    343                     //ALOGI("adding cache files from %s\n", tmpdir);
    344                     add_cache_files(cache, tmpdir, "cache");
    345                 } else {
    346                     ALOGW("Path exceeds limit: %s%s", tmpdir, name);
    347                 }
    348             }
    349         }
    350         closedir(d);
    351     }
    352 
    353     // Collect cache files on external storage for all users (if it is mounted as part
    354     // of the internal storage).
    355     strcpy(tmpdir, android_media_dir.path);
    356     dirpos = tmpdir + strlen(tmpdir);
    357     d = opendir(tmpdir);
    358     if (d != NULL) {
    359         while ((de = readdir(d))) {
    360             if (de->d_type == DT_DIR) {
    361                 const char *name = de->d_name;
    362                     /* skip any dir that doesn't start with a number, so not a user */
    363                 if (name[0] < '0' || name[0] > '9') {
    364                     continue;
    365                 }
    366                 if ((strlen(name)+(dirpos-tmpdir)) < (sizeof(tmpdir)-1)) {
    367                     strcpy(dirpos, name);
    368                     if (lookup_media_dir(tmpdir, "Android") == 0
    369                             && lookup_media_dir(tmpdir, "data") == 0) {
    370                         //ALOGI("adding cache files from %s\n", tmpdir);
    371                         add_cache_files(cache, tmpdir, "cache");
    372                     }
    373                 } else {
    374                     ALOGW("Path exceeds limit: %s%s", tmpdir, name);
    375                 }
    376             }
    377         }
    378         closedir(d);
    379     }
    380 
    381     clear_cache_files(cache, free_size);
    382     finish_cache_collection(cache);
    383 
    384     return data_disk_free() >= free_size ? 0 : -1;
    385 }
    386 
    387 int move_dex(const char *src, const char *dst)
    388 {
    389     char src_dex[PKG_PATH_MAX];
    390     char dst_dex[PKG_PATH_MAX];
    391 
    392     if (validate_apk_path(src)) return -1;
    393     if (validate_apk_path(dst)) return -1;
    394 
    395     if (create_cache_path(src_dex, src)) return -1;
    396     if (create_cache_path(dst_dex, dst)) return -1;
    397 
    398     ALOGV("move %s -> %s\n", src_dex, dst_dex);
    399     if (rename(src_dex, dst_dex) < 0) {
    400         ALOGE("Couldn't move %s: %s\n", src_dex, strerror(errno));
    401         return -1;
    402     } else {
    403         return 0;
    404     }
    405 }
    406 
    407 int rm_dex(const char *path)
    408 {
    409     char dex_path[PKG_PATH_MAX];
    410 
    411     if (validate_apk_path(path)) return -1;
    412     if (create_cache_path(dex_path, path)) return -1;
    413 
    414     ALOGV("unlink %s\n", dex_path);
    415     if (unlink(dex_path) < 0) {
    416         ALOGE("Couldn't unlink %s: %s\n", dex_path, strerror(errno));
    417         return -1;
    418     } else {
    419         return 0;
    420     }
    421 }
    422 
    423 int get_size(const char *pkgname, userid_t userid, const char *apkpath,
    424              const char *libdirpath, const char *fwdlock_apkpath, const char *asecpath,
    425              int64_t *_codesize, int64_t *_datasize, int64_t *_cachesize,
    426              int64_t* _asecsize)
    427 {
    428     DIR *d;
    429     int dfd;
    430     struct dirent *de;
    431     struct stat s;
    432     char path[PKG_PATH_MAX];
    433 
    434     int64_t codesize = 0;
    435     int64_t datasize = 0;
    436     int64_t cachesize = 0;
    437     int64_t asecsize = 0;
    438 
    439         /* count the source apk as code -- but only if it's not
    440          * on the /system partition and its not on the sdcard.
    441          */
    442     if (validate_system_app_path(apkpath) &&
    443             strncmp(apkpath, android_asec_dir.path, android_asec_dir.len) != 0) {
    444         if (stat(apkpath, &s) == 0) {
    445             codesize += stat_size(&s);
    446         }
    447     }
    448         /* count the forward locked apk as code if it is given
    449          */
    450     if (fwdlock_apkpath != NULL && fwdlock_apkpath[0] != '!') {
    451         if (stat(fwdlock_apkpath, &s) == 0) {
    452             codesize += stat_size(&s);
    453         }
    454     }
    455         /* count the cached dexfile as code */
    456     if (!create_cache_path(path, apkpath)) {
    457         if (stat(path, &s) == 0) {
    458             codesize += stat_size(&s);
    459         }
    460     }
    461 
    462         /* add in size of any libraries */
    463     if (libdirpath != NULL && libdirpath[0] != '!') {
    464         d = opendir(libdirpath);
    465         if (d != NULL) {
    466             dfd = dirfd(d);
    467             codesize += calculate_dir_size(dfd);
    468             closedir(d);
    469         }
    470     }
    471 
    472         /* compute asec size if it is given
    473          */
    474     if (asecpath != NULL && asecpath[0] != '!') {
    475         if (stat(asecpath, &s) == 0) {
    476             asecsize += stat_size(&s);
    477         }
    478     }
    479 
    480     if (create_pkg_path(path, pkgname, PKG_DIR_POSTFIX, userid)) {
    481         goto done;
    482     }
    483 
    484     d = opendir(path);
    485     if (d == NULL) {
    486         goto done;
    487     }
    488     dfd = dirfd(d);
    489 
    490     /* most stuff in the pkgdir is data, except for the "cache"
    491      * directory and below, which is cache, and the "lib" directory
    492      * and below, which is code...
    493      */
    494     while ((de = readdir(d))) {
    495         const char *name = de->d_name;
    496 
    497         if (de->d_type == DT_DIR) {
    498             int subfd;
    499             int64_t statsize = 0;
    500             int64_t dirsize = 0;
    501                 /* always skip "." and ".." */
    502             if (name[0] == '.') {
    503                 if (name[1] == 0) continue;
    504                 if ((name[1] == '.') && (name[2] == 0)) continue;
    505             }
    506             if (fstatat(dfd, name, &s, AT_SYMLINK_NOFOLLOW) == 0) {
    507                 statsize = stat_size(&s);
    508             }
    509             subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY);
    510             if (subfd >= 0) {
    511                 dirsize = calculate_dir_size(subfd);
    512             }
    513             if(!strcmp(name,"lib")) {
    514                 codesize += dirsize + statsize;
    515             } else if(!strcmp(name,"cache")) {
    516                 cachesize += dirsize + statsize;
    517             } else {
    518                 datasize += dirsize + statsize;
    519             }
    520         } else if (de->d_type == DT_LNK && !strcmp(name,"lib")) {
    521             // This is the symbolic link to the application's library
    522             // code.  We'll count this as code instead of data, since
    523             // it is not something that the app creates.
    524             if (fstatat(dfd, name, &s, AT_SYMLINK_NOFOLLOW) == 0) {
    525                 codesize += stat_size(&s);
    526             }
    527         } else {
    528             if (fstatat(dfd, name, &s, AT_SYMLINK_NOFOLLOW) == 0) {
    529                 datasize += stat_size(&s);
    530             }
    531         }
    532     }
    533     closedir(d);
    534 done:
    535     *_codesize = codesize;
    536     *_datasize = datasize;
    537     *_cachesize = cachesize;
    538     *_asecsize = asecsize;
    539     return 0;
    540 }
    541 
    542 
    543 int create_cache_path(char path[PKG_PATH_MAX], const char *src)
    544 {
    545     char *tmp;
    546     int srclen;
    547     int dstlen;
    548 
    549     srclen = strlen(src);
    550 
    551         /* demand that we are an absolute path */
    552     if ((src == 0) || (src[0] != '/') || strstr(src,"..")) {
    553         return -1;
    554     }
    555 
    556     if (srclen > PKG_PATH_MAX) {        // XXX: PKG_NAME_MAX?
    557         return -1;
    558     }
    559 
    560     dstlen = srclen + strlen(DALVIK_CACHE_PREFIX) +
    561         strlen(DALVIK_CACHE_POSTFIX) + 1;
    562 
    563     if (dstlen > PKG_PATH_MAX) {
    564         return -1;
    565     }
    566 
    567     sprintf(path,"%s%s%s",
    568             DALVIK_CACHE_PREFIX,
    569             src + 1, /* skip the leading / */
    570             DALVIK_CACHE_POSTFIX);
    571 
    572     for(tmp = path + strlen(DALVIK_CACHE_PREFIX); *tmp; tmp++) {
    573         if (*tmp == '/') {
    574             *tmp = '@';
    575         }
    576     }
    577 
    578     return 0;
    579 }
    580 
    581 static void run_dexopt(int zip_fd, int odex_fd, const char* input_file_name,
    582     const char* output_file_name, const char* dexopt_flags)
    583 {
    584     static const char* DEX_OPT_BIN = "/system/bin/dexopt";
    585     static const int MAX_INT_LEN = 12;      // '-'+10dig+'\0' -OR- 0x+8dig
    586     char zip_num[MAX_INT_LEN];
    587     char odex_num[MAX_INT_LEN];
    588 
    589     sprintf(zip_num, "%d", zip_fd);
    590     sprintf(odex_num, "%d", odex_fd);
    591 
    592     ALOGV("Running %s in=%s out=%s\n", DEX_OPT_BIN, input_file_name, output_file_name);
    593     execl(DEX_OPT_BIN, DEX_OPT_BIN, "--zip", zip_num, odex_num, input_file_name,
    594         dexopt_flags, (char*) NULL);
    595     ALOGE("execl(%s) failed: %s\n", DEX_OPT_BIN, strerror(errno));
    596 }
    597 
    598 static void run_dex2oat(int zip_fd, int oat_fd, const char* input_file_name,
    599     const char* output_file_name, const char* dexopt_flags)
    600 {
    601     static const char* DEX2OAT_BIN = "/system/bin/dex2oat";
    602     static const int MAX_INT_LEN = 12;      // '-'+10dig+'\0' -OR- 0x+8dig
    603     char zip_fd_arg[strlen("--zip-fd=") + MAX_INT_LEN];
    604     char zip_location_arg[strlen("--zip-location=") + PKG_PATH_MAX];
    605     char oat_fd_arg[strlen("--oat-fd=") + MAX_INT_LEN];
    606     char oat_location_arg[strlen("--oat-name=") + PKG_PATH_MAX];
    607 
    608     sprintf(zip_fd_arg, "--zip-fd=%d", zip_fd);
    609     sprintf(zip_location_arg, "--zip-location=%s", input_file_name);
    610     sprintf(oat_fd_arg, "--oat-fd=%d", oat_fd);
    611     sprintf(oat_location_arg, "--oat-location=%s", output_file_name);
    612 
    613     ALOGV("Running %s in=%s out=%s\n", DEX2OAT_BIN, input_file_name, output_file_name);
    614     execl(DEX2OAT_BIN, DEX2OAT_BIN,
    615           zip_fd_arg, zip_location_arg,
    616           oat_fd_arg, oat_location_arg,
    617           (char*) NULL);
    618     ALOGE("execl(%s) failed: %s\n", DEX2OAT_BIN, strerror(errno));
    619 }
    620 
    621 static int wait_dexopt(pid_t pid, const char* apk_path)
    622 {
    623     int status;
    624     pid_t got_pid;
    625 
    626     /*
    627      * Wait for the optimization process to finish.
    628      */
    629     while (1) {
    630         got_pid = waitpid(pid, &status, 0);
    631         if (got_pid == -1 && errno == EINTR) {
    632             printf("waitpid interrupted, retrying\n");
    633         } else {
    634             break;
    635         }
    636     }
    637     if (got_pid != pid) {
    638         ALOGW("waitpid failed: wanted %d, got %d: %s\n",
    639             (int) pid, (int) got_pid, strerror(errno));
    640         return 1;
    641     }
    642 
    643     if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
    644         ALOGV("DexInv: --- END '%s' (success) ---\n", apk_path);
    645         return 0;
    646     } else {
    647         ALOGW("DexInv: --- END '%s' --- status=0x%04x, process failed\n",
    648             apk_path, status);
    649         return status;      /* always nonzero */
    650     }
    651 }
    652 
    653 int dexopt(const char *apk_path, uid_t uid, int is_public)
    654 {
    655     struct utimbuf ut;
    656     struct stat apk_stat, dex_stat;
    657     char out_path[PKG_PATH_MAX];
    658     char dexopt_flags[PROPERTY_VALUE_MAX];
    659     char persist_sys_dalvik_vm_lib[PROPERTY_VALUE_MAX];
    660     char *end;
    661     int res, zip_fd=-1, out_fd=-1;
    662 
    663     if (strlen(apk_path) >= (PKG_PATH_MAX - 8)) {
    664         return -1;
    665     }
    666 
    667     /* platform-specific flags affecting optimization and verification */
    668     property_get("dalvik.vm.dexopt-flags", dexopt_flags, "");
    669     ALOGV("dalvik.vm.dexopt_flags=%s\n", dexopt_flags);
    670 
    671     /* The command to run depend ones the value of persist.sys.dalvik.vm.lib */
    672     property_get("persist.sys.dalvik.vm.lib", persist_sys_dalvik_vm_lib, "libdvm.so");
    673 
    674     /* Before anything else: is there a .odex file?  If so, we have
    675      * precompiled the apk and there is nothing to do here.
    676      */
    677     sprintf(out_path, "%s%s", apk_path, ".odex");
    678     if (stat(out_path, &dex_stat) == 0) {
    679         return 0;
    680     }
    681 
    682     if (create_cache_path(out_path, apk_path)) {
    683         return -1;
    684     }
    685 
    686     memset(&apk_stat, 0, sizeof(apk_stat));
    687     stat(apk_path, &apk_stat);
    688 
    689     zip_fd = open(apk_path, O_RDONLY, 0);
    690     if (zip_fd < 0) {
    691         ALOGE("installd cannot open '%s' for input during dexopt\n", apk_path);
    692         return -1;
    693     }
    694 
    695     unlink(out_path);
    696     out_fd = open(out_path, O_RDWR | O_CREAT | O_EXCL, 0644);
    697     if (out_fd < 0) {
    698         ALOGE("installd cannot open '%s' for output during dexopt\n", out_path);
    699         goto fail;
    700     }
    701     if (fchmod(out_fd,
    702                S_IRUSR|S_IWUSR|S_IRGRP |
    703                (is_public ? S_IROTH : 0)) < 0) {
    704         ALOGE("installd cannot chmod '%s' during dexopt\n", out_path);
    705         goto fail;
    706     }
    707     if (fchown(out_fd, AID_SYSTEM, uid) < 0) {
    708         ALOGE("installd cannot chown '%s' during dexopt\n", out_path);
    709         goto fail;
    710     }
    711 
    712     ALOGV("DexInv: --- BEGIN '%s' ---\n", apk_path);
    713 
    714     pid_t pid;
    715     pid = fork();
    716     if (pid == 0) {
    717         /* child -- drop privileges before continuing */
    718         if (setgid(uid) != 0) {
    719             ALOGE("setgid(%d) failed in installd during dexopt\n", uid);
    720             exit(64);
    721         }
    722         if (setuid(uid) != 0) {
    723             ALOGE("setuid(%d) failed in installd during dexopt\n", uid);
    724             exit(65);
    725         }
    726         // drop capabilities
    727         struct __user_cap_header_struct capheader;
    728         struct __user_cap_data_struct capdata[2];
    729         memset(&capheader, 0, sizeof(capheader));
    730         memset(&capdata, 0, sizeof(capdata));
    731         capheader.version = _LINUX_CAPABILITY_VERSION_3;
    732         if (capset(&capheader, &capdata[0]) < 0) {
    733             ALOGE("capset failed: %s\n", strerror(errno));
    734             exit(66);
    735         }
    736         if (flock(out_fd, LOCK_EX | LOCK_NB) != 0) {
    737             ALOGE("flock(%s) failed: %s\n", out_path, strerror(errno));
    738             exit(67);
    739         }
    740 
    741         if (strncmp(persist_sys_dalvik_vm_lib, "libdvm", 6) == 0) {
    742             run_dexopt(zip_fd, out_fd, apk_path, out_path, dexopt_flags);
    743         } else if (strncmp(persist_sys_dalvik_vm_lib, "libart", 6) == 0) {
    744             run_dex2oat(zip_fd, out_fd, apk_path, out_path, dexopt_flags);
    745         } else {
    746             exit(69);   /* Unexpected persist.sys.dalvik.vm.lib value */
    747         }
    748         exit(68);   /* only get here on exec failure */
    749     } else {
    750         res = wait_dexopt(pid, apk_path);
    751         if (res != 0) {
    752             ALOGE("dexopt in='%s' out='%s' res=%d\n", apk_path, out_path, res);
    753             goto fail;
    754         }
    755     }
    756 
    757     ut.actime = apk_stat.st_atime;
    758     ut.modtime = apk_stat.st_mtime;
    759     utime(out_path, &ut);
    760 
    761     close(out_fd);
    762     close(zip_fd);
    763     return 0;
    764 
    765 fail:
    766     if (out_fd >= 0) {
    767         close(out_fd);
    768         unlink(out_path);
    769     }
    770     if (zip_fd >= 0) {
    771         close(zip_fd);
    772     }
    773     return -1;
    774 }
    775 
    776 void mkinnerdirs(char* path, int basepos, mode_t mode, int uid, int gid,
    777         struct stat* statbuf)
    778 {
    779     while (path[basepos] != 0) {
    780         if (path[basepos] == '/') {
    781             path[basepos] = 0;
    782             if (lstat(path, statbuf) < 0) {
    783                 ALOGV("Making directory: %s\n", path);
    784                 if (mkdir(path, mode) == 0) {
    785                     chown(path, uid, gid);
    786                 } else {
    787                     ALOGW("Unable to make directory %s: %s\n", path, strerror(errno));
    788                 }
    789             }
    790             path[basepos] = '/';
    791             basepos++;
    792         }
    793         basepos++;
    794     }
    795 }
    796 
    797 int movefileordir(char* srcpath, char* dstpath, int dstbasepos,
    798         int dstuid, int dstgid, struct stat* statbuf)
    799 {
    800     DIR *d;
    801     struct dirent *de;
    802     int res;
    803 
    804     int srcend = strlen(srcpath);
    805     int dstend = strlen(dstpath);
    806 
    807     if (lstat(srcpath, statbuf) < 0) {
    808         ALOGW("Unable to stat %s: %s\n", srcpath, strerror(errno));
    809         return 1;
    810     }
    811 
    812     if ((statbuf->st_mode&S_IFDIR) == 0) {
    813         mkinnerdirs(dstpath, dstbasepos, S_IRWXU|S_IRWXG|S_IXOTH,
    814                 dstuid, dstgid, statbuf);
    815         ALOGV("Renaming %s to %s (uid %d)\n", srcpath, dstpath, dstuid);
    816         if (rename(srcpath, dstpath) >= 0) {
    817             if (chown(dstpath, dstuid, dstgid) < 0) {
    818                 ALOGE("cannot chown %s: %s\n", dstpath, strerror(errno));
    819                 unlink(dstpath);
    820                 return 1;
    821             }
    822         } else {
    823             ALOGW("Unable to rename %s to %s: %s\n",
    824                 srcpath, dstpath, strerror(errno));
    825             return 1;
    826         }
    827         return 0;
    828     }
    829 
    830     d = opendir(srcpath);
    831     if (d == NULL) {
    832         ALOGW("Unable to opendir %s: %s\n", srcpath, strerror(errno));
    833         return 1;
    834     }
    835 
    836     res = 0;
    837 
    838     while ((de = readdir(d))) {
    839         const char *name = de->d_name;
    840             /* always skip "." and ".." */
    841         if (name[0] == '.') {
    842             if (name[1] == 0) continue;
    843             if ((name[1] == '.') && (name[2] == 0)) continue;
    844         }
    845 
    846         if ((srcend+strlen(name)) >= (PKG_PATH_MAX-2)) {
    847             ALOGW("Source path too long; skipping: %s/%s\n", srcpath, name);
    848             continue;
    849         }
    850 
    851         if ((dstend+strlen(name)) >= (PKG_PATH_MAX-2)) {
    852             ALOGW("Destination path too long; skipping: %s/%s\n", dstpath, name);
    853             continue;
    854         }
    855 
    856         srcpath[srcend] = dstpath[dstend] = '/';
    857         strcpy(srcpath+srcend+1, name);
    858         strcpy(dstpath+dstend+1, name);
    859 
    860         if (movefileordir(srcpath, dstpath, dstbasepos, dstuid, dstgid, statbuf) != 0) {
    861             res = 1;
    862         }
    863 
    864         // Note: we will be leaving empty directories behind in srcpath,
    865         // but that is okay, the package manager will be erasing all of the
    866         // data associated with .apks that disappear.
    867 
    868         srcpath[srcend] = dstpath[dstend] = 0;
    869     }
    870 
    871     closedir(d);
    872     return res;
    873 }
    874 
    875 int movefiles()
    876 {
    877     DIR *d;
    878     int dfd, subfd;
    879     struct dirent *de;
    880     struct stat s;
    881     char buf[PKG_PATH_MAX+1];
    882     int bufp, bufe, bufi, readlen;
    883 
    884     char srcpkg[PKG_NAME_MAX];
    885     char dstpkg[PKG_NAME_MAX];
    886     char srcpath[PKG_PATH_MAX];
    887     char dstpath[PKG_PATH_MAX];
    888     int dstuid=-1, dstgid=-1;
    889     int hasspace;
    890 
    891     d = opendir(UPDATE_COMMANDS_DIR_PREFIX);
    892     if (d == NULL) {
    893         goto done;
    894     }
    895     dfd = dirfd(d);
    896 
    897         /* Iterate through all files in the directory, executing the
    898          * file movements requested there-in.
    899          */
    900     while ((de = readdir(d))) {
    901         const char *name = de->d_name;
    902 
    903         if (de->d_type == DT_DIR) {
    904             continue;
    905         } else {
    906             subfd = openat(dfd, name, O_RDONLY);
    907             if (subfd < 0) {
    908                 ALOGW("Unable to open update commands at %s%s\n",
    909                         UPDATE_COMMANDS_DIR_PREFIX, name);
    910                 continue;
    911             }
    912 
    913             bufp = 0;
    914             bufe = 0;
    915             buf[PKG_PATH_MAX] = 0;
    916             srcpkg[0] = dstpkg[0] = 0;
    917             while (1) {
    918                 bufi = bufp;
    919                 while (bufi < bufe && buf[bufi] != '\n') {
    920                     bufi++;
    921                 }
    922                 if (bufi < bufe) {
    923                     buf[bufi] = 0;
    924                     ALOGV("Processing line: %s\n", buf+bufp);
    925                     hasspace = 0;
    926                     while (bufp < bufi && isspace(buf[bufp])) {
    927                         hasspace = 1;
    928                         bufp++;
    929                     }
    930                     if (buf[bufp] == '#' || bufp == bufi) {
    931                         // skip comments and empty lines.
    932                     } else if (hasspace) {
    933                         if (dstpkg[0] == 0) {
    934                             ALOGW("Path before package line in %s%s: %s\n",
    935                                     UPDATE_COMMANDS_DIR_PREFIX, name, buf+bufp);
    936                         } else if (srcpkg[0] == 0) {
    937                             // Skip -- source package no longer exists.
    938                         } else {
    939                             ALOGV("Move file: %s (from %s to %s)\n", buf+bufp, srcpkg, dstpkg);
    940                             if (!create_move_path(srcpath, srcpkg, buf+bufp, 0) &&
    941                                     !create_move_path(dstpath, dstpkg, buf+bufp, 0)) {
    942                                 movefileordir(srcpath, dstpath,
    943                                         strlen(dstpath)-strlen(buf+bufp),
    944                                         dstuid, dstgid, &s);
    945                             }
    946                         }
    947                     } else {
    948                         char* div = strchr(buf+bufp, ':');
    949                         if (div == NULL) {
    950                             ALOGW("Bad package spec in %s%s; no ':' sep: %s\n",
    951                                     UPDATE_COMMANDS_DIR_PREFIX, name, buf+bufp);
    952                         } else {
    953                             *div = 0;
    954                             div++;
    955                             if (strlen(buf+bufp) < PKG_NAME_MAX) {
    956                                 strcpy(dstpkg, buf+bufp);
    957                             } else {
    958                                 srcpkg[0] = dstpkg[0] = 0;
    959                                 ALOGW("Package name too long in %s%s: %s\n",
    960                                         UPDATE_COMMANDS_DIR_PREFIX, name, buf+bufp);
    961                             }
    962                             if (strlen(div) < PKG_NAME_MAX) {
    963                                 strcpy(srcpkg, div);
    964                             } else {
    965                                 srcpkg[0] = dstpkg[0] = 0;
    966                                 ALOGW("Package name too long in %s%s: %s\n",
    967                                         UPDATE_COMMANDS_DIR_PREFIX, name, div);
    968                             }
    969                             if (srcpkg[0] != 0) {
    970                                 if (!create_pkg_path(srcpath, srcpkg, PKG_DIR_POSTFIX, 0)) {
    971                                     if (lstat(srcpath, &s) < 0) {
    972                                         // Package no longer exists -- skip.
    973                                         srcpkg[0] = 0;
    974                                     }
    975                                 } else {
    976                                     srcpkg[0] = 0;
    977                                     ALOGW("Can't create path %s in %s%s\n",
    978                                             div, UPDATE_COMMANDS_DIR_PREFIX, name);
    979                                 }
    980                                 if (srcpkg[0] != 0) {
    981                                     if (!create_pkg_path(dstpath, dstpkg, PKG_DIR_POSTFIX, 0)) {
    982                                         if (lstat(dstpath, &s) == 0) {
    983                                             dstuid = s.st_uid;
    984                                             dstgid = s.st_gid;
    985                                         } else {
    986                                             // Destination package doesn't
    987                                             // exist...  due to original-package,
    988                                             // this is normal, so don't be
    989                                             // noisy about it.
    990                                             srcpkg[0] = 0;
    991                                         }
    992                                     } else {
    993                                         srcpkg[0] = 0;
    994                                         ALOGW("Can't create path %s in %s%s\n",
    995                                                 div, UPDATE_COMMANDS_DIR_PREFIX, name);
    996                                     }
    997                                 }
    998                                 ALOGV("Transfering from %s to %s: uid=%d\n",
    999                                     srcpkg, dstpkg, dstuid);
   1000                             }
   1001                         }
   1002                     }
   1003                     bufp = bufi+1;
   1004                 } else {
   1005                     if (bufp == 0) {
   1006                         if (bufp < bufe) {
   1007                             ALOGW("Line too long in %s%s, skipping: %s\n",
   1008                                     UPDATE_COMMANDS_DIR_PREFIX, name, buf);
   1009                         }
   1010                     } else if (bufp < bufe) {
   1011                         memcpy(buf, buf+bufp, bufe-bufp);
   1012                         bufe -= bufp;
   1013                         bufp = 0;
   1014                     }
   1015                     readlen = read(subfd, buf+bufe, PKG_PATH_MAX-bufe);
   1016                     if (readlen < 0) {
   1017                         ALOGW("Failure reading update commands in %s%s: %s\n",
   1018                                 UPDATE_COMMANDS_DIR_PREFIX, name, strerror(errno));
   1019                         break;
   1020                     } else if (readlen == 0) {
   1021                         break;
   1022                     }
   1023                     bufe += readlen;
   1024                     buf[bufe] = 0;
   1025                     ALOGV("Read buf: %s\n", buf);
   1026                 }
   1027             }
   1028             close(subfd);
   1029         }
   1030     }
   1031     closedir(d);
   1032 done:
   1033     return 0;
   1034 }
   1035 
   1036 int linklib(const char* pkgname, const char* asecLibDir, int userId)
   1037 {
   1038     char pkgdir[PKG_PATH_MAX];
   1039     char libsymlink[PKG_PATH_MAX];
   1040     struct stat s, libStat;
   1041     int rc = 0;
   1042 
   1043     if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, userId)) {
   1044         ALOGE("cannot create package path\n");
   1045         return -1;
   1046     }
   1047     if (create_pkg_path(libsymlink, pkgname, PKG_LIB_POSTFIX, userId)) {
   1048         ALOGE("cannot create package lib symlink origin path\n");
   1049         return -1;
   1050     }
   1051 
   1052     if (stat(pkgdir, &s) < 0) return -1;
   1053 
   1054     if (chown(pkgdir, AID_INSTALL, AID_INSTALL) < 0) {
   1055         ALOGE("failed to chown '%s': %s\n", pkgdir, strerror(errno));
   1056         return -1;
   1057     }
   1058 
   1059     if (chmod(pkgdir, 0700) < 0) {
   1060         ALOGE("linklib() 1: failed to chmod '%s': %s\n", pkgdir, strerror(errno));
   1061         rc = -1;
   1062         goto out;
   1063     }
   1064 
   1065     if (lstat(libsymlink, &libStat) < 0) {
   1066         if (errno != ENOENT) {
   1067             ALOGE("couldn't stat lib dir: %s\n", strerror(errno));
   1068             rc = -1;
   1069             goto out;
   1070         }
   1071     } else {
   1072         if (S_ISDIR(libStat.st_mode)) {
   1073             if (delete_dir_contents(libsymlink, 1, 0) < 0) {
   1074                 rc = -1;
   1075                 goto out;
   1076             }
   1077         } else if (S_ISLNK(libStat.st_mode)) {
   1078             if (unlink(libsymlink) < 0) {
   1079                 ALOGE("couldn't unlink lib dir: %s\n", strerror(errno));
   1080                 rc = -1;
   1081                 goto out;
   1082             }
   1083         }
   1084     }
   1085 
   1086     if (symlink(asecLibDir, libsymlink) < 0) {
   1087         ALOGE("couldn't symlink directory '%s' -> '%s': %s\n", libsymlink, asecLibDir,
   1088                 strerror(errno));
   1089         rc = -errno;
   1090         goto out;
   1091     }
   1092 
   1093 out:
   1094     if (chmod(pkgdir, s.st_mode) < 0) {
   1095         ALOGE("linklib() 2: failed to chmod '%s': %s\n", pkgdir, strerror(errno));
   1096         rc = -errno;
   1097     }
   1098 
   1099     if (chown(pkgdir, s.st_uid, s.st_gid) < 0) {
   1100         ALOGE("failed to chown '%s' : %s\n", pkgdir, strerror(errno));
   1101         return -errno;
   1102     }
   1103 
   1104     return rc;
   1105 }
   1106