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 "utils.h" 18 19 #include <errno.h> 20 #include <fcntl.h> 21 #include <fts.h> 22 #include <stdlib.h> 23 #include <sys/stat.h> 24 #include <sys/wait.h> 25 #include <sys/xattr.h> 26 #include <sys/statvfs.h> 27 28 #include <android-base/logging.h> 29 #include <android-base/stringprintf.h> 30 #include <cutils/fs.h> 31 #include <cutils/properties.h> 32 #include <log/log.h> 33 #include <private/android_filesystem_config.h> 34 35 #include "globals.h" // extern variables. 36 37 #ifndef LOG_TAG 38 #define LOG_TAG "installd" 39 #endif 40 41 #define DEBUG_XATTRS 0 42 43 using android::base::StringPrintf; 44 45 namespace android { 46 namespace installd { 47 48 /** 49 * Check that given string is valid filename, and that it attempts no 50 * parent or child directory traversal. 51 */ 52 bool is_valid_filename(const std::string& name) { 53 if (name.empty() || (name == ".") || (name == "..") 54 || (name.find('/') != std::string::npos)) { 55 return false; 56 } else { 57 return true; 58 } 59 } 60 61 static void check_package_name(const char* package_name) { 62 CHECK(is_valid_filename(package_name)); 63 CHECK(is_valid_package_name(package_name)); 64 } 65 66 /** 67 * Create the path name where package app contents should be stored for 68 * the given volume UUID and package name. An empty UUID is assumed to 69 * be internal storage. 70 */ 71 std::string create_data_app_package_path(const char* volume_uuid, 72 const char* package_name) { 73 check_package_name(package_name); 74 return StringPrintf("%s/%s", 75 create_data_app_path(volume_uuid).c_str(), package_name); 76 } 77 78 /** 79 * Create the path name where package data should be stored for the given 80 * volume UUID, package name, and user ID. An empty UUID is assumed to be 81 * internal storage. 82 */ 83 std::string create_data_user_ce_package_path(const char* volume_uuid, 84 userid_t user, const char* package_name) { 85 check_package_name(package_name); 86 return StringPrintf("%s/%s", 87 create_data_user_ce_path(volume_uuid, user).c_str(), package_name); 88 } 89 90 std::string create_data_user_ce_package_path(const char* volume_uuid, userid_t user, 91 const char* package_name, ino_t ce_data_inode) { 92 // For testing purposes, rely on the inode when defined; this could be 93 // optimized to use access() in the future. 94 auto fallback = create_data_user_ce_package_path(volume_uuid, user, package_name); 95 if (ce_data_inode != 0) { 96 auto user_path = create_data_user_ce_path(volume_uuid, user); 97 DIR* dir = opendir(user_path.c_str()); 98 if (dir == nullptr) { 99 PLOG(ERROR) << "Failed to opendir " << user_path; 100 return fallback; 101 } 102 103 struct dirent* ent; 104 while ((ent = readdir(dir))) { 105 if (ent->d_ino == ce_data_inode) { 106 auto resolved = StringPrintf("%s/%s", user_path.c_str(), ent->d_name); 107 #if DEBUG_XATTRS 108 if (resolved != fallback) { 109 LOG(DEBUG) << "Resolved path " << resolved << " for inode " << ce_data_inode 110 << " instead of " << fallback; 111 } 112 #endif 113 closedir(dir); 114 return resolved; 115 } 116 } 117 LOG(WARNING) << "Failed to resolve inode " << ce_data_inode << "; using " << fallback; 118 closedir(dir); 119 return fallback; 120 } else { 121 return fallback; 122 } 123 } 124 125 std::string create_data_user_de_package_path(const char* volume_uuid, 126 userid_t user, const char* package_name) { 127 check_package_name(package_name); 128 return StringPrintf("%s/%s", 129 create_data_user_de_path(volume_uuid, user).c_str(), package_name); 130 } 131 132 int create_pkg_path(char path[PKG_PATH_MAX], const char *pkgname, 133 const char *postfix, userid_t userid) { 134 if (!is_valid_package_name(pkgname)) { 135 path[0] = '\0'; 136 return -1; 137 } 138 139 std::string _tmp(create_data_user_ce_package_path(nullptr, userid, pkgname) + postfix); 140 const char* tmp = _tmp.c_str(); 141 if (strlen(tmp) >= PKG_PATH_MAX) { 142 path[0] = '\0'; 143 return -1; 144 } else { 145 strcpy(path, tmp); 146 return 0; 147 } 148 } 149 150 std::string create_data_path(const char* volume_uuid) { 151 if (volume_uuid == nullptr) { 152 return "/data"; 153 } else if (!strcmp(volume_uuid, "TEST")) { 154 CHECK(property_get_bool("ro.debuggable", false)); 155 return "/data/local/tmp"; 156 } else { 157 CHECK(is_valid_filename(volume_uuid)); 158 return StringPrintf("/mnt/expand/%s", volume_uuid); 159 } 160 } 161 162 /** 163 * Create the path name for app data. 164 */ 165 std::string create_data_app_path(const char* volume_uuid) { 166 return StringPrintf("%s/app", create_data_path(volume_uuid).c_str()); 167 } 168 169 /** 170 * Create the path name for user data for a certain userid. 171 */ 172 std::string create_data_user_ce_path(const char* volume_uuid, userid_t userid) { 173 std::string data(create_data_path(volume_uuid)); 174 if (volume_uuid == nullptr) { 175 if (userid == 0) { 176 return StringPrintf("%s/data", data.c_str()); 177 } else { 178 return StringPrintf("%s/user/%u", data.c_str(), userid); 179 } 180 } else { 181 return StringPrintf("%s/user/%u", data.c_str(), userid); 182 } 183 } 184 185 /** 186 * Create the path name for device encrypted user data for a certain userid. 187 */ 188 std::string create_data_user_de_path(const char* volume_uuid, userid_t userid) { 189 std::string data(create_data_path(volume_uuid)); 190 return StringPrintf("%s/user_de/%u", data.c_str(), userid); 191 } 192 193 /** 194 * Create the path name for media for a certain userid. 195 */ 196 std::string create_data_media_path(const char* volume_uuid, userid_t userid) { 197 return StringPrintf("%s/media/%u", create_data_path(volume_uuid).c_str(), userid); 198 } 199 200 std::string create_data_media_obb_path(const char* volume_uuid, const char* package_name) { 201 return StringPrintf("%s/media/obb/%s", create_data_path(volume_uuid).c_str(), package_name); 202 } 203 204 std::string create_data_media_package_path(const char* volume_uuid, userid_t userid, 205 const char* data_type, const char* package_name) { 206 return StringPrintf("%s/Android/%s/%s", create_data_media_path(volume_uuid, userid).c_str(), 207 data_type, package_name); 208 } 209 210 std::string create_data_misc_legacy_path(userid_t userid) { 211 return StringPrintf("%s/misc/user/%u", create_data_path(nullptr).c_str(), userid); 212 } 213 214 std::string create_primary_cur_profile_dir_path(userid_t userid) { 215 return StringPrintf("%s/cur/%u", android_profiles_dir.path, userid); 216 } 217 218 std::string create_primary_current_profile_package_dir_path(userid_t user, 219 const std::string& package_name) { 220 check_package_name(package_name.c_str()); 221 return StringPrintf("%s/%s", 222 create_primary_cur_profile_dir_path(user).c_str(), package_name.c_str()); 223 } 224 225 std::string create_primary_ref_profile_dir_path() { 226 return StringPrintf("%s/ref", android_profiles_dir.path); 227 } 228 229 std::string create_primary_reference_profile_package_dir_path(const std::string& package_name) { 230 check_package_name(package_name.c_str()); 231 return StringPrintf("%s/ref/%s", android_profiles_dir.path, package_name.c_str()); 232 } 233 234 std::string create_data_dalvik_cache_path() { 235 return "/data/dalvik-cache"; 236 } 237 238 // Keep profile paths in sync with ActivityThread and LoadedApk. 239 const std::string PROFILE_EXT = ".prof"; 240 const std::string PRIMARY_PROFILE_NAME = "primary" + PROFILE_EXT; 241 242 std::string create_current_profile_path(userid_t user, const std::string& location, 243 bool is_secondary_dex) { 244 if (is_secondary_dex) { 245 // Secondary dex profiles are stored next to the dex files using .prof extension. 246 return StringPrintf("%s%s", location.c_str(), PROFILE_EXT.c_str()); 247 } else { 248 // Profiles for primary apks are under /data/misc/profiles/cur. 249 std::string profile_dir = create_primary_current_profile_package_dir_path(user, location); 250 return StringPrintf("%s/%s", profile_dir.c_str(), PRIMARY_PROFILE_NAME.c_str()); 251 } 252 } 253 254 std::string create_reference_profile_path(const std::string& location, bool is_secondary_dex) { 255 if (is_secondary_dex) { 256 // Secondary dex reference profiles are stored next to the dex files under the oat folder. 257 size_t dirIndex = location.rfind('/'); 258 CHECK(dirIndex != std::string::npos) 259 << "Unexpected dir structure for secondary dex " << location; 260 261 std::string dex_dir = location.substr(0, dirIndex); 262 std::string dex_name = location.substr(dirIndex +1); 263 return StringPrintf("%s/oat/%s%s", 264 dex_dir.c_str(), dex_name.c_str(), PROFILE_EXT.c_str()); 265 } else { 266 // Reference profiles for primary apks are stored in /data/misc/profile/ref. 267 std::string profile_dir = create_primary_reference_profile_package_dir_path(location); 268 return StringPrintf("%s/%s", profile_dir.c_str(), PRIMARY_PROFILE_NAME.c_str()); 269 } 270 } 271 272 std::vector<userid_t> get_known_users(const char* volume_uuid) { 273 std::vector<userid_t> users; 274 275 // We always have an owner 276 users.push_back(0); 277 278 std::string path(create_data_path(volume_uuid) + "/" + SECONDARY_USER_PREFIX); 279 DIR* dir = opendir(path.c_str()); 280 if (dir == NULL) { 281 // Unable to discover other users, but at least return owner 282 PLOG(ERROR) << "Failed to opendir " << path; 283 return users; 284 } 285 286 struct dirent* ent; 287 while ((ent = readdir(dir))) { 288 if (ent->d_type != DT_DIR) { 289 continue; 290 } 291 292 char* end; 293 userid_t user = strtol(ent->d_name, &end, 10); 294 if (*end == '\0' && user != 0) { 295 LOG(DEBUG) << "Found valid user " << user; 296 users.push_back(user); 297 } 298 } 299 closedir(dir); 300 301 return users; 302 } 303 304 int calculate_tree_size(const std::string& path, int64_t* size, 305 int32_t include_gid, int32_t exclude_gid, bool exclude_apps) { 306 FTS *fts; 307 FTSENT *p; 308 int64_t matchedSize = 0; 309 char *argv[] = { (char*) path.c_str(), nullptr }; 310 if (!(fts = fts_open(argv, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, NULL))) { 311 if (errno != ENOENT) { 312 PLOG(ERROR) << "Failed to fts_open " << path; 313 } 314 return -1; 315 } 316 while ((p = fts_read(fts)) != NULL) { 317 switch (p->fts_info) { 318 case FTS_D: 319 case FTS_DEFAULT: 320 case FTS_F: 321 case FTS_SL: 322 case FTS_SLNONE: 323 int32_t uid = p->fts_statp->st_uid; 324 int32_t gid = p->fts_statp->st_gid; 325 int32_t user_uid = multiuser_get_app_id(uid); 326 int32_t user_gid = multiuser_get_app_id(gid); 327 if (exclude_apps && ((user_uid >= AID_APP_START && user_uid <= AID_APP_END) 328 || (user_gid >= AID_CACHE_GID_START && user_gid <= AID_CACHE_GID_END) 329 || (user_gid >= AID_SHARED_GID_START && user_gid <= AID_SHARED_GID_END))) { 330 // Don't traverse inside or measure 331 fts_set(fts, p, FTS_SKIP); 332 break; 333 } 334 if (include_gid != -1 && gid != include_gid) { 335 break; 336 } 337 if (exclude_gid != -1 && gid == exclude_gid) { 338 break; 339 } 340 matchedSize += (p->fts_statp->st_blocks * 512); 341 break; 342 } 343 } 344 fts_close(fts); 345 #if MEASURE_DEBUG 346 if ((include_gid == -1) && (exclude_gid == -1)) { 347 LOG(DEBUG) << "Measured " << path << " size " << matchedSize; 348 } else { 349 LOG(DEBUG) << "Measured " << path << " size " << matchedSize << "; include " << include_gid 350 << " exclude " << exclude_gid; 351 } 352 #endif 353 *size += matchedSize; 354 return 0; 355 } 356 357 int create_move_path(char path[PKG_PATH_MAX], 358 const char* pkgname, 359 const char* leaf, 360 userid_t userid ATTRIBUTE_UNUSED) 361 { 362 if ((android_data_dir.len + strlen(PRIMARY_USER_PREFIX) + strlen(pkgname) + strlen(leaf) + 1) 363 >= PKG_PATH_MAX) { 364 return -1; 365 } 366 367 sprintf(path, "%s%s%s/%s", android_data_dir.path, PRIMARY_USER_PREFIX, pkgname, leaf); 368 return 0; 369 } 370 371 /** 372 * Checks whether the package name is valid. Returns -1 on error and 373 * 0 on success. 374 */ 375 bool is_valid_package_name(const std::string& packageName) { 376 // This logic is borrowed from PackageParser.java 377 bool hasSep = false; 378 bool front = true; 379 380 auto it = packageName.begin(); 381 for (; it != packageName.end() && *it != '-'; it++) { 382 char c = *it; 383 if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { 384 front = false; 385 continue; 386 } 387 if (!front) { 388 if ((c >= '0' && c <= '9') || c == '_') { 389 continue; 390 } 391 } 392 if (c == '.') { 393 hasSep = true; 394 front = true; 395 continue; 396 } 397 LOG(WARNING) << "Bad package character " << c << " in " << packageName; 398 return false; 399 } 400 401 if (front) { 402 LOG(WARNING) << "Missing separator in " << packageName; 403 return false; 404 } 405 406 for (; it != packageName.end(); it++) { 407 char c = *it; 408 if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) continue; 409 if ((c >= '0' && c <= '9') || c == '_' || c == '-' || c == '=') continue; 410 LOG(WARNING) << "Bad suffix character " << c << " in " << packageName; 411 return false; 412 } 413 414 return true; 415 } 416 417 static int _delete_dir_contents(DIR *d, 418 int (*exclusion_predicate)(const char *name, const int is_dir)) 419 { 420 int result = 0; 421 struct dirent *de; 422 int dfd; 423 424 dfd = dirfd(d); 425 426 if (dfd < 0) return -1; 427 428 while ((de = readdir(d))) { 429 const char *name = de->d_name; 430 431 /* check using the exclusion predicate, if provided */ 432 if (exclusion_predicate && exclusion_predicate(name, (de->d_type == DT_DIR))) { 433 continue; 434 } 435 436 if (de->d_type == DT_DIR) { 437 int subfd; 438 DIR *subdir; 439 440 /* always skip "." and ".." */ 441 if (name[0] == '.') { 442 if (name[1] == 0) continue; 443 if ((name[1] == '.') && (name[2] == 0)) continue; 444 } 445 446 subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); 447 if (subfd < 0) { 448 ALOGE("Couldn't openat %s: %s\n", name, strerror(errno)); 449 result = -1; 450 continue; 451 } 452 subdir = fdopendir(subfd); 453 if (subdir == NULL) { 454 ALOGE("Couldn't fdopendir %s: %s\n", name, strerror(errno)); 455 close(subfd); 456 result = -1; 457 continue; 458 } 459 if (_delete_dir_contents(subdir, exclusion_predicate)) { 460 result = -1; 461 } 462 closedir(subdir); 463 if (unlinkat(dfd, name, AT_REMOVEDIR) < 0) { 464 ALOGE("Couldn't unlinkat %s: %s\n", name, strerror(errno)); 465 result = -1; 466 } 467 } else { 468 if (unlinkat(dfd, name, 0) < 0) { 469 ALOGE("Couldn't unlinkat %s: %s\n", name, strerror(errno)); 470 result = -1; 471 } 472 } 473 } 474 475 return result; 476 } 477 478 int delete_dir_contents(const std::string& pathname, bool ignore_if_missing) { 479 return delete_dir_contents(pathname.c_str(), 0, NULL, ignore_if_missing); 480 } 481 482 int delete_dir_contents_and_dir(const std::string& pathname, bool ignore_if_missing) { 483 return delete_dir_contents(pathname.c_str(), 1, NULL, ignore_if_missing); 484 } 485 486 int delete_dir_contents(const char *pathname, 487 int also_delete_dir, 488 int (*exclusion_predicate)(const char*, const int), 489 bool ignore_if_missing) 490 { 491 int res = 0; 492 DIR *d; 493 494 d = opendir(pathname); 495 if (d == NULL) { 496 if (ignore_if_missing && (errno == ENOENT)) { 497 return 0; 498 } 499 ALOGE("Couldn't opendir %s: %s\n", pathname, strerror(errno)); 500 return -errno; 501 } 502 res = _delete_dir_contents(d, exclusion_predicate); 503 closedir(d); 504 if (also_delete_dir) { 505 if (rmdir(pathname)) { 506 ALOGE("Couldn't rmdir %s: %s\n", pathname, strerror(errno)); 507 res = -1; 508 } 509 } 510 return res; 511 } 512 513 int delete_dir_contents_fd(int dfd, const char *name) 514 { 515 int fd, res; 516 DIR *d; 517 518 fd = openat(dfd, name, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); 519 if (fd < 0) { 520 ALOGE("Couldn't openat %s: %s\n", name, strerror(errno)); 521 return -1; 522 } 523 d = fdopendir(fd); 524 if (d == NULL) { 525 ALOGE("Couldn't fdopendir %s: %s\n", name, strerror(errno)); 526 close(fd); 527 return -1; 528 } 529 res = _delete_dir_contents(d, 0); 530 closedir(d); 531 return res; 532 } 533 534 static int _copy_owner_permissions(int srcfd, int dstfd) 535 { 536 struct stat st; 537 if (fstat(srcfd, &st) != 0) { 538 return -1; 539 } 540 if (fchmod(dstfd, st.st_mode) != 0) { 541 return -1; 542 } 543 return 0; 544 } 545 546 static int _copy_dir_files(int sdfd, int ddfd, uid_t owner, gid_t group) 547 { 548 int result = 0; 549 if (_copy_owner_permissions(sdfd, ddfd) != 0) { 550 ALOGE("_copy_dir_files failed to copy dir permissions\n"); 551 } 552 if (fchown(ddfd, owner, group) != 0) { 553 ALOGE("_copy_dir_files failed to change dir owner\n"); 554 } 555 556 DIR *ds = fdopendir(sdfd); 557 if (ds == NULL) { 558 ALOGE("Couldn't fdopendir: %s\n", strerror(errno)); 559 return -1; 560 } 561 struct dirent *de; 562 while ((de = readdir(ds))) { 563 if (de->d_type != DT_REG) { 564 continue; 565 } 566 567 const char *name = de->d_name; 568 int fsfd = openat(sdfd, name, O_RDONLY | O_NOFOLLOW | O_CLOEXEC); 569 int fdfd = openat(ddfd, name, O_WRONLY | O_NOFOLLOW | O_CLOEXEC | O_CREAT, 0600); 570 if (fsfd == -1 || fdfd == -1) { 571 ALOGW("Couldn't copy %s: %s\n", name, strerror(errno)); 572 } else { 573 if (_copy_owner_permissions(fsfd, fdfd) != 0) { 574 ALOGE("Failed to change file permissions\n"); 575 } 576 if (fchown(fdfd, owner, group) != 0) { 577 ALOGE("Failed to change file owner\n"); 578 } 579 580 char buf[8192]; 581 ssize_t size; 582 while ((size = read(fsfd, buf, sizeof(buf))) > 0) { 583 write(fdfd, buf, size); 584 } 585 if (size < 0) { 586 ALOGW("Couldn't copy %s: %s\n", name, strerror(errno)); 587 result = -1; 588 } 589 } 590 close(fdfd); 591 close(fsfd); 592 } 593 594 return result; 595 } 596 597 int copy_dir_files(const char *srcname, 598 const char *dstname, 599 uid_t owner, 600 uid_t group) 601 { 602 int res = 0; 603 DIR *ds = NULL; 604 DIR *dd = NULL; 605 606 ds = opendir(srcname); 607 if (ds == NULL) { 608 ALOGE("Couldn't opendir %s: %s\n", srcname, strerror(errno)); 609 return -errno; 610 } 611 612 mkdir(dstname, 0600); 613 dd = opendir(dstname); 614 if (dd == NULL) { 615 ALOGE("Couldn't opendir %s: %s\n", dstname, strerror(errno)); 616 closedir(ds); 617 return -errno; 618 } 619 620 int sdfd = dirfd(ds); 621 int ddfd = dirfd(dd); 622 if (sdfd != -1 && ddfd != -1) { 623 res = _copy_dir_files(sdfd, ddfd, owner, group); 624 } else { 625 res = -errno; 626 } 627 closedir(dd); 628 closedir(ds); 629 return res; 630 } 631 632 int64_t data_disk_free(const std::string& data_path) { 633 struct statvfs sfs; 634 if (statvfs(data_path.c_str(), &sfs) == 0) { 635 return sfs.f_bavail * sfs.f_frsize; 636 } else { 637 PLOG(ERROR) << "Couldn't statvfs " << data_path; 638 return -1; 639 } 640 } 641 642 int get_path_inode(const std::string& path, ino_t *inode) { 643 struct stat buf; 644 memset(&buf, 0, sizeof(buf)); 645 if (stat(path.c_str(), &buf) != 0) { 646 PLOG(WARNING) << "Failed to stat " << path; 647 return -1; 648 } else { 649 *inode = buf.st_ino; 650 return 0; 651 } 652 } 653 654 /** 655 * Write the inode of a specific child file into the given xattr on the 656 * parent directory. This allows you to find the child later, even if its 657 * name is encrypted. 658 */ 659 int write_path_inode(const std::string& parent, const char* name, const char* inode_xattr) { 660 ino_t inode = 0; 661 uint64_t inode_raw = 0; 662 auto path = StringPrintf("%s/%s", parent.c_str(), name); 663 664 if (get_path_inode(path, &inode) != 0) { 665 // Path probably doesn't exist yet; ignore 666 return 0; 667 } 668 669 // Check to see if already set correctly 670 if (getxattr(parent.c_str(), inode_xattr, &inode_raw, sizeof(inode_raw)) == sizeof(inode_raw)) { 671 if (inode_raw == inode) { 672 // Already set correctly; skip writing 673 return 0; 674 } else { 675 PLOG(WARNING) << "Mismatched inode value; found " << inode 676 << " on disk but marked value was " << inode_raw << "; overwriting"; 677 } 678 } 679 680 inode_raw = inode; 681 if (setxattr(parent.c_str(), inode_xattr, &inode_raw, sizeof(inode_raw), 0) != 0 && errno != EOPNOTSUPP) { 682 PLOG(ERROR) << "Failed to write xattr " << inode_xattr << " at " << parent; 683 return -1; 684 } else { 685 return 0; 686 } 687 } 688 689 /** 690 * Read the inode of a specific child file from the given xattr on the 691 * parent directory. Returns a currently valid path for that child, which 692 * might have an encrypted name. 693 */ 694 std::string read_path_inode(const std::string& parent, const char* name, const char* inode_xattr) { 695 ino_t inode = 0; 696 uint64_t inode_raw = 0; 697 auto fallback = StringPrintf("%s/%s", parent.c_str(), name); 698 699 // Lookup the inode value written earlier 700 if (getxattr(parent.c_str(), inode_xattr, &inode_raw, sizeof(inode_raw)) == sizeof(inode_raw)) { 701 inode = inode_raw; 702 } 703 704 // For testing purposes, rely on the inode when defined; this could be 705 // optimized to use access() in the future. 706 if (inode != 0) { 707 DIR* dir = opendir(parent.c_str()); 708 if (dir == nullptr) { 709 PLOG(ERROR) << "Failed to opendir " << parent; 710 return fallback; 711 } 712 713 struct dirent* ent; 714 while ((ent = readdir(dir))) { 715 if (ent->d_ino == inode) { 716 auto resolved = StringPrintf("%s/%s", parent.c_str(), ent->d_name); 717 #if DEBUG_XATTRS 718 if (resolved != fallback) { 719 LOG(DEBUG) << "Resolved path " << resolved << " for inode " << inode 720 << " instead of " << fallback; 721 } 722 #endif 723 closedir(dir); 724 return resolved; 725 } 726 } 727 LOG(WARNING) << "Failed to resolve inode " << inode << "; using " << fallback; 728 closedir(dir); 729 return fallback; 730 } else { 731 return fallback; 732 } 733 } 734 735 /** 736 * Validate that the path is valid in the context of the provided directory. 737 * The path is allowed to have at most one subdirectory and no indirections 738 * to top level directories (i.e. have ".."). 739 */ 740 static int validate_path(const dir_rec_t* dir, const char* path, int maxSubdirs) { 741 size_t dir_len = dir->len; 742 const char* subdir = strchr(path + dir_len, '/'); 743 744 // Only allow the path to have at most one subdirectory. 745 if (subdir != NULL) { 746 ++subdir; 747 if ((--maxSubdirs == 0) && strchr(subdir, '/') != NULL) { 748 ALOGE("invalid apk path '%s' (subdir?)\n", path); 749 return -1; 750 } 751 } 752 753 // Directories can't have a period directly after the directory markers to prevent "..". 754 if ((path[dir_len] == '.') || ((subdir != NULL) && (*subdir == '.'))) { 755 ALOGE("invalid apk path '%s' (trickery)\n", path); 756 return -1; 757 } 758 759 return 0; 760 } 761 762 /** 763 * Checks whether a path points to a system app (.apk file). Returns 0 764 * if it is a system app or -1 if it is not. 765 */ 766 int validate_system_app_path(const char* path) { 767 size_t i; 768 769 for (i = 0; i < android_system_dirs.count; i++) { 770 const size_t dir_len = android_system_dirs.dirs[i].len; 771 if (!strncmp(path, android_system_dirs.dirs[i].path, dir_len)) { 772 return validate_path(android_system_dirs.dirs + i, path, 1); 773 } 774 } 775 776 return -1; 777 } 778 779 bool validate_secondary_dex_path(const std::string& pkgname, const std::string& dex_path, 780 const char* volume_uuid, int uid, int storage_flag) { 781 CHECK(storage_flag == FLAG_STORAGE_CE || storage_flag == FLAG_STORAGE_DE); 782 783 std::string app_private_dir = storage_flag == FLAG_STORAGE_CE 784 ? create_data_user_ce_package_path( 785 volume_uuid, multiuser_get_user_id(uid), pkgname.c_str()) 786 : create_data_user_de_package_path( 787 volume_uuid, multiuser_get_user_id(uid), pkgname.c_str()); 788 dir_rec_t dir; 789 if (get_path_from_string(&dir, app_private_dir.c_str()) != 0) { 790 LOG(WARNING) << "Could not get dir rec for " << app_private_dir; 791 return false; 792 } 793 // Usually secondary dex files have a nested directory structure. 794 // Pick at most 10 subdirectories when validating (arbitrary value). 795 // If the secondary dex file is >10 directory nested then validation will 796 // fail and the file will not be compiled. 797 return validate_path(&dir, dex_path.c_str(), /*max_subdirs*/ 10) == 0; 798 } 799 800 /** 801 * Get the contents of a environment variable that contains a path. Caller 802 * owns the string that is inserted into the directory record. Returns 803 * 0 on success and -1 on error. 804 */ 805 int get_path_from_env(dir_rec_t* rec, const char* var) { 806 const char* path = getenv(var); 807 int ret = get_path_from_string(rec, path); 808 if (ret < 0) { 809 ALOGW("Problem finding value for environment variable %s\n", var); 810 } 811 return ret; 812 } 813 814 /** 815 * Puts the string into the record as a directory. Appends '/' to the end 816 * of all paths. Caller owns the string that is inserted into the directory 817 * record. A null value will result in an error. 818 * 819 * Returns 0 on success and -1 on error. 820 */ 821 int get_path_from_string(dir_rec_t* rec, const char* path) { 822 if (path == NULL) { 823 return -1; 824 } else { 825 const size_t path_len = strlen(path); 826 if (path_len <= 0) { 827 return -1; 828 } 829 830 // Make sure path is absolute. 831 if (path[0] != '/') { 832 return -1; 833 } 834 835 if (path[path_len - 1] == '/') { 836 // Path ends with a forward slash. Make our own copy. 837 838 rec->path = strdup(path); 839 if (rec->path == NULL) { 840 return -1; 841 } 842 843 rec->len = path_len; 844 } else { 845 // Path does not end with a slash. Generate a new string. 846 char *dst; 847 848 // Add space for slash and terminating null. 849 size_t dst_size = path_len + 2; 850 851 rec->path = (char*) malloc(dst_size); 852 if (rec->path == NULL) { 853 return -1; 854 } 855 856 dst = rec->path; 857 858 if (append_and_increment(&dst, path, &dst_size) < 0 859 || append_and_increment(&dst, "/", &dst_size)) { 860 ALOGE("Error canonicalizing path"); 861 return -1; 862 } 863 864 rec->len = dst - rec->path; 865 } 866 } 867 return 0; 868 } 869 870 int copy_and_append(dir_rec_t* dst, const dir_rec_t* src, const char* suffix) { 871 dst->len = src->len + strlen(suffix); 872 const size_t dstSize = dst->len + 1; 873 dst->path = (char*) malloc(dstSize); 874 875 if (dst->path == NULL 876 || snprintf(dst->path, dstSize, "%s%s", src->path, suffix) 877 != (ssize_t) dst->len) { 878 ALOGE("Could not allocate memory to hold appended path; aborting\n"); 879 return -1; 880 } 881 882 return 0; 883 } 884 885 /** 886 * Check whether path points to a valid path for an APK file. The path must 887 * begin with a whitelisted prefix path and must be no deeper than |maxSubdirs| within 888 * that path. Returns -1 when an invalid path is encountered and 0 when a valid path 889 * is encountered. 890 */ 891 static int validate_apk_path_internal(const char *path, int maxSubdirs) { 892 const dir_rec_t* dir = NULL; 893 if (!strncmp(path, android_app_dir.path, android_app_dir.len)) { 894 dir = &android_app_dir; 895 } else if (!strncmp(path, android_app_private_dir.path, android_app_private_dir.len)) { 896 dir = &android_app_private_dir; 897 } else if (!strncmp(path, android_app_ephemeral_dir.path, android_app_ephemeral_dir.len)) { 898 dir = &android_app_ephemeral_dir; 899 } else if (!strncmp(path, android_asec_dir.path, android_asec_dir.len)) { 900 dir = &android_asec_dir; 901 } else if (!strncmp(path, android_mnt_expand_dir.path, android_mnt_expand_dir.len)) { 902 dir = &android_mnt_expand_dir; 903 if (maxSubdirs < 2) { 904 maxSubdirs = 2; 905 } 906 } else { 907 return -1; 908 } 909 910 return validate_path(dir, path, maxSubdirs); 911 } 912 913 int validate_apk_path(const char* path) { 914 return validate_apk_path_internal(path, 1 /* maxSubdirs */); 915 } 916 917 int validate_apk_path_subdirs(const char* path) { 918 return validate_apk_path_internal(path, 3 /* maxSubdirs */); 919 } 920 921 int append_and_increment(char** dst, const char* src, size_t* dst_size) { 922 ssize_t ret = strlcpy(*dst, src, *dst_size); 923 if (ret < 0 || (size_t) ret >= *dst_size) { 924 return -1; 925 } 926 *dst += ret; 927 *dst_size -= ret; 928 return 0; 929 } 930 931 char *build_string2(const char *s1, const char *s2) { 932 if (s1 == NULL || s2 == NULL) return NULL; 933 934 int len_s1 = strlen(s1); 935 int len_s2 = strlen(s2); 936 int len = len_s1 + len_s2 + 1; 937 char *result = (char *) malloc(len); 938 if (result == NULL) return NULL; 939 940 strcpy(result, s1); 941 strcpy(result + len_s1, s2); 942 943 return result; 944 } 945 946 char *build_string3(const char *s1, const char *s2, const char *s3) { 947 if (s1 == NULL || s2 == NULL || s3 == NULL) return NULL; 948 949 int len_s1 = strlen(s1); 950 int len_s2 = strlen(s2); 951 int len_s3 = strlen(s3); 952 int len = len_s1 + len_s2 + len_s3 + 1; 953 char *result = (char *) malloc(len); 954 if (result == NULL) return NULL; 955 956 strcpy(result, s1); 957 strcpy(result + len_s1, s2); 958 strcpy(result + len_s1 + len_s2, s3); 959 960 return result; 961 } 962 963 int ensure_config_user_dirs(userid_t userid) { 964 // writable by system, readable by any app within the same user 965 const int uid = multiuser_get_uid(userid, AID_SYSTEM); 966 const int gid = multiuser_get_uid(userid, AID_EVERYBODY); 967 968 // Ensure /data/misc/user/<userid> exists 969 auto path = create_data_misc_legacy_path(userid); 970 return fs_prepare_dir(path.c_str(), 0750, uid, gid); 971 } 972 973 int wait_child(pid_t pid) 974 { 975 int status; 976 pid_t got_pid; 977 978 while (1) { 979 got_pid = waitpid(pid, &status, 0); 980 if (got_pid == -1 && errno == EINTR) { 981 printf("waitpid interrupted, retrying\n"); 982 } else { 983 break; 984 } 985 } 986 if (got_pid != pid) { 987 ALOGW("waitpid failed: wanted %d, got %d: %s\n", 988 (int) pid, (int) got_pid, strerror(errno)); 989 return 1; 990 } 991 992 if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { 993 return 0; 994 } else { 995 return status; /* always nonzero */ 996 } 997 } 998 999 /** 1000 * Prepare an app cache directory, which offers to fix-up the GID and 1001 * directory mode flags during a platform upgrade. 1002 * The app cache directory path will be 'parent'/'name'. 1003 */ 1004 int prepare_app_cache_dir(const std::string& parent, const char* name, mode_t target_mode, 1005 uid_t uid, gid_t gid) { 1006 auto path = StringPrintf("%s/%s", parent.c_str(), name); 1007 struct stat st; 1008 if (stat(path.c_str(), &st) != 0) { 1009 if (errno == ENOENT) { 1010 // This is fine, just create it 1011 if (fs_prepare_dir_strict(path.c_str(), target_mode, uid, gid) != 0) { 1012 PLOG(ERROR) << "Failed to prepare " << path; 1013 return -1; 1014 } else { 1015 return 0; 1016 } 1017 } else { 1018 PLOG(ERROR) << "Failed to stat " << path; 1019 return -1; 1020 } 1021 } 1022 1023 mode_t actual_mode = st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO | S_ISGID); 1024 if (st.st_uid != uid) { 1025 // Mismatched UID is real trouble; we can't recover 1026 LOG(ERROR) << "Mismatched UID at " << path << ": found " << st.st_uid 1027 << " but expected " << uid; 1028 return -1; 1029 } else if (st.st_gid == gid && actual_mode == target_mode) { 1030 // Everything looks good! 1031 return 0; 1032 } else { 1033 // Mismatched GID/mode is recoverable; fall through to update 1034 LOG(DEBUG) << "Mismatched cache GID/mode at " << path << ": found " << st.st_gid 1035 << " but expected " << gid; 1036 } 1037 1038 // Directory is owned correctly, but GID or mode mismatch means it's 1039 // probably a platform upgrade so we need to fix them 1040 FTS *fts; 1041 FTSENT *p; 1042 char *argv[] = { (char*) path.c_str(), nullptr }; 1043 if (!(fts = fts_open(argv, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, NULL))) { 1044 PLOG(ERROR) << "Failed to fts_open " << path; 1045 return -1; 1046 } 1047 while ((p = fts_read(fts)) != NULL) { 1048 switch (p->fts_info) { 1049 case FTS_DP: 1050 if (chmod(p->fts_path, target_mode) != 0) { 1051 PLOG(WARNING) << "Failed to chmod " << p->fts_path; 1052 } 1053 // Intentional fall through to also set GID 1054 case FTS_F: 1055 if (chown(p->fts_path, -1, gid) != 0) { 1056 PLOG(WARNING) << "Failed to chown " << p->fts_path; 1057 } 1058 break; 1059 case FTS_SL: 1060 case FTS_SLNONE: 1061 if (lchown(p->fts_path, -1, gid) != 0) { 1062 PLOG(WARNING) << "Failed to chown " << p->fts_path; 1063 } 1064 break; 1065 } 1066 } 1067 fts_close(fts); 1068 return 0; 1069 } 1070 1071 } // namespace installd 1072 } // namespace android 1073