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