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