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 <inttypes.h> 18 #include <sys/capability.h> 19 #include "installd.h" 20 #include <cutils/sched_policy.h> 21 #include <diskusage/dirsize.h> 22 #include <selinux/android.h> 23 24 /* Directory records that are used in execution of commands. */ 25 dir_rec_t android_data_dir; 26 dir_rec_t android_asec_dir; 27 dir_rec_t android_app_dir; 28 dir_rec_t android_app_private_dir; 29 dir_rec_t android_app_lib_dir; 30 dir_rec_t android_media_dir; 31 dir_rec_array_t android_system_dirs; 32 33 int install(const char *pkgname, uid_t uid, gid_t gid, const char *seinfo) 34 { 35 char pkgdir[PKG_PATH_MAX]; 36 char libsymlink[PKG_PATH_MAX]; 37 char applibdir[PKG_PATH_MAX]; 38 struct stat libStat; 39 40 if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) { 41 ALOGE("invalid uid/gid: %d %d\n", uid, gid); 42 return -1; 43 } 44 45 if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, 0)) { 46 ALOGE("cannot create package path\n"); 47 return -1; 48 } 49 50 if (create_pkg_path(libsymlink, pkgname, PKG_LIB_POSTFIX, 0)) { 51 ALOGE("cannot create package lib symlink origin path\n"); 52 return -1; 53 } 54 55 if (create_pkg_path_in_dir(applibdir, &android_app_lib_dir, pkgname, PKG_DIR_POSTFIX)) { 56 ALOGE("cannot create package lib symlink dest path\n"); 57 return -1; 58 } 59 60 if (mkdir(pkgdir, 0751) < 0) { 61 ALOGE("cannot create dir '%s': %s\n", pkgdir, strerror(errno)); 62 return -1; 63 } 64 if (chmod(pkgdir, 0751) < 0) { 65 ALOGE("cannot chmod dir '%s': %s\n", pkgdir, strerror(errno)); 66 unlink(pkgdir); 67 return -1; 68 } 69 70 if (lstat(libsymlink, &libStat) < 0) { 71 if (errno != ENOENT) { 72 ALOGE("couldn't stat lib dir: %s\n", strerror(errno)); 73 return -1; 74 } 75 } else { 76 if (S_ISDIR(libStat.st_mode)) { 77 if (delete_dir_contents(libsymlink, 1, NULL) < 0) { 78 ALOGE("couldn't delete lib directory during install for: %s", libsymlink); 79 return -1; 80 } 81 } else if (S_ISLNK(libStat.st_mode)) { 82 if (unlink(libsymlink) < 0) { 83 ALOGE("couldn't unlink lib directory during install for: %s", libsymlink); 84 return -1; 85 } 86 } 87 } 88 89 if (selinux_android_setfilecon(pkgdir, pkgname, seinfo, uid) < 0) { 90 ALOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno)); 91 unlink(libsymlink); 92 unlink(pkgdir); 93 return -errno; 94 } 95 96 if (symlink(applibdir, libsymlink) < 0) { 97 ALOGE("couldn't symlink directory '%s' -> '%s': %s\n", libsymlink, applibdir, 98 strerror(errno)); 99 unlink(pkgdir); 100 return -1; 101 } 102 103 if (chown(pkgdir, uid, gid) < 0) { 104 ALOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno)); 105 unlink(libsymlink); 106 unlink(pkgdir); 107 return -1; 108 } 109 110 return 0; 111 } 112 113 int uninstall(const char *pkgname, userid_t userid) 114 { 115 char pkgdir[PKG_PATH_MAX]; 116 117 if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, userid)) 118 return -1; 119 120 remove_profile_file(pkgname); 121 122 /* delete contents AND directory, no exceptions */ 123 return delete_dir_contents(pkgdir, 1, NULL); 124 } 125 126 int renamepkg(const char *oldpkgname, const char *newpkgname) 127 { 128 char oldpkgdir[PKG_PATH_MAX]; 129 char newpkgdir[PKG_PATH_MAX]; 130 131 if (create_pkg_path(oldpkgdir, oldpkgname, PKG_DIR_POSTFIX, 0)) 132 return -1; 133 if (create_pkg_path(newpkgdir, newpkgname, PKG_DIR_POSTFIX, 0)) 134 return -1; 135 136 if (rename(oldpkgdir, newpkgdir) < 0) { 137 ALOGE("cannot rename dir '%s' to '%s': %s\n", oldpkgdir, newpkgdir, strerror(errno)); 138 return -errno; 139 } 140 return 0; 141 } 142 143 int fix_uid(const char *pkgname, uid_t uid, gid_t gid) 144 { 145 char pkgdir[PKG_PATH_MAX]; 146 struct stat s; 147 int rc = 0; 148 149 if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) { 150 ALOGE("invalid uid/gid: %d %d\n", uid, gid); 151 return -1; 152 } 153 154 if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, 0)) { 155 ALOGE("cannot create package path\n"); 156 return -1; 157 } 158 159 if (stat(pkgdir, &s) < 0) return -1; 160 161 if (s.st_uid != 0 || s.st_gid != 0) { 162 ALOGE("fixing uid of non-root pkg: %s %" PRIu32 " %" PRIu32 "\n", pkgdir, s.st_uid, s.st_gid); 163 return -1; 164 } 165 166 if (chmod(pkgdir, 0751) < 0) { 167 ALOGE("cannot chmod dir '%s': %s\n", pkgdir, strerror(errno)); 168 unlink(pkgdir); 169 return -errno; 170 } 171 if (chown(pkgdir, uid, gid) < 0) { 172 ALOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno)); 173 unlink(pkgdir); 174 return -errno; 175 } 176 177 return 0; 178 } 179 180 int delete_user_data(const char *pkgname, userid_t userid) 181 { 182 char pkgdir[PKG_PATH_MAX]; 183 184 if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, userid)) 185 return -1; 186 187 return delete_dir_contents(pkgdir, 0, NULL); 188 } 189 190 int make_user_data(const char *pkgname, uid_t uid, userid_t userid, const char* seinfo) 191 { 192 char pkgdir[PKG_PATH_MAX]; 193 char applibdir[PKG_PATH_MAX]; 194 char libsymlink[PKG_PATH_MAX]; 195 struct stat libStat; 196 197 // Create the data dir for the package 198 if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, userid)) { 199 return -1; 200 } 201 if (create_pkg_path(libsymlink, pkgname, PKG_LIB_POSTFIX, userid)) { 202 ALOGE("cannot create package lib symlink origin path\n"); 203 return -1; 204 } 205 if (create_pkg_path_in_dir(applibdir, &android_app_lib_dir, pkgname, PKG_DIR_POSTFIX)) { 206 ALOGE("cannot create package lib symlink dest path\n"); 207 return -1; 208 } 209 210 if (mkdir(pkgdir, 0751) < 0) { 211 ALOGE("cannot create dir '%s': %s\n", pkgdir, strerror(errno)); 212 return -errno; 213 } 214 if (chmod(pkgdir, 0751) < 0) { 215 ALOGE("cannot chmod dir '%s': %s\n", pkgdir, strerror(errno)); 216 unlink(pkgdir); 217 return -errno; 218 } 219 220 if (lstat(libsymlink, &libStat) < 0) { 221 if (errno != ENOENT) { 222 ALOGE("couldn't stat lib dir for non-primary: %s\n", strerror(errno)); 223 unlink(pkgdir); 224 return -1; 225 } 226 } else { 227 if (S_ISDIR(libStat.st_mode)) { 228 if (delete_dir_contents(libsymlink, 1, NULL) < 0) { 229 ALOGE("couldn't delete lib directory during install for non-primary: %s", 230 libsymlink); 231 unlink(pkgdir); 232 return -1; 233 } 234 } else if (S_ISLNK(libStat.st_mode)) { 235 if (unlink(libsymlink) < 0) { 236 ALOGE("couldn't unlink lib directory during install for non-primary: %s", 237 libsymlink); 238 unlink(pkgdir); 239 return -1; 240 } 241 } 242 } 243 244 if (selinux_android_setfilecon(pkgdir, pkgname, seinfo, uid) < 0) { 245 ALOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno)); 246 unlink(libsymlink); 247 unlink(pkgdir); 248 return -errno; 249 } 250 251 if (symlink(applibdir, libsymlink) < 0) { 252 ALOGE("couldn't symlink directory for non-primary '%s' -> '%s': %s\n", libsymlink, 253 applibdir, strerror(errno)); 254 unlink(pkgdir); 255 return -1; 256 } 257 258 if (chown(pkgdir, uid, uid) < 0) { 259 ALOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno)); 260 unlink(libsymlink); 261 unlink(pkgdir); 262 return -errno; 263 } 264 265 return 0; 266 } 267 268 int make_user_config(userid_t userid) 269 { 270 if (ensure_config_user_dirs(userid) == -1) { 271 return -1; 272 } 273 274 return 0; 275 } 276 277 int delete_user(userid_t userid) 278 { 279 int status = 0; 280 281 char data_path[PKG_PATH_MAX]; 282 if ((create_user_path(data_path, userid) != 0) 283 || (delete_dir_contents(data_path, 1, NULL) != 0)) { 284 status = -1; 285 } 286 287 char media_path[PATH_MAX]; 288 if ((create_user_media_path(media_path, userid) != 0) 289 || (delete_dir_contents(media_path, 1, NULL) != 0)) { 290 status = -1; 291 } 292 293 char config_path[PATH_MAX]; 294 if ((create_user_config_path(config_path, userid) != 0) 295 || (delete_dir_contents(config_path, 1, NULL) != 0)) { 296 status = -1; 297 } 298 299 return status; 300 } 301 302 int delete_cache(const char *pkgname, userid_t userid) 303 { 304 char cachedir[PKG_PATH_MAX]; 305 306 if (create_pkg_path(cachedir, pkgname, CACHE_DIR_POSTFIX, userid)) 307 return -1; 308 309 /* delete contents, not the directory, no exceptions */ 310 return delete_dir_contents(cachedir, 0, NULL); 311 } 312 313 int delete_code_cache(const char *pkgname, userid_t userid) 314 { 315 char codecachedir[PKG_PATH_MAX]; 316 struct stat s; 317 318 if (create_pkg_path(codecachedir, pkgname, CODE_CACHE_DIR_POSTFIX, userid)) 319 return -1; 320 321 /* it's okay if code cache is missing */ 322 if (lstat(codecachedir, &s) == -1 && errno == ENOENT) { 323 return 0; 324 } 325 326 /* delete contents, not the directory, no exceptions */ 327 return delete_dir_contents(codecachedir, 0, NULL); 328 } 329 330 /* Try to ensure free_size bytes of storage are available. 331 * Returns 0 on success. 332 * This is rather simple-minded because doing a full LRU would 333 * be potentially memory-intensive, and without atime it would 334 * also require that apps constantly modify file metadata even 335 * when just reading from the cache, which is pretty awful. 336 */ 337 int free_cache(int64_t free_size) 338 { 339 cache_t* cache; 340 int64_t avail; 341 DIR *d; 342 struct dirent *de; 343 char tmpdir[PATH_MAX]; 344 char *dirpos; 345 346 avail = data_disk_free(); 347 if (avail < 0) return -1; 348 349 ALOGI("free_cache(%" PRId64 ") avail %" PRId64 "\n", free_size, avail); 350 if (avail >= free_size) return 0; 351 352 cache = start_cache_collection(); 353 354 // Collect cache files for primary user. 355 if (create_user_path(tmpdir, 0) == 0) { 356 //ALOGI("adding cache files from %s\n", tmpdir); 357 add_cache_files(cache, tmpdir, "cache"); 358 } 359 360 // Search for other users and add any cache files from them. 361 snprintf(tmpdir, sizeof(tmpdir), "%s%s", android_data_dir.path, 362 SECONDARY_USER_PREFIX); 363 dirpos = tmpdir + strlen(tmpdir); 364 d = opendir(tmpdir); 365 if (d != NULL) { 366 while ((de = readdir(d))) { 367 if (de->d_type == DT_DIR) { 368 const char *name = de->d_name; 369 /* always skip "." and ".." */ 370 if (name[0] == '.') { 371 if (name[1] == 0) continue; 372 if ((name[1] == '.') && (name[2] == 0)) continue; 373 } 374 if ((strlen(name)+(dirpos-tmpdir)) < (sizeof(tmpdir)-1)) { 375 strcpy(dirpos, name); 376 //ALOGI("adding cache files from %s\n", tmpdir); 377 add_cache_files(cache, tmpdir, "cache"); 378 } else { 379 ALOGW("Path exceeds limit: %s%s", tmpdir, name); 380 } 381 } 382 } 383 closedir(d); 384 } 385 386 // Collect cache files on external storage for all users (if it is mounted as part 387 // of the internal storage). 388 strcpy(tmpdir, android_media_dir.path); 389 dirpos = tmpdir + strlen(tmpdir); 390 d = opendir(tmpdir); 391 if (d != NULL) { 392 while ((de = readdir(d))) { 393 if (de->d_type == DT_DIR) { 394 const char *name = de->d_name; 395 /* skip any dir that doesn't start with a number, so not a user */ 396 if (name[0] < '0' || name[0] > '9') { 397 continue; 398 } 399 if ((strlen(name)+(dirpos-tmpdir)) < (sizeof(tmpdir)-1)) { 400 strcpy(dirpos, name); 401 if (lookup_media_dir(tmpdir, "Android") == 0 402 && lookup_media_dir(tmpdir, "data") == 0) { 403 //ALOGI("adding cache files from %s\n", tmpdir); 404 add_cache_files(cache, tmpdir, "cache"); 405 } 406 } else { 407 ALOGW("Path exceeds limit: %s%s", tmpdir, name); 408 } 409 } 410 } 411 closedir(d); 412 } 413 414 clear_cache_files(cache, free_size); 415 finish_cache_collection(cache); 416 417 return data_disk_free() >= free_size ? 0 : -1; 418 } 419 420 int move_dex(const char *src, const char *dst, const char *instruction_set) 421 { 422 char src_dex[PKG_PATH_MAX]; 423 char dst_dex[PKG_PATH_MAX]; 424 425 if (validate_apk_path(src)) { 426 ALOGE("invalid apk path '%s' (bad prefix)\n", src); 427 return -1; 428 } 429 if (validate_apk_path(dst)) { 430 ALOGE("invalid apk path '%s' (bad prefix)\n", dst); 431 return -1; 432 } 433 434 if (create_cache_path(src_dex, src, instruction_set)) return -1; 435 if (create_cache_path(dst_dex, dst, instruction_set)) return -1; 436 437 ALOGV("move %s -> %s\n", src_dex, dst_dex); 438 if (rename(src_dex, dst_dex) < 0) { 439 ALOGE("Couldn't move %s: %s\n", src_dex, strerror(errno)); 440 return -1; 441 } else { 442 return 0; 443 } 444 } 445 446 int rm_dex(const char *path, const char *instruction_set) 447 { 448 char dex_path[PKG_PATH_MAX]; 449 450 if (validate_apk_path(path) && validate_system_app_path(path)) { 451 ALOGE("invalid apk path '%s' (bad prefix)\n", path); 452 return -1; 453 } 454 455 if (create_cache_path(dex_path, path, instruction_set)) return -1; 456 457 ALOGV("unlink %s\n", dex_path); 458 if (unlink(dex_path) < 0) { 459 if (errno != ENOENT) { 460 ALOGE("Couldn't unlink %s: %s\n", dex_path, strerror(errno)); 461 } 462 return -1; 463 } else { 464 return 0; 465 } 466 } 467 468 int get_size(const char *pkgname, userid_t userid, const char *apkpath, 469 const char *libdirpath, const char *fwdlock_apkpath, const char *asecpath, 470 const char *instruction_set, int64_t *_codesize, int64_t *_datasize, 471 int64_t *_cachesize, int64_t* _asecsize) 472 { 473 DIR *d; 474 int dfd; 475 struct dirent *de; 476 struct stat s; 477 char path[PKG_PATH_MAX]; 478 479 int64_t codesize = 0; 480 int64_t datasize = 0; 481 int64_t cachesize = 0; 482 int64_t asecsize = 0; 483 484 /* count the source apk as code -- but only if it's not 485 * on the /system partition and its not on the sdcard. 486 */ 487 if (validate_system_app_path(apkpath) && 488 strncmp(apkpath, android_asec_dir.path, android_asec_dir.len) != 0) { 489 if (stat(apkpath, &s) == 0) { 490 codesize += stat_size(&s); 491 } 492 } 493 /* count the forward locked apk as code if it is given 494 */ 495 if (fwdlock_apkpath != NULL && fwdlock_apkpath[0] != '!') { 496 if (stat(fwdlock_apkpath, &s) == 0) { 497 codesize += stat_size(&s); 498 } 499 } 500 /* count the cached dexfile as code */ 501 if (!create_cache_path(path, apkpath, instruction_set)) { 502 if (stat(path, &s) == 0) { 503 codesize += stat_size(&s); 504 } 505 } 506 507 /* add in size of any libraries */ 508 if (libdirpath != NULL && libdirpath[0] != '!') { 509 d = opendir(libdirpath); 510 if (d != NULL) { 511 dfd = dirfd(d); 512 codesize += calculate_dir_size(dfd); 513 closedir(d); 514 } 515 } 516 517 /* compute asec size if it is given 518 */ 519 if (asecpath != NULL && asecpath[0] != '!') { 520 if (stat(asecpath, &s) == 0) { 521 asecsize += stat_size(&s); 522 } 523 } 524 525 if (create_pkg_path(path, pkgname, PKG_DIR_POSTFIX, userid)) { 526 goto done; 527 } 528 529 d = opendir(path); 530 if (d == NULL) { 531 goto done; 532 } 533 dfd = dirfd(d); 534 535 /* most stuff in the pkgdir is data, except for the "cache" 536 * directory and below, which is cache, and the "lib" directory 537 * and below, which is code... 538 */ 539 while ((de = readdir(d))) { 540 const char *name = de->d_name; 541 542 if (de->d_type == DT_DIR) { 543 int subfd; 544 int64_t statsize = 0; 545 int64_t dirsize = 0; 546 /* always skip "." and ".." */ 547 if (name[0] == '.') { 548 if (name[1] == 0) continue; 549 if ((name[1] == '.') && (name[2] == 0)) continue; 550 } 551 if (fstatat(dfd, name, &s, AT_SYMLINK_NOFOLLOW) == 0) { 552 statsize = stat_size(&s); 553 } 554 subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY); 555 if (subfd >= 0) { 556 dirsize = calculate_dir_size(subfd); 557 } 558 if(!strcmp(name,"lib")) { 559 codesize += dirsize + statsize; 560 } else if(!strcmp(name,"cache")) { 561 cachesize += dirsize + statsize; 562 } else { 563 datasize += dirsize + statsize; 564 } 565 } else if (de->d_type == DT_LNK && !strcmp(name,"lib")) { 566 // This is the symbolic link to the application's library 567 // code. We'll count this as code instead of data, since 568 // it is not something that the app creates. 569 if (fstatat(dfd, name, &s, AT_SYMLINK_NOFOLLOW) == 0) { 570 codesize += stat_size(&s); 571 } 572 } else { 573 if (fstatat(dfd, name, &s, AT_SYMLINK_NOFOLLOW) == 0) { 574 datasize += stat_size(&s); 575 } 576 } 577 } 578 closedir(d); 579 done: 580 *_codesize = codesize; 581 *_datasize = datasize; 582 *_cachesize = cachesize; 583 *_asecsize = asecsize; 584 return 0; 585 } 586 587 int create_cache_path(char path[PKG_PATH_MAX], const char *src, const char *instruction_set) 588 { 589 char *tmp; 590 int srclen; 591 int dstlen; 592 593 srclen = strlen(src); 594 595 /* demand that we are an absolute path */ 596 if ((src == 0) || (src[0] != '/') || strstr(src,"..")) { 597 return -1; 598 } 599 600 if (srclen > PKG_PATH_MAX) { // XXX: PKG_NAME_MAX? 601 return -1; 602 } 603 604 dstlen = srclen + strlen(DALVIK_CACHE_PREFIX) + 605 strlen(instruction_set) + 606 strlen(DALVIK_CACHE_POSTFIX) + 2; 607 608 if (dstlen > PKG_PATH_MAX) { 609 return -1; 610 } 611 612 sprintf(path,"%s%s/%s%s", 613 DALVIK_CACHE_PREFIX, 614 instruction_set, 615 src + 1, /* skip the leading / */ 616 DALVIK_CACHE_POSTFIX); 617 618 for(tmp = path + strlen(DALVIK_CACHE_PREFIX) + strlen(instruction_set) + 1; *tmp; tmp++) { 619 if (*tmp == '/') { 620 *tmp = '@'; 621 } 622 } 623 624 return 0; 625 } 626 627 static void run_dexopt(int zip_fd, int odex_fd, const char* input_file_name, 628 const char* output_file_name) 629 { 630 /* platform-specific flags affecting optimization and verification */ 631 char dexopt_flags[PROPERTY_VALUE_MAX]; 632 property_get("dalvik.vm.dexopt-flags", dexopt_flags, ""); 633 ALOGV("dalvik.vm.dexopt-flags=%s\n", dexopt_flags); 634 635 static const char* DEX_OPT_BIN = "/system/bin/dexopt"; 636 static const int MAX_INT_LEN = 12; // '-'+10dig+'\0' -OR- 0x+8dig 637 char zip_num[MAX_INT_LEN]; 638 char odex_num[MAX_INT_LEN]; 639 640 sprintf(zip_num, "%d", zip_fd); 641 sprintf(odex_num, "%d", odex_fd); 642 643 ALOGV("Running %s in=%s out=%s\n", DEX_OPT_BIN, input_file_name, output_file_name); 644 execl(DEX_OPT_BIN, DEX_OPT_BIN, "--zip", zip_num, odex_num, input_file_name, 645 dexopt_flags, (char*) NULL); 646 ALOGE("execl(%s) failed: %s\n", DEX_OPT_BIN, strerror(errno)); 647 } 648 649 static void run_patchoat(int input_fd, int oat_fd, const char* input_file_name, 650 const char* output_file_name, const char *pkgname, const char *instruction_set) 651 { 652 static const int MAX_INT_LEN = 12; // '-'+10dig+'\0' -OR- 0x+8dig 653 static const unsigned int MAX_INSTRUCTION_SET_LEN = 7; 654 655 static const char* PATCHOAT_BIN = "/system/bin/patchoat"; 656 if (strlen(instruction_set) >= MAX_INSTRUCTION_SET_LEN) { 657 ALOGE("Instruction set %s longer than max length of %d", 658 instruction_set, MAX_INSTRUCTION_SET_LEN); 659 return; 660 } 661 662 /* input_file_name/input_fd should be the .odex/.oat file that is precompiled. I think*/ 663 char instruction_set_arg[strlen("--instruction-set=") + MAX_INSTRUCTION_SET_LEN]; 664 char output_oat_fd_arg[strlen("--output-oat-fd=") + MAX_INT_LEN]; 665 char input_oat_fd_arg[strlen("--input-oat-fd=") + MAX_INT_LEN]; 666 const char* patched_image_location_arg = "--patched-image-location=/system/framework/boot.art"; 667 // The caller has already gotten all the locks we need. 668 const char* no_lock_arg = "--no-lock-output"; 669 sprintf(instruction_set_arg, "--instruction-set=%s", instruction_set); 670 sprintf(output_oat_fd_arg, "--output-oat-fd=%d", oat_fd); 671 sprintf(input_oat_fd_arg, "--input-oat-fd=%d", input_fd); 672 ALOGE("Running %s isa=%s in-fd=%d (%s) out-fd=%d (%s)\n", 673 PATCHOAT_BIN, instruction_set, input_fd, input_file_name, oat_fd, output_file_name); 674 675 /* patchoat, patched-image-location, no-lock, isa, input-fd, output-fd */ 676 char* argv[7]; 677 argv[0] = (char*) PATCHOAT_BIN; 678 argv[1] = (char*) patched_image_location_arg; 679 argv[2] = (char*) no_lock_arg; 680 argv[3] = instruction_set_arg; 681 argv[4] = output_oat_fd_arg; 682 argv[5] = input_oat_fd_arg; 683 argv[6] = NULL; 684 685 execv(PATCHOAT_BIN, (char* const *)argv); 686 ALOGE("execv(%s) failed: %s\n", PATCHOAT_BIN, strerror(errno)); 687 } 688 689 static void run_dex2oat(int zip_fd, int oat_fd, const char* input_file_name, 690 const char* output_file_name, const char *pkgname, const char *instruction_set, 691 bool vm_safe_mode) 692 { 693 static const unsigned int MAX_INSTRUCTION_SET_LEN = 7; 694 695 if (strlen(instruction_set) >= MAX_INSTRUCTION_SET_LEN) { 696 ALOGE("Instruction set %s longer than max length of %d", 697 instruction_set, MAX_INSTRUCTION_SET_LEN); 698 return; 699 } 700 701 char prop_buf[PROPERTY_VALUE_MAX]; 702 bool profiler = (property_get("dalvik.vm.profiler", prop_buf, "0") > 0) && (prop_buf[0] == '1'); 703 704 char dex2oat_Xms_flag[PROPERTY_VALUE_MAX]; 705 bool have_dex2oat_Xms_flag = property_get("dalvik.vm.dex2oat-Xms", dex2oat_Xms_flag, NULL) > 0; 706 707 char dex2oat_Xmx_flag[PROPERTY_VALUE_MAX]; 708 bool have_dex2oat_Xmx_flag = property_get("dalvik.vm.dex2oat-Xmx", dex2oat_Xmx_flag, NULL) > 0; 709 710 char dex2oat_compiler_filter_flag[PROPERTY_VALUE_MAX]; 711 bool have_dex2oat_compiler_filter_flag = property_get("dalvik.vm.dex2oat-filter", 712 dex2oat_compiler_filter_flag, NULL) > 0; 713 714 char dex2oat_isa_features_key[PROPERTY_KEY_MAX]; 715 sprintf(dex2oat_isa_features_key, "dalvik.vm.isa.%s.features", instruction_set); 716 char dex2oat_isa_features[PROPERTY_VALUE_MAX]; 717 bool have_dex2oat_isa_features = property_get(dex2oat_isa_features_key, 718 dex2oat_isa_features, NULL) > 0; 719 720 char dex2oat_flags[PROPERTY_VALUE_MAX]; 721 bool have_dex2oat_flags = property_get("dalvik.vm.dex2oat-flags", dex2oat_flags, NULL) > 0; 722 ALOGV("dalvik.vm.dex2oat-flags=%s\n", dex2oat_flags); 723 724 // If we booting without the real /data, don't spend time compiling. 725 char vold_decrypt[PROPERTY_VALUE_MAX]; 726 bool have_vold_decrypt = property_get("vold.decrypt", vold_decrypt, "") > 0; 727 bool skip_compilation = (have_vold_decrypt && 728 (strcmp(vold_decrypt, "trigger_restart_min_framework") == 0 || 729 (strcmp(vold_decrypt, "1") == 0))); 730 731 static const char* DEX2OAT_BIN = "/system/bin/dex2oat"; 732 733 static const char* RUNTIME_ARG = "--runtime-arg"; 734 735 static const int MAX_INT_LEN = 12; // '-'+10dig+'\0' -OR- 0x+8dig 736 737 char zip_fd_arg[strlen("--zip-fd=") + MAX_INT_LEN]; 738 char zip_location_arg[strlen("--zip-location=") + PKG_PATH_MAX]; 739 char oat_fd_arg[strlen("--oat-fd=") + MAX_INT_LEN]; 740 char oat_location_arg[strlen("--oat-location=") + PKG_PATH_MAX]; 741 char instruction_set_arg[strlen("--instruction-set=") + MAX_INSTRUCTION_SET_LEN]; 742 char instruction_set_features_arg[strlen("--instruction-set-features=") + PROPERTY_VALUE_MAX]; 743 char profile_file_arg[strlen("--profile-file=") + PKG_PATH_MAX]; 744 char top_k_profile_threshold_arg[strlen("--top-k-profile-threshold=") + PROPERTY_VALUE_MAX]; 745 char dex2oat_Xms_arg[strlen("-Xms") + PROPERTY_VALUE_MAX]; 746 char dex2oat_Xmx_arg[strlen("-Xmx") + PROPERTY_VALUE_MAX]; 747 char dex2oat_compiler_filter_arg[strlen("--compiler-filter=") + PROPERTY_VALUE_MAX]; 748 749 sprintf(zip_fd_arg, "--zip-fd=%d", zip_fd); 750 sprintf(zip_location_arg, "--zip-location=%s", input_file_name); 751 sprintf(oat_fd_arg, "--oat-fd=%d", oat_fd); 752 sprintf(oat_location_arg, "--oat-location=%s", output_file_name); 753 sprintf(instruction_set_arg, "--instruction-set=%s", instruction_set); 754 sprintf(instruction_set_features_arg, "--instruction-set-features=%s", dex2oat_isa_features); 755 756 bool have_profile_file = false; 757 bool have_top_k_profile_threshold = false; 758 if (profiler && (strcmp(pkgname, "*") != 0)) { 759 char profile_file[PKG_PATH_MAX]; 760 snprintf(profile_file, sizeof(profile_file), "%s/%s", 761 DALVIK_CACHE_PREFIX "profiles", pkgname); 762 struct stat st; 763 if ((stat(profile_file, &st) == 0) && (st.st_size > 0)) { 764 sprintf(profile_file_arg, "--profile-file=%s", profile_file); 765 have_profile_file = true; 766 if (property_get("dalvik.vm.profile.top-k-thr", prop_buf, NULL) > 0) { 767 snprintf(top_k_profile_threshold_arg, sizeof(top_k_profile_threshold_arg), 768 "--top-k-profile-threshold=%s", prop_buf); 769 have_top_k_profile_threshold = true; 770 } 771 } 772 } 773 774 if (have_dex2oat_Xms_flag) { 775 sprintf(dex2oat_Xms_arg, "-Xms%s", dex2oat_Xms_flag); 776 } 777 if (have_dex2oat_Xmx_flag) { 778 sprintf(dex2oat_Xmx_arg, "-Xmx%s", dex2oat_Xmx_flag); 779 } 780 if (skip_compilation) { 781 strcpy(dex2oat_compiler_filter_arg, "--compiler-filter=verify-none"); 782 have_dex2oat_compiler_filter_flag = true; 783 } else if (vm_safe_mode) { 784 strcpy(dex2oat_compiler_filter_arg, "--compiler-filter=interpret-only"); 785 have_dex2oat_compiler_filter_flag = true; 786 } else if (have_dex2oat_compiler_filter_flag) { 787 sprintf(dex2oat_compiler_filter_arg, "--compiler-filter=%s", dex2oat_compiler_filter_flag); 788 } 789 790 ALOGV("Running %s in=%s out=%s\n", DEX2OAT_BIN, input_file_name, output_file_name); 791 792 char* argv[7 // program name, mandatory arguments and the final NULL 793 + (have_dex2oat_isa_features ? 1 : 0) 794 + (have_profile_file ? 1 : 0) 795 + (have_top_k_profile_threshold ? 1 : 0) 796 + (have_dex2oat_Xms_flag ? 2 : 0) 797 + (have_dex2oat_Xmx_flag ? 2 : 0) 798 + (have_dex2oat_compiler_filter_flag ? 1 : 0) 799 + (have_dex2oat_flags ? 1 : 0)]; 800 int i = 0; 801 argv[i++] = (char*)DEX2OAT_BIN; 802 argv[i++] = zip_fd_arg; 803 argv[i++] = zip_location_arg; 804 argv[i++] = oat_fd_arg; 805 argv[i++] = oat_location_arg; 806 argv[i++] = instruction_set_arg; 807 if (have_dex2oat_isa_features) { 808 argv[i++] = instruction_set_features_arg; 809 } 810 if (have_profile_file) { 811 argv[i++] = profile_file_arg; 812 } 813 if (have_top_k_profile_threshold) { 814 argv[i++] = top_k_profile_threshold_arg; 815 } 816 if (have_dex2oat_Xms_flag) { 817 argv[i++] = (char*)RUNTIME_ARG; 818 argv[i++] = dex2oat_Xms_arg; 819 } 820 if (have_dex2oat_Xmx_flag) { 821 argv[i++] = (char*)RUNTIME_ARG; 822 argv[i++] = dex2oat_Xmx_arg; 823 } 824 if (have_dex2oat_compiler_filter_flag) { 825 argv[i++] = dex2oat_compiler_filter_arg; 826 } 827 if (have_dex2oat_flags) { 828 argv[i++] = dex2oat_flags; 829 } 830 // Do not add after dex2oat_flags, they should override others for debugging. 831 argv[i] = NULL; 832 833 execv(DEX2OAT_BIN, (char* const *)argv); 834 ALOGE("execl(%s) failed: %s\n", DEX2OAT_BIN, strerror(errno)); 835 } 836 837 static int wait_child(pid_t pid) 838 { 839 int status; 840 pid_t got_pid; 841 842 while (1) { 843 got_pid = waitpid(pid, &status, 0); 844 if (got_pid == -1 && errno == EINTR) { 845 printf("waitpid interrupted, retrying\n"); 846 } else { 847 break; 848 } 849 } 850 if (got_pid != pid) { 851 ALOGW("waitpid failed: wanted %d, got %d: %s\n", 852 (int) pid, (int) got_pid, strerror(errno)); 853 return 1; 854 } 855 856 if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { 857 return 0; 858 } else { 859 return status; /* always nonzero */ 860 } 861 } 862 863 int dexopt(const char *apk_path, uid_t uid, bool is_public, 864 const char *pkgname, const char *instruction_set, 865 bool vm_safe_mode, bool is_patchoat) 866 { 867 struct utimbuf ut; 868 struct stat input_stat, dex_stat; 869 char out_path[PKG_PATH_MAX]; 870 char persist_sys_dalvik_vm_lib[PROPERTY_VALUE_MAX]; 871 char *end; 872 const char *input_file; 873 char in_odex_path[PKG_PATH_MAX]; 874 int res, input_fd=-1, out_fd=-1; 875 876 if (strlen(apk_path) >= (PKG_PATH_MAX - 8)) { 877 return -1; 878 } 879 880 /* The command to run depend on the value of persist.sys.dalvik.vm.lib */ 881 property_get("persist.sys.dalvik.vm.lib.2", persist_sys_dalvik_vm_lib, "libart.so"); 882 883 if (is_patchoat && strncmp(persist_sys_dalvik_vm_lib, "libart", 6) != 0) { 884 /* We may only patch if we are libart */ 885 ALOGE("Patching is only supported in libart\n"); 886 return -1; 887 } 888 889 /* Before anything else: is there a .odex file? If so, we have 890 * precompiled the apk and there is nothing to do here. 891 * 892 * We skip this if we are doing a patchoat. 893 */ 894 strcpy(out_path, apk_path); 895 end = strrchr(out_path, '.'); 896 if (end != NULL && !is_patchoat) { 897 strcpy(end, ".odex"); 898 if (stat(out_path, &dex_stat) == 0) { 899 return 0; 900 } 901 } 902 903 if (create_cache_path(out_path, apk_path, instruction_set)) { 904 return -1; 905 } 906 907 if (is_patchoat) { 908 /* /system/framework/whatever.jar -> /system/framework/<isa>/whatever.odex */ 909 strcpy(in_odex_path, apk_path); 910 end = strrchr(in_odex_path, '/'); 911 if (end == NULL) { 912 ALOGE("apk_path '%s' has no '/'s in it?!\n", apk_path); 913 return -1; 914 } 915 const char *apk_end = apk_path + (end - in_odex_path); // strrchr(apk_path, '/'); 916 strcpy(end + 1, instruction_set); // in_odex_path now is /system/framework/<isa>\0 917 strcat(in_odex_path, apk_end); 918 end = strrchr(in_odex_path, '.'); 919 if (end == NULL) { 920 return -1; 921 } 922 strcpy(end + 1, "odex"); 923 input_file = in_odex_path; 924 } else { 925 input_file = apk_path; 926 } 927 928 memset(&input_stat, 0, sizeof(input_stat)); 929 stat(input_file, &input_stat); 930 931 input_fd = open(input_file, O_RDONLY, 0); 932 if (input_fd < 0) { 933 ALOGE("installd cannot open '%s' for input during dexopt\n", input_file); 934 return -1; 935 } 936 937 unlink(out_path); 938 out_fd = open(out_path, O_RDWR | O_CREAT | O_EXCL, 0644); 939 if (out_fd < 0) { 940 ALOGE("installd cannot open '%s' for output during dexopt\n", out_path); 941 goto fail; 942 } 943 if (fchmod(out_fd, 944 S_IRUSR|S_IWUSR|S_IRGRP | 945 (is_public ? S_IROTH : 0)) < 0) { 946 ALOGE("installd cannot chmod '%s' during dexopt\n", out_path); 947 goto fail; 948 } 949 if (fchown(out_fd, AID_SYSTEM, uid) < 0) { 950 ALOGE("installd cannot chown '%s' during dexopt\n", out_path); 951 goto fail; 952 } 953 954 // Create profile file if there is a package name present. 955 if (strcmp(pkgname, "*") != 0) { 956 create_profile_file(pkgname, uid); 957 } 958 959 960 ALOGV("DexInv: --- BEGIN '%s' ---\n", input_file); 961 962 pid_t pid; 963 pid = fork(); 964 if (pid == 0) { 965 /* child -- drop privileges before continuing */ 966 if (setgid(uid) != 0) { 967 ALOGE("setgid(%d) failed in installd during dexopt\n", uid); 968 exit(64); 969 } 970 if (setuid(uid) != 0) { 971 ALOGE("setuid(%d) failed in installd during dexopt\n", uid); 972 exit(65); 973 } 974 // drop capabilities 975 struct __user_cap_header_struct capheader; 976 struct __user_cap_data_struct capdata[2]; 977 memset(&capheader, 0, sizeof(capheader)); 978 memset(&capdata, 0, sizeof(capdata)); 979 capheader.version = _LINUX_CAPABILITY_VERSION_3; 980 if (capset(&capheader, &capdata[0]) < 0) { 981 ALOGE("capset failed: %s\n", strerror(errno)); 982 exit(66); 983 } 984 if (set_sched_policy(0, SP_BACKGROUND) < 0) { 985 ALOGE("set_sched_policy failed: %s\n", strerror(errno)); 986 exit(70); 987 } 988 if (flock(out_fd, LOCK_EX | LOCK_NB) != 0) { 989 ALOGE("flock(%s) failed: %s\n", out_path, strerror(errno)); 990 exit(67); 991 } 992 993 if (strncmp(persist_sys_dalvik_vm_lib, "libdvm", 6) == 0) { 994 run_dexopt(input_fd, out_fd, input_file, out_path); 995 } else if (strncmp(persist_sys_dalvik_vm_lib, "libart", 6) == 0) { 996 if (is_patchoat) { 997 run_patchoat(input_fd, out_fd, input_file, out_path, pkgname, instruction_set); 998 } else { 999 run_dex2oat(input_fd, out_fd, input_file, out_path, pkgname, instruction_set, 1000 vm_safe_mode); 1001 } 1002 } else { 1003 exit(69); /* Unexpected persist.sys.dalvik.vm.lib value */ 1004 } 1005 exit(68); /* only get here on exec failure */ 1006 } else { 1007 res = wait_child(pid); 1008 if (res == 0) { 1009 ALOGV("DexInv: --- END '%s' (success) ---\n", input_file); 1010 } else { 1011 ALOGE("DexInv: --- END '%s' --- status=0x%04x, process failed\n", input_file, res); 1012 goto fail; 1013 } 1014 } 1015 1016 ut.actime = input_stat.st_atime; 1017 ut.modtime = input_stat.st_mtime; 1018 utime(out_path, &ut); 1019 1020 close(out_fd); 1021 close(input_fd); 1022 return 0; 1023 1024 fail: 1025 if (out_fd >= 0) { 1026 close(out_fd); 1027 unlink(out_path); 1028 } 1029 if (input_fd >= 0) { 1030 close(input_fd); 1031 } 1032 return -1; 1033 } 1034 1035 void mkinnerdirs(char* path, int basepos, mode_t mode, int uid, int gid, 1036 struct stat* statbuf) 1037 { 1038 while (path[basepos] != 0) { 1039 if (path[basepos] == '/') { 1040 path[basepos] = 0; 1041 if (lstat(path, statbuf) < 0) { 1042 ALOGV("Making directory: %s\n", path); 1043 if (mkdir(path, mode) == 0) { 1044 chown(path, uid, gid); 1045 } else { 1046 ALOGW("Unable to make directory %s: %s\n", path, strerror(errno)); 1047 } 1048 } 1049 path[basepos] = '/'; 1050 basepos++; 1051 } 1052 basepos++; 1053 } 1054 } 1055 1056 int movefileordir(char* srcpath, char* dstpath, int dstbasepos, 1057 int dstuid, int dstgid, struct stat* statbuf) 1058 { 1059 DIR *d; 1060 struct dirent *de; 1061 int res; 1062 1063 int srcend = strlen(srcpath); 1064 int dstend = strlen(dstpath); 1065 1066 if (lstat(srcpath, statbuf) < 0) { 1067 ALOGW("Unable to stat %s: %s\n", srcpath, strerror(errno)); 1068 return 1; 1069 } 1070 1071 if ((statbuf->st_mode&S_IFDIR) == 0) { 1072 mkinnerdirs(dstpath, dstbasepos, S_IRWXU|S_IRWXG|S_IXOTH, 1073 dstuid, dstgid, statbuf); 1074 ALOGV("Renaming %s to %s (uid %d)\n", srcpath, dstpath, dstuid); 1075 if (rename(srcpath, dstpath) >= 0) { 1076 if (chown(dstpath, dstuid, dstgid) < 0) { 1077 ALOGE("cannot chown %s: %s\n", dstpath, strerror(errno)); 1078 unlink(dstpath); 1079 return 1; 1080 } 1081 } else { 1082 ALOGW("Unable to rename %s to %s: %s\n", 1083 srcpath, dstpath, strerror(errno)); 1084 return 1; 1085 } 1086 return 0; 1087 } 1088 1089 d = opendir(srcpath); 1090 if (d == NULL) { 1091 ALOGW("Unable to opendir %s: %s\n", srcpath, strerror(errno)); 1092 return 1; 1093 } 1094 1095 res = 0; 1096 1097 while ((de = readdir(d))) { 1098 const char *name = de->d_name; 1099 /* always skip "." and ".." */ 1100 if (name[0] == '.') { 1101 if (name[1] == 0) continue; 1102 if ((name[1] == '.') && (name[2] == 0)) continue; 1103 } 1104 1105 if ((srcend+strlen(name)) >= (PKG_PATH_MAX-2)) { 1106 ALOGW("Source path too long; skipping: %s/%s\n", srcpath, name); 1107 continue; 1108 } 1109 1110 if ((dstend+strlen(name)) >= (PKG_PATH_MAX-2)) { 1111 ALOGW("Destination path too long; skipping: %s/%s\n", dstpath, name); 1112 continue; 1113 } 1114 1115 srcpath[srcend] = dstpath[dstend] = '/'; 1116 strcpy(srcpath+srcend+1, name); 1117 strcpy(dstpath+dstend+1, name); 1118 1119 if (movefileordir(srcpath, dstpath, dstbasepos, dstuid, dstgid, statbuf) != 0) { 1120 res = 1; 1121 } 1122 1123 // Note: we will be leaving empty directories behind in srcpath, 1124 // but that is okay, the package manager will be erasing all of the 1125 // data associated with .apks that disappear. 1126 1127 srcpath[srcend] = dstpath[dstend] = 0; 1128 } 1129 1130 closedir(d); 1131 return res; 1132 } 1133 1134 int movefiles() 1135 { 1136 DIR *d; 1137 int dfd, subfd; 1138 struct dirent *de; 1139 struct stat s; 1140 char buf[PKG_PATH_MAX+1]; 1141 int bufp, bufe, bufi, readlen; 1142 1143 char srcpkg[PKG_NAME_MAX]; 1144 char dstpkg[PKG_NAME_MAX]; 1145 char srcpath[PKG_PATH_MAX]; 1146 char dstpath[PKG_PATH_MAX]; 1147 int dstuid=-1, dstgid=-1; 1148 int hasspace; 1149 1150 d = opendir(UPDATE_COMMANDS_DIR_PREFIX); 1151 if (d == NULL) { 1152 goto done; 1153 } 1154 dfd = dirfd(d); 1155 1156 /* Iterate through all files in the directory, executing the 1157 * file movements requested there-in. 1158 */ 1159 while ((de = readdir(d))) { 1160 const char *name = de->d_name; 1161 1162 if (de->d_type == DT_DIR) { 1163 continue; 1164 } else { 1165 subfd = openat(dfd, name, O_RDONLY); 1166 if (subfd < 0) { 1167 ALOGW("Unable to open update commands at %s%s\n", 1168 UPDATE_COMMANDS_DIR_PREFIX, name); 1169 continue; 1170 } 1171 1172 bufp = 0; 1173 bufe = 0; 1174 buf[PKG_PATH_MAX] = 0; 1175 srcpkg[0] = dstpkg[0] = 0; 1176 while (1) { 1177 bufi = bufp; 1178 while (bufi < bufe && buf[bufi] != '\n') { 1179 bufi++; 1180 } 1181 if (bufi < bufe) { 1182 buf[bufi] = 0; 1183 ALOGV("Processing line: %s\n", buf+bufp); 1184 hasspace = 0; 1185 while (bufp < bufi && isspace(buf[bufp])) { 1186 hasspace = 1; 1187 bufp++; 1188 } 1189 if (buf[bufp] == '#' || bufp == bufi) { 1190 // skip comments and empty lines. 1191 } else if (hasspace) { 1192 if (dstpkg[0] == 0) { 1193 ALOGW("Path before package line in %s%s: %s\n", 1194 UPDATE_COMMANDS_DIR_PREFIX, name, buf+bufp); 1195 } else if (srcpkg[0] == 0) { 1196 // Skip -- source package no longer exists. 1197 } else { 1198 ALOGV("Move file: %s (from %s to %s)\n", buf+bufp, srcpkg, dstpkg); 1199 if (!create_move_path(srcpath, srcpkg, buf+bufp, 0) && 1200 !create_move_path(dstpath, dstpkg, buf+bufp, 0)) { 1201 movefileordir(srcpath, dstpath, 1202 strlen(dstpath)-strlen(buf+bufp), 1203 dstuid, dstgid, &s); 1204 } 1205 } 1206 } else { 1207 char* div = strchr(buf+bufp, ':'); 1208 if (div == NULL) { 1209 ALOGW("Bad package spec in %s%s; no ':' sep: %s\n", 1210 UPDATE_COMMANDS_DIR_PREFIX, name, buf+bufp); 1211 } else { 1212 *div = 0; 1213 div++; 1214 if (strlen(buf+bufp) < PKG_NAME_MAX) { 1215 strcpy(dstpkg, buf+bufp); 1216 } else { 1217 srcpkg[0] = dstpkg[0] = 0; 1218 ALOGW("Package name too long in %s%s: %s\n", 1219 UPDATE_COMMANDS_DIR_PREFIX, name, buf+bufp); 1220 } 1221 if (strlen(div) < PKG_NAME_MAX) { 1222 strcpy(srcpkg, div); 1223 } else { 1224 srcpkg[0] = dstpkg[0] = 0; 1225 ALOGW("Package name too long in %s%s: %s\n", 1226 UPDATE_COMMANDS_DIR_PREFIX, name, div); 1227 } 1228 if (srcpkg[0] != 0) { 1229 if (!create_pkg_path(srcpath, srcpkg, PKG_DIR_POSTFIX, 0)) { 1230 if (lstat(srcpath, &s) < 0) { 1231 // Package no longer exists -- skip. 1232 srcpkg[0] = 0; 1233 } 1234 } else { 1235 srcpkg[0] = 0; 1236 ALOGW("Can't create path %s in %s%s\n", 1237 div, UPDATE_COMMANDS_DIR_PREFIX, name); 1238 } 1239 if (srcpkg[0] != 0) { 1240 if (!create_pkg_path(dstpath, dstpkg, PKG_DIR_POSTFIX, 0)) { 1241 if (lstat(dstpath, &s) == 0) { 1242 dstuid = s.st_uid; 1243 dstgid = s.st_gid; 1244 } else { 1245 // Destination package doesn't 1246 // exist... due to original-package, 1247 // this is normal, so don't be 1248 // noisy about it. 1249 srcpkg[0] = 0; 1250 } 1251 } else { 1252 srcpkg[0] = 0; 1253 ALOGW("Can't create path %s in %s%s\n", 1254 div, UPDATE_COMMANDS_DIR_PREFIX, name); 1255 } 1256 } 1257 ALOGV("Transfering from %s to %s: uid=%d\n", 1258 srcpkg, dstpkg, dstuid); 1259 } 1260 } 1261 } 1262 bufp = bufi+1; 1263 } else { 1264 if (bufp == 0) { 1265 if (bufp < bufe) { 1266 ALOGW("Line too long in %s%s, skipping: %s\n", 1267 UPDATE_COMMANDS_DIR_PREFIX, name, buf); 1268 } 1269 } else if (bufp < bufe) { 1270 memcpy(buf, buf+bufp, bufe-bufp); 1271 bufe -= bufp; 1272 bufp = 0; 1273 } 1274 readlen = read(subfd, buf+bufe, PKG_PATH_MAX-bufe); 1275 if (readlen < 0) { 1276 ALOGW("Failure reading update commands in %s%s: %s\n", 1277 UPDATE_COMMANDS_DIR_PREFIX, name, strerror(errno)); 1278 break; 1279 } else if (readlen == 0) { 1280 break; 1281 } 1282 bufe += readlen; 1283 buf[bufe] = 0; 1284 ALOGV("Read buf: %s\n", buf); 1285 } 1286 } 1287 close(subfd); 1288 } 1289 } 1290 closedir(d); 1291 done: 1292 return 0; 1293 } 1294 1295 int linklib(const char* pkgname, const char* asecLibDir, int userId) 1296 { 1297 char pkgdir[PKG_PATH_MAX]; 1298 char libsymlink[PKG_PATH_MAX]; 1299 struct stat s, libStat; 1300 int rc = 0; 1301 1302 if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, userId)) { 1303 ALOGE("cannot create package path\n"); 1304 return -1; 1305 } 1306 if (create_pkg_path(libsymlink, pkgname, PKG_LIB_POSTFIX, userId)) { 1307 ALOGE("cannot create package lib symlink origin path\n"); 1308 return -1; 1309 } 1310 1311 if (stat(pkgdir, &s) < 0) return -1; 1312 1313 if (chown(pkgdir, AID_INSTALL, AID_INSTALL) < 0) { 1314 ALOGE("failed to chown '%s': %s\n", pkgdir, strerror(errno)); 1315 return -1; 1316 } 1317 1318 if (chmod(pkgdir, 0700) < 0) { 1319 ALOGE("linklib() 1: failed to chmod '%s': %s\n", pkgdir, strerror(errno)); 1320 rc = -1; 1321 goto out; 1322 } 1323 1324 if (lstat(libsymlink, &libStat) < 0) { 1325 if (errno != ENOENT) { 1326 ALOGE("couldn't stat lib dir: %s\n", strerror(errno)); 1327 rc = -1; 1328 goto out; 1329 } 1330 } else { 1331 if (S_ISDIR(libStat.st_mode)) { 1332 if (delete_dir_contents(libsymlink, 1, NULL) < 0) { 1333 rc = -1; 1334 goto out; 1335 } 1336 } else if (S_ISLNK(libStat.st_mode)) { 1337 if (unlink(libsymlink) < 0) { 1338 ALOGE("couldn't unlink lib dir: %s\n", strerror(errno)); 1339 rc = -1; 1340 goto out; 1341 } 1342 } 1343 } 1344 1345 if (symlink(asecLibDir, libsymlink) < 0) { 1346 ALOGE("couldn't symlink directory '%s' -> '%s': %s\n", libsymlink, asecLibDir, 1347 strerror(errno)); 1348 rc = -errno; 1349 goto out; 1350 } 1351 1352 out: 1353 if (chmod(pkgdir, s.st_mode) < 0) { 1354 ALOGE("linklib() 2: failed to chmod '%s': %s\n", pkgdir, strerror(errno)); 1355 rc = -errno; 1356 } 1357 1358 if (chown(pkgdir, s.st_uid, s.st_gid) < 0) { 1359 ALOGE("failed to chown '%s' : %s\n", pkgdir, strerror(errno)); 1360 return -errno; 1361 } 1362 1363 return rc; 1364 } 1365 1366 static void run_idmap(const char *target_apk, const char *overlay_apk, int idmap_fd) 1367 { 1368 static const char *IDMAP_BIN = "/system/bin/idmap"; 1369 static const size_t MAX_INT_LEN = 32; 1370 char idmap_str[MAX_INT_LEN]; 1371 1372 snprintf(idmap_str, sizeof(idmap_str), "%d", idmap_fd); 1373 1374 execl(IDMAP_BIN, IDMAP_BIN, "--fd", target_apk, overlay_apk, idmap_str, (char*)NULL); 1375 ALOGE("execl(%s) failed: %s\n", IDMAP_BIN, strerror(errno)); 1376 } 1377 1378 // Transform string /a/b/c.apk to (prefix)/a@b (at) c.apk@(suffix) 1379 // eg /a/b/c.apk to /data/resource-cache/a@b (at) c.apk@idmap 1380 static int flatten_path(const char *prefix, const char *suffix, 1381 const char *overlay_path, char *idmap_path, size_t N) 1382 { 1383 if (overlay_path == NULL || idmap_path == NULL) { 1384 return -1; 1385 } 1386 const size_t len_overlay_path = strlen(overlay_path); 1387 // will access overlay_path + 1 further below; requires absolute path 1388 if (len_overlay_path < 2 || *overlay_path != '/') { 1389 return -1; 1390 } 1391 const size_t len_idmap_root = strlen(prefix); 1392 const size_t len_suffix = strlen(suffix); 1393 if (SIZE_MAX - len_idmap_root < len_overlay_path || 1394 SIZE_MAX - (len_idmap_root + len_overlay_path) < len_suffix) { 1395 // additions below would cause overflow 1396 return -1; 1397 } 1398 if (N < len_idmap_root + len_overlay_path + len_suffix) { 1399 return -1; 1400 } 1401 memset(idmap_path, 0, N); 1402 snprintf(idmap_path, N, "%s%s%s", prefix, overlay_path + 1, suffix); 1403 char *ch = idmap_path + len_idmap_root; 1404 while (*ch != '\0') { 1405 if (*ch == '/') { 1406 *ch = '@'; 1407 } 1408 ++ch; 1409 } 1410 return 0; 1411 } 1412 1413 int idmap(const char *target_apk, const char *overlay_apk, uid_t uid) 1414 { 1415 ALOGV("idmap target_apk=%s overlay_apk=%s uid=%d\n", target_apk, overlay_apk, uid); 1416 1417 int idmap_fd = -1; 1418 char idmap_path[PATH_MAX]; 1419 1420 if (flatten_path(IDMAP_PREFIX, IDMAP_SUFFIX, overlay_apk, 1421 idmap_path, sizeof(idmap_path)) == -1) { 1422 ALOGE("idmap cannot generate idmap path for overlay %s\n", overlay_apk); 1423 goto fail; 1424 } 1425 1426 unlink(idmap_path); 1427 idmap_fd = open(idmap_path, O_RDWR | O_CREAT | O_EXCL, 0644); 1428 if (idmap_fd < 0) { 1429 ALOGE("idmap cannot open '%s' for output: %s\n", idmap_path, strerror(errno)); 1430 goto fail; 1431 } 1432 if (fchown(idmap_fd, AID_SYSTEM, uid) < 0) { 1433 ALOGE("idmap cannot chown '%s'\n", idmap_path); 1434 goto fail; 1435 } 1436 if (fchmod(idmap_fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0) { 1437 ALOGE("idmap cannot chmod '%s'\n", idmap_path); 1438 goto fail; 1439 } 1440 1441 pid_t pid; 1442 pid = fork(); 1443 if (pid == 0) { 1444 /* child -- drop privileges before continuing */ 1445 if (setgid(uid) != 0) { 1446 ALOGE("setgid(%d) failed during idmap\n", uid); 1447 exit(1); 1448 } 1449 if (setuid(uid) != 0) { 1450 ALOGE("setuid(%d) failed during idmap\n", uid); 1451 exit(1); 1452 } 1453 if (flock(idmap_fd, LOCK_EX | LOCK_NB) != 0) { 1454 ALOGE("flock(%s) failed during idmap: %s\n", idmap_path, strerror(errno)); 1455 exit(1); 1456 } 1457 1458 run_idmap(target_apk, overlay_apk, idmap_fd); 1459 exit(1); /* only if exec call to idmap failed */ 1460 } else { 1461 int status = wait_child(pid); 1462 if (status != 0) { 1463 ALOGE("idmap failed, status=0x%04x\n", status); 1464 goto fail; 1465 } 1466 } 1467 1468 close(idmap_fd); 1469 return 0; 1470 fail: 1471 if (idmap_fd >= 0) { 1472 close(idmap_fd); 1473 unlink(idmap_path); 1474 } 1475 return -1; 1476 } 1477 1478 int restorecon_data(const char* pkgName, const char* seinfo, uid_t uid) 1479 { 1480 struct dirent *entry; 1481 DIR *d; 1482 struct stat s; 1483 char *userdir; 1484 char *primarydir; 1485 char *pkgdir; 1486 int ret = 0; 1487 1488 // SELINUX_ANDROID_RESTORECON_DATADATA flag is set by libselinux. Not needed here. 1489 unsigned int flags = SELINUX_ANDROID_RESTORECON_RECURSE; 1490 1491 if (!pkgName || !seinfo) { 1492 ALOGE("Package name or seinfo tag is null when trying to restorecon."); 1493 return -1; 1494 } 1495 1496 if (asprintf(&primarydir, "%s%s%s", android_data_dir.path, PRIMARY_USER_PREFIX, pkgName) < 0) { 1497 return -1; 1498 } 1499 1500 // Relabel for primary user. 1501 if (selinux_android_restorecon_pkgdir(primarydir, seinfo, uid, flags) < 0) { 1502 ALOGE("restorecon failed for %s: %s\n", primarydir, strerror(errno)); 1503 ret |= -1; 1504 } 1505 1506 if (asprintf(&userdir, "%s%s", android_data_dir.path, SECONDARY_USER_PREFIX) < 0) { 1507 free(primarydir); 1508 return -1; 1509 } 1510 1511 // Relabel package directory for all secondary users. 1512 d = opendir(userdir); 1513 if (d == NULL) { 1514 free(primarydir); 1515 free(userdir); 1516 return -1; 1517 } 1518 1519 while ((entry = readdir(d))) { 1520 if (entry->d_type != DT_DIR) { 1521 continue; 1522 } 1523 1524 const char *user = entry->d_name; 1525 // Ignore "." and ".." 1526 if (!strcmp(user, ".") || !strcmp(user, "..")) { 1527 continue; 1528 } 1529 1530 // user directories start with a number 1531 if (user[0] < '0' || user[0] > '9') { 1532 ALOGE("Expecting numbered directory during restorecon. Instead got '%s'.", user); 1533 continue; 1534 } 1535 1536 if (asprintf(&pkgdir, "%s%s/%s", userdir, user, pkgName) < 0) { 1537 continue; 1538 } 1539 1540 if (stat(pkgdir, &s) < 0) { 1541 free(pkgdir); 1542 continue; 1543 } 1544 1545 if (selinux_android_restorecon_pkgdir(pkgdir, seinfo, uid, flags) < 0) { 1546 ALOGE("restorecon failed for %s: %s\n", pkgdir, strerror(errno)); 1547 ret |= -1; 1548 } 1549 free(pkgdir); 1550 } 1551 1552 closedir(d); 1553 free(primarydir); 1554 free(userdir); 1555 return ret; 1556 } 1557 1558