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