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, uid_t persona)
    112 {
    113     char pkgdir[PKG_PATH_MAX];
    114 
    115     if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, persona))
    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, uid_t persona)
    177 {
    178     char pkgdir[PKG_PATH_MAX];
    179 
    180     if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, persona))
    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, uid_t persona)
    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, persona)) {
    196         return -1;
    197     }
    198     if (create_pkg_path(libsymlink, pkgname, PKG_LIB_POSTFIX, persona)) {
    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_persona(uid_t persona)
    266 {
    267     char data_path[PKG_PATH_MAX];
    268     if (create_persona_path(data_path, persona)) {
    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_persona_media_path(media_path, (userid_t) persona) == -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, uid_t persona)
    287 {
    288     char cachedir[PKG_PATH_MAX];
    289 
    290     if (create_pkg_path(cachedir, pkgname, CACHE_DIR_POSTFIX, persona))
    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_persona_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, int persona, 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, persona)) {
    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 /* a simpler version of dexOptGenerateCacheFileName() */
    544 int create_cache_path(char path[PKG_PATH_MAX], const char *src)
    545 {
    546     char *tmp;
    547     int srclen;
    548     int dstlen;
    549 
    550     srclen = strlen(src);
    551 
    552         /* demand that we are an absolute path */
    553     if ((src == 0) || (src[0] != '/') || strstr(src,"..")) {
    554         return -1;
    555     }
    556 
    557     if (srclen > PKG_PATH_MAX) {        // XXX: PKG_NAME_MAX?
    558         return -1;
    559     }
    560 
    561     dstlen = srclen + strlen(DALVIK_CACHE_PREFIX) +
    562         strlen(DALVIK_CACHE_POSTFIX) + 1;
    563 
    564     if (dstlen > PKG_PATH_MAX) {
    565         return -1;
    566     }
    567 
    568     sprintf(path,"%s%s%s",
    569             DALVIK_CACHE_PREFIX,
    570             src + 1, /* skip the leading / */
    571             DALVIK_CACHE_POSTFIX);
    572 
    573     for(tmp = path + strlen(DALVIK_CACHE_PREFIX); *tmp; tmp++) {
    574         if (*tmp == '/') {
    575             *tmp = '@';
    576         }
    577     }
    578 
    579     return 0;
    580 }
    581 
    582 static void run_dexopt(int zip_fd, int odex_fd, const char* input_file_name,
    583     const char* dexopt_flags)
    584 {
    585     static const char* DEX_OPT_BIN = "/system/bin/dexopt";
    586     static const int MAX_INT_LEN = 12;      // '-'+10dig+'\0' -OR- 0x+8dig
    587     char zip_num[MAX_INT_LEN];
    588     char odex_num[MAX_INT_LEN];
    589 
    590     sprintf(zip_num, "%d", zip_fd);
    591     sprintf(odex_num, "%d", odex_fd);
    592 
    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 int wait_dexopt(pid_t pid, const char* apk_path)
    599 {
    600     int status;
    601     pid_t got_pid;
    602 
    603     /*
    604      * Wait for the optimization process to finish.
    605      */
    606     while (1) {
    607         got_pid = waitpid(pid, &status, 0);
    608         if (got_pid == -1 && errno == EINTR) {
    609             printf("waitpid interrupted, retrying\n");
    610         } else {
    611             break;
    612         }
    613     }
    614     if (got_pid != pid) {
    615         ALOGW("waitpid failed: wanted %d, got %d: %s\n",
    616             (int) pid, (int) got_pid, strerror(errno));
    617         return 1;
    618     }
    619 
    620     if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
    621         ALOGV("DexInv: --- END '%s' (success) ---\n", apk_path);
    622         return 0;
    623     } else {
    624         ALOGW("DexInv: --- END '%s' --- status=0x%04x, process failed\n",
    625             apk_path, status);
    626         return status;      /* always nonzero */
    627     }
    628 }
    629 
    630 int dexopt(const char *apk_path, uid_t uid, int is_public)
    631 {
    632     struct utimbuf ut;
    633     struct stat apk_stat, dex_stat;
    634     char dex_path[PKG_PATH_MAX];
    635     char dexopt_flags[PROPERTY_VALUE_MAX];
    636     char *end;
    637     int res, zip_fd=-1, odex_fd=-1;
    638 
    639         /* Before anything else: is there a .odex file?  If so, we have
    640          * pre-optimized the apk and there is nothing to do here.
    641          */
    642     if (strlen(apk_path) >= (PKG_PATH_MAX - 8)) {
    643         return -1;
    644     }
    645 
    646     /* platform-specific flags affecting optimization and verification */
    647     property_get("dalvik.vm.dexopt-flags", dexopt_flags, "");
    648 
    649     strcpy(dex_path, apk_path);
    650     end = strrchr(dex_path, '.');
    651     if (end != NULL) {
    652         strcpy(end, ".odex");
    653         if (stat(dex_path, &dex_stat) == 0) {
    654             return 0;
    655         }
    656     }
    657 
    658     if (create_cache_path(dex_path, apk_path)) {
    659         return -1;
    660     }
    661 
    662     memset(&apk_stat, 0, sizeof(apk_stat));
    663     stat(apk_path, &apk_stat);
    664 
    665     zip_fd = open(apk_path, O_RDONLY, 0);
    666     if (zip_fd < 0) {
    667         ALOGE("dexopt cannot open '%s' for input\n", apk_path);
    668         return -1;
    669     }
    670 
    671     unlink(dex_path);
    672     odex_fd = open(dex_path, O_RDWR | O_CREAT | O_EXCL, 0644);
    673     if (odex_fd < 0) {
    674         ALOGE("dexopt cannot open '%s' for output\n", dex_path);
    675         goto fail;
    676     }
    677     if (fchmod(odex_fd,
    678                S_IRUSR|S_IWUSR|S_IRGRP |
    679                (is_public ? S_IROTH : 0)) < 0) {
    680         ALOGE("dexopt cannot chmod '%s'\n", dex_path);
    681         goto fail;
    682     }
    683     if (fchown(odex_fd, AID_SYSTEM, uid) < 0) {
    684         ALOGE("dexopt cannot chown '%s'\n", dex_path);
    685         goto fail;
    686     }
    687 
    688     ALOGV("DexInv: --- BEGIN '%s' ---\n", apk_path);
    689 
    690     pid_t pid;
    691     pid = fork();
    692     if (pid == 0) {
    693         /* child -- drop privileges before continuing */
    694         if (setgid(uid) != 0) {
    695             ALOGE("setgid(%d) failed during dexopt\n", uid);
    696             exit(64);
    697         }
    698         if (setuid(uid) != 0) {
    699             ALOGE("setuid(%d) during dexopt\n", uid);
    700             exit(65);
    701         }
    702         // drop capabilities
    703         struct __user_cap_header_struct capheader;
    704         struct __user_cap_data_struct capdata[2];
    705         memset(&capheader, 0, sizeof(capheader));
    706         memset(&capdata, 0, sizeof(capdata));
    707         capheader.version = _LINUX_CAPABILITY_VERSION_3;
    708         if (capset(&capheader, &capdata[0]) < 0) {
    709             ALOGE("capset failed: %s\n", strerror(errno));
    710             exit(66);
    711         }
    712         if (flock(odex_fd, LOCK_EX | LOCK_NB) != 0) {
    713             ALOGE("flock(%s) failed: %s\n", dex_path, strerror(errno));
    714             exit(67);
    715         }
    716 
    717         run_dexopt(zip_fd, odex_fd, apk_path, dexopt_flags);
    718         exit(68);   /* only get here on exec failure */
    719     } else {
    720         res = wait_dexopt(pid, apk_path);
    721         if (res != 0) {
    722             ALOGE("dexopt failed on '%s' res = %d\n", dex_path, res);
    723             goto fail;
    724         }
    725     }
    726 
    727     ut.actime = apk_stat.st_atime;
    728     ut.modtime = apk_stat.st_mtime;
    729     utime(dex_path, &ut);
    730 
    731     close(odex_fd);
    732     close(zip_fd);
    733     return 0;
    734 
    735 fail:
    736     if (odex_fd >= 0) {
    737         close(odex_fd);
    738         unlink(dex_path);
    739     }
    740     if (zip_fd >= 0) {
    741         close(zip_fd);
    742     }
    743     return -1;
    744 }
    745 
    746 void mkinnerdirs(char* path, int basepos, mode_t mode, int uid, int gid,
    747         struct stat* statbuf)
    748 {
    749     while (path[basepos] != 0) {
    750         if (path[basepos] == '/') {
    751             path[basepos] = 0;
    752             if (lstat(path, statbuf) < 0) {
    753                 ALOGV("Making directory: %s\n", path);
    754                 if (mkdir(path, mode) == 0) {
    755                     chown(path, uid, gid);
    756                 } else {
    757                     ALOGW("Unable to make directory %s: %s\n", path, strerror(errno));
    758                 }
    759             }
    760             path[basepos] = '/';
    761             basepos++;
    762         }
    763         basepos++;
    764     }
    765 }
    766 
    767 int movefileordir(char* srcpath, char* dstpath, int dstbasepos,
    768         int dstuid, int dstgid, struct stat* statbuf)
    769 {
    770     DIR *d;
    771     struct dirent *de;
    772     int res;
    773 
    774     int srcend = strlen(srcpath);
    775     int dstend = strlen(dstpath);
    776 
    777     if (lstat(srcpath, statbuf) < 0) {
    778         ALOGW("Unable to stat %s: %s\n", srcpath, strerror(errno));
    779         return 1;
    780     }
    781 
    782     if ((statbuf->st_mode&S_IFDIR) == 0) {
    783         mkinnerdirs(dstpath, dstbasepos, S_IRWXU|S_IRWXG|S_IXOTH,
    784                 dstuid, dstgid, statbuf);
    785         ALOGV("Renaming %s to %s (uid %d)\n", srcpath, dstpath, dstuid);
    786         if (rename(srcpath, dstpath) >= 0) {
    787             if (chown(dstpath, dstuid, dstgid) < 0) {
    788                 ALOGE("cannot chown %s: %s\n", dstpath, strerror(errno));
    789                 unlink(dstpath);
    790                 return 1;
    791             }
    792         } else {
    793             ALOGW("Unable to rename %s to %s: %s\n",
    794                 srcpath, dstpath, strerror(errno));
    795             return 1;
    796         }
    797         return 0;
    798     }
    799 
    800     d = opendir(srcpath);
    801     if (d == NULL) {
    802         ALOGW("Unable to opendir %s: %s\n", srcpath, strerror(errno));
    803         return 1;
    804     }
    805 
    806     res = 0;
    807 
    808     while ((de = readdir(d))) {
    809         const char *name = de->d_name;
    810             /* always skip "." and ".." */
    811         if (name[0] == '.') {
    812             if (name[1] == 0) continue;
    813             if ((name[1] == '.') && (name[2] == 0)) continue;
    814         }
    815 
    816         if ((srcend+strlen(name)) >= (PKG_PATH_MAX-2)) {
    817             ALOGW("Source path too long; skipping: %s/%s\n", srcpath, name);
    818             continue;
    819         }
    820 
    821         if ((dstend+strlen(name)) >= (PKG_PATH_MAX-2)) {
    822             ALOGW("Destination path too long; skipping: %s/%s\n", dstpath, name);
    823             continue;
    824         }
    825 
    826         srcpath[srcend] = dstpath[dstend] = '/';
    827         strcpy(srcpath+srcend+1, name);
    828         strcpy(dstpath+dstend+1, name);
    829 
    830         if (movefileordir(srcpath, dstpath, dstbasepos, dstuid, dstgid, statbuf) != 0) {
    831             res = 1;
    832         }
    833 
    834         // Note: we will be leaving empty directories behind in srcpath,
    835         // but that is okay, the package manager will be erasing all of the
    836         // data associated with .apks that disappear.
    837 
    838         srcpath[srcend] = dstpath[dstend] = 0;
    839     }
    840 
    841     closedir(d);
    842     return res;
    843 }
    844 
    845 int movefiles()
    846 {
    847     DIR *d;
    848     int dfd, subfd;
    849     struct dirent *de;
    850     struct stat s;
    851     char buf[PKG_PATH_MAX+1];
    852     int bufp, bufe, bufi, readlen;
    853 
    854     char srcpkg[PKG_NAME_MAX];
    855     char dstpkg[PKG_NAME_MAX];
    856     char srcpath[PKG_PATH_MAX];
    857     char dstpath[PKG_PATH_MAX];
    858     int dstuid=-1, dstgid=-1;
    859     int hasspace;
    860 
    861     d = opendir(UPDATE_COMMANDS_DIR_PREFIX);
    862     if (d == NULL) {
    863         goto done;
    864     }
    865     dfd = dirfd(d);
    866 
    867         /* Iterate through all files in the directory, executing the
    868          * file movements requested there-in.
    869          */
    870     while ((de = readdir(d))) {
    871         const char *name = de->d_name;
    872 
    873         if (de->d_type == DT_DIR) {
    874             continue;
    875         } else {
    876             subfd = openat(dfd, name, O_RDONLY);
    877             if (subfd < 0) {
    878                 ALOGW("Unable to open update commands at %s%s\n",
    879                         UPDATE_COMMANDS_DIR_PREFIX, name);
    880                 continue;
    881             }
    882 
    883             bufp = 0;
    884             bufe = 0;
    885             buf[PKG_PATH_MAX] = 0;
    886             srcpkg[0] = dstpkg[0] = 0;
    887             while (1) {
    888                 bufi = bufp;
    889                 while (bufi < bufe && buf[bufi] != '\n') {
    890                     bufi++;
    891                 }
    892                 if (bufi < bufe) {
    893                     buf[bufi] = 0;
    894                     ALOGV("Processing line: %s\n", buf+bufp);
    895                     hasspace = 0;
    896                     while (bufp < bufi && isspace(buf[bufp])) {
    897                         hasspace = 1;
    898                         bufp++;
    899                     }
    900                     if (buf[bufp] == '#' || bufp == bufi) {
    901                         // skip comments and empty lines.
    902                     } else if (hasspace) {
    903                         if (dstpkg[0] == 0) {
    904                             ALOGW("Path before package line in %s%s: %s\n",
    905                                     UPDATE_COMMANDS_DIR_PREFIX, name, buf+bufp);
    906                         } else if (srcpkg[0] == 0) {
    907                             // Skip -- source package no longer exists.
    908                         } else {
    909                             ALOGV("Move file: %s (from %s to %s)\n", buf+bufp, srcpkg, dstpkg);
    910                             if (!create_move_path(srcpath, srcpkg, buf+bufp, 0) &&
    911                                     !create_move_path(dstpath, dstpkg, buf+bufp, 0)) {
    912                                 movefileordir(srcpath, dstpath,
    913                                         strlen(dstpath)-strlen(buf+bufp),
    914                                         dstuid, dstgid, &s);
    915                             }
    916                         }
    917                     } else {
    918                         char* div = strchr(buf+bufp, ':');
    919                         if (div == NULL) {
    920                             ALOGW("Bad package spec in %s%s; no ':' sep: %s\n",
    921                                     UPDATE_COMMANDS_DIR_PREFIX, name, buf+bufp);
    922                         } else {
    923                             *div = 0;
    924                             div++;
    925                             if (strlen(buf+bufp) < PKG_NAME_MAX) {
    926                                 strcpy(dstpkg, buf+bufp);
    927                             } else {
    928                                 srcpkg[0] = dstpkg[0] = 0;
    929                                 ALOGW("Package name too long in %s%s: %s\n",
    930                                         UPDATE_COMMANDS_DIR_PREFIX, name, buf+bufp);
    931                             }
    932                             if (strlen(div) < PKG_NAME_MAX) {
    933                                 strcpy(srcpkg, div);
    934                             } else {
    935                                 srcpkg[0] = dstpkg[0] = 0;
    936                                 ALOGW("Package name too long in %s%s: %s\n",
    937                                         UPDATE_COMMANDS_DIR_PREFIX, name, div);
    938                             }
    939                             if (srcpkg[0] != 0) {
    940                                 if (!create_pkg_path(srcpath, srcpkg, PKG_DIR_POSTFIX, 0)) {
    941                                     if (lstat(srcpath, &s) < 0) {
    942                                         // Package no longer exists -- skip.
    943                                         srcpkg[0] = 0;
    944                                     }
    945                                 } else {
    946                                     srcpkg[0] = 0;
    947                                     ALOGW("Can't create path %s in %s%s\n",
    948                                             div, UPDATE_COMMANDS_DIR_PREFIX, name);
    949                                 }
    950                                 if (srcpkg[0] != 0) {
    951                                     if (!create_pkg_path(dstpath, dstpkg, PKG_DIR_POSTFIX, 0)) {
    952                                         if (lstat(dstpath, &s) == 0) {
    953                                             dstuid = s.st_uid;
    954                                             dstgid = s.st_gid;
    955                                         } else {
    956                                             // Destination package doesn't
    957                                             // exist...  due to original-package,
    958                                             // this is normal, so don't be
    959                                             // noisy about it.
    960                                             srcpkg[0] = 0;
    961                                         }
    962                                     } else {
    963                                         srcpkg[0] = 0;
    964                                         ALOGW("Can't create path %s in %s%s\n",
    965                                                 div, UPDATE_COMMANDS_DIR_PREFIX, name);
    966                                     }
    967                                 }
    968                                 ALOGV("Transfering from %s to %s: uid=%d\n",
    969                                     srcpkg, dstpkg, dstuid);
    970                             }
    971                         }
    972                     }
    973                     bufp = bufi+1;
    974                 } else {
    975                     if (bufp == 0) {
    976                         if (bufp < bufe) {
    977                             ALOGW("Line too long in %s%s, skipping: %s\n",
    978                                     UPDATE_COMMANDS_DIR_PREFIX, name, buf);
    979                         }
    980                     } else if (bufp < bufe) {
    981                         memcpy(buf, buf+bufp, bufe-bufp);
    982                         bufe -= bufp;
    983                         bufp = 0;
    984                     }
    985                     readlen = read(subfd, buf+bufe, PKG_PATH_MAX-bufe);
    986                     if (readlen < 0) {
    987                         ALOGW("Failure reading update commands in %s%s: %s\n",
    988                                 UPDATE_COMMANDS_DIR_PREFIX, name, strerror(errno));
    989                         break;
    990                     } else if (readlen == 0) {
    991                         break;
    992                     }
    993                     bufe += readlen;
    994                     buf[bufe] = 0;
    995                     ALOGV("Read buf: %s\n", buf);
    996                 }
    997             }
    998             close(subfd);
    999         }
   1000     }
   1001     closedir(d);
   1002 done:
   1003     return 0;
   1004 }
   1005 
   1006 int linklib(const char* pkgname, const char* asecLibDir, int userId)
   1007 {
   1008     char pkgdir[PKG_PATH_MAX];
   1009     char libsymlink[PKG_PATH_MAX];
   1010     struct stat s, libStat;
   1011     int rc = 0;
   1012 
   1013     if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, userId)) {
   1014         ALOGE("cannot create package path\n");
   1015         return -1;
   1016     }
   1017     if (create_pkg_path(libsymlink, pkgname, PKG_LIB_POSTFIX, userId)) {
   1018         ALOGE("cannot create package lib symlink origin path\n");
   1019         return -1;
   1020     }
   1021 
   1022     if (stat(pkgdir, &s) < 0) return -1;
   1023 
   1024     if (chown(pkgdir, AID_INSTALL, AID_INSTALL) < 0) {
   1025         ALOGE("failed to chown '%s': %s\n", pkgdir, strerror(errno));
   1026         return -1;
   1027     }
   1028 
   1029     if (chmod(pkgdir, 0700) < 0) {
   1030         ALOGE("linklib() 1: failed to chmod '%s': %s\n", pkgdir, strerror(errno));
   1031         rc = -1;
   1032         goto out;
   1033     }
   1034 
   1035     if (lstat(libsymlink, &libStat) < 0) {
   1036         if (errno != ENOENT) {
   1037             ALOGE("couldn't stat lib dir: %s\n", strerror(errno));
   1038             rc = -1;
   1039             goto out;
   1040         }
   1041     } else {
   1042         if (S_ISDIR(libStat.st_mode)) {
   1043             if (delete_dir_contents(libsymlink, 1, 0) < 0) {
   1044                 rc = -1;
   1045                 goto out;
   1046             }
   1047         } else if (S_ISLNK(libStat.st_mode)) {
   1048             if (unlink(libsymlink) < 0) {
   1049                 ALOGE("couldn't unlink lib dir: %s\n", strerror(errno));
   1050                 rc = -1;
   1051                 goto out;
   1052             }
   1053         }
   1054     }
   1055 
   1056     if (symlink(asecLibDir, libsymlink) < 0) {
   1057         ALOGE("couldn't symlink directory '%s' -> '%s': %s\n", libsymlink, asecLibDir,
   1058                 strerror(errno));
   1059         rc = -errno;
   1060         goto out;
   1061     }
   1062 
   1063 out:
   1064     if (chmod(pkgdir, s.st_mode) < 0) {
   1065         ALOGE("linklib() 2: failed to chmod '%s': %s\n", pkgdir, strerror(errno));
   1066         rc = -errno;
   1067     }
   1068 
   1069     if (chown(pkgdir, s.st_uid, s.st_gid) < 0) {
   1070         ALOGE("failed to chown '%s' : %s\n", pkgdir, strerror(errno));
   1071         return -errno;
   1072     }
   1073 
   1074     return rc;
   1075 }
   1076