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