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