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