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