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