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