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 <stdlib.h> 22#include <sys/stat.h> 23#include <sys/wait.h> 24 25#if defined(__APPLE__) 26#include <sys/mount.h> 27#else 28#include <sys/statfs.h> 29#endif 30 31#include <android-base/logging.h> 32#include <android-base/stringprintf.h> 33#include <cutils/fs.h> 34#include <cutils/log.h> 35#include <private/android_filesystem_config.h> 36 37#include "globals.h" // extern variables. 38 39#ifndef LOG_TAG 40#define LOG_TAG "installd" 41#endif 42#define CACHE_NOISY(x) //x 43 44using android::base::StringPrintf; 45 46namespace android { 47namespace installd { 48 49/** 50 * Check that given string is valid filename, and that it attempts no 51 * parent or child directory traversal. 52 */ 53static bool is_valid_filename(const std::string& name) { 54 if (name.empty() || (name == ".") || (name == "..") 55 || (name.find('/') != std::string::npos)) { 56 return false; 57 } else { 58 return true; 59 } 60} 61 62static void check_package_name(const char* package_name) { 63 CHECK(is_valid_filename(package_name)); 64 CHECK(is_valid_package_name(package_name) == 0); 65} 66 67/** 68 * Create the path name where package app contents should be stored for 69 * the given volume UUID and package name. An empty UUID is assumed to 70 * be internal storage. 71 */ 72std::string create_data_app_package_path(const char* volume_uuid, 73 const char* package_name) { 74 check_package_name(package_name); 75 return StringPrintf("%s/%s", 76 create_data_app_path(volume_uuid).c_str(), package_name); 77} 78 79/** 80 * Create the path name where package data should be stored for the given 81 * volume UUID, package name, and user ID. An empty UUID is assumed to be 82 * internal storage. 83 */ 84std::string create_data_user_ce_package_path(const char* volume_uuid, 85 userid_t user, const char* package_name) { 86 check_package_name(package_name); 87 return StringPrintf("%s/%s", 88 create_data_user_ce_path(volume_uuid, user).c_str(), package_name); 89} 90 91std::string create_data_user_ce_package_path(const char* volume_uuid, userid_t user, 92 const char* package_name, ino_t ce_data_inode) { 93 // For testing purposes, rely on the inode when defined; this could be 94 // optimized to use access() in the future. 95 auto fallback = create_data_user_ce_package_path(volume_uuid, user, package_name); 96 if (ce_data_inode != 0) { 97 auto user_path = create_data_user_ce_path(volume_uuid, user); 98 DIR* dir = opendir(user_path.c_str()); 99 if (dir == nullptr) { 100 PLOG(ERROR) << "Failed to opendir " << user_path; 101 return fallback; 102 } 103 104 struct dirent* ent; 105 while ((ent = readdir(dir))) { 106 if (ent->d_ino == ce_data_inode) { 107 auto resolved = StringPrintf("%s/%s", user_path.c_str(), ent->d_name); 108 if (resolved != fallback) { 109 LOG(DEBUG) << "Resolved path " << resolved << " for inode " << ce_data_inode 110 << " instead of " << fallback; 111 } 112 closedir(dir); 113 return resolved; 114 } 115 } 116 LOG(WARNING) << "Failed to resolve inode " << ce_data_inode << "; using " << fallback; 117 closedir(dir); 118 return fallback; 119 } else { 120 return fallback; 121 } 122} 123 124std::string create_data_user_de_package_path(const char* volume_uuid, 125 userid_t user, const char* package_name) { 126 check_package_name(package_name); 127 return StringPrintf("%s/%s", 128 create_data_user_de_path(volume_uuid, user).c_str(), package_name); 129} 130 131int create_pkg_path(char path[PKG_PATH_MAX], const char *pkgname, 132 const char *postfix, userid_t userid) { 133 if (is_valid_package_name(pkgname) != 0) { 134 path[0] = '\0'; 135 return -1; 136 } 137 138 std::string _tmp(create_data_user_ce_package_path(nullptr, userid, pkgname) + postfix); 139 const char* tmp = _tmp.c_str(); 140 if (strlen(tmp) >= PKG_PATH_MAX) { 141 path[0] = '\0'; 142 return -1; 143 } else { 144 strcpy(path, tmp); 145 return 0; 146 } 147} 148 149std::string create_data_path(const char* volume_uuid) { 150 if (volume_uuid == nullptr) { 151 return "/data"; 152 } else { 153 CHECK(is_valid_filename(volume_uuid)); 154 return StringPrintf("/mnt/expand/%s", volume_uuid); 155 } 156} 157 158/** 159 * Create the path name for app data. 160 */ 161std::string create_data_app_path(const char* volume_uuid) { 162 return StringPrintf("%s/app", create_data_path(volume_uuid).c_str()); 163} 164 165/** 166 * Create the path name for user data for a certain userid. 167 */ 168std::string create_data_user_ce_path(const char* volume_uuid, userid_t userid) { 169 std::string data(create_data_path(volume_uuid)); 170 if (volume_uuid == nullptr) { 171 if (userid == 0) { 172 return StringPrintf("%s/data", data.c_str()); 173 } else { 174 return StringPrintf("%s/user/%u", data.c_str(), userid); 175 } 176 } else { 177 return StringPrintf("%s/user/%u", data.c_str(), userid); 178 } 179} 180 181/** 182 * Create the path name for device encrypted user data for a certain userid. 183 */ 184std::string create_data_user_de_path(const char* volume_uuid, userid_t userid) { 185 std::string data(create_data_path(volume_uuid)); 186 return StringPrintf("%s/user_de/%u", data.c_str(), userid); 187} 188 189/** 190 * Create the path name for media for a certain userid. 191 */ 192std::string create_data_media_path(const char* volume_uuid, userid_t userid) { 193 return StringPrintf("%s/media/%u", create_data_path(volume_uuid).c_str(), userid); 194} 195 196std::string create_data_misc_legacy_path(userid_t userid) { 197 return StringPrintf("%s/misc/user/%u", create_data_path(nullptr).c_str(), userid); 198} 199 200std::string create_data_user_profiles_path(userid_t userid) { 201 return StringPrintf("%s/cur/%u", android_profiles_dir.path, userid); 202} 203 204std::string create_data_user_profile_package_path(userid_t user, const char* package_name) { 205 check_package_name(package_name); 206 return StringPrintf("%s/%s",create_data_user_profiles_path(user).c_str(), package_name); 207} 208 209std::string create_data_ref_profile_package_path(const char* package_name) { 210 check_package_name(package_name); 211 return StringPrintf("%s/ref/%s", android_profiles_dir.path, package_name); 212} 213 214std::vector<userid_t> get_known_users(const char* volume_uuid) { 215 std::vector<userid_t> users; 216 217 // We always have an owner 218 users.push_back(0); 219 220 std::string path(create_data_path(volume_uuid) + "/" + SECONDARY_USER_PREFIX); 221 DIR* dir = opendir(path.c_str()); 222 if (dir == NULL) { 223 // Unable to discover other users, but at least return owner 224 PLOG(ERROR) << "Failed to opendir " << path; 225 return users; 226 } 227 228 struct dirent* ent; 229 while ((ent = readdir(dir))) { 230 if (ent->d_type != DT_DIR) { 231 continue; 232 } 233 234 char* end; 235 userid_t user = strtol(ent->d_name, &end, 10); 236 if (*end == '\0' && user != 0) { 237 LOG(DEBUG) << "Found valid user " << user; 238 users.push_back(user); 239 } 240 } 241 closedir(dir); 242 243 return users; 244} 245 246int create_move_path(char path[PKG_PATH_MAX], 247 const char* pkgname, 248 const char* leaf, 249 userid_t userid ATTRIBUTE_UNUSED) 250{ 251 if ((android_data_dir.len + strlen(PRIMARY_USER_PREFIX) + strlen(pkgname) + strlen(leaf) + 1) 252 >= PKG_PATH_MAX) { 253 return -1; 254 } 255 256 sprintf(path, "%s%s%s/%s", android_data_dir.path, PRIMARY_USER_PREFIX, pkgname, leaf); 257 return 0; 258} 259 260/** 261 * Checks whether the package name is valid. Returns -1 on error and 262 * 0 on success. 263 */ 264int is_valid_package_name(const char* pkgname) { 265 const char *x = pkgname; 266 int alpha = -1; 267 268 if (strlen(pkgname) > PKG_NAME_MAX) { 269 return -1; 270 } 271 272 while (*x) { 273 if (isalnum(*x) || (*x == '_')) { 274 /* alphanumeric or underscore are fine */ 275 } else if (*x == '.') { 276 if ((x == pkgname) || (x[1] == '.') || (x[1] == 0)) { 277 /* periods must not be first, last, or doubled */ 278 ALOGE("invalid package name '%s'\n", pkgname); 279 return -1; 280 } 281 } else if (*x == '-') { 282 /* Suffix -X is fine to let versioning of packages. 283 But whatever follows should be alphanumeric.*/ 284 alpha = 1; 285 } else { 286 /* anything not A-Z, a-z, 0-9, _, or . is invalid */ 287 ALOGE("invalid package name '%s'\n", pkgname); 288 return -1; 289 } 290 291 x++; 292 } 293 294 if (alpha == 1) { 295 // Skip current character 296 x++; 297 while (*x) { 298 if (!isalnum(*x)) { 299 ALOGE("invalid package name '%s' should include only numbers after -\n", pkgname); 300 return -1; 301 } 302 x++; 303 } 304 } 305 306 return 0; 307} 308 309static int _delete_dir_contents(DIR *d, 310 int (*exclusion_predicate)(const char *name, const int is_dir)) 311{ 312 int result = 0; 313 struct dirent *de; 314 int dfd; 315 316 dfd = dirfd(d); 317 318 if (dfd < 0) return -1; 319 320 while ((de = readdir(d))) { 321 const char *name = de->d_name; 322 323 /* check using the exclusion predicate, if provided */ 324 if (exclusion_predicate && exclusion_predicate(name, (de->d_type == DT_DIR))) { 325 continue; 326 } 327 328 if (de->d_type == DT_DIR) { 329 int subfd; 330 DIR *subdir; 331 332 /* always skip "." and ".." */ 333 if (name[0] == '.') { 334 if (name[1] == 0) continue; 335 if ((name[1] == '.') && (name[2] == 0)) continue; 336 } 337 338 subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); 339 if (subfd < 0) { 340 ALOGE("Couldn't openat %s: %s\n", name, strerror(errno)); 341 result = -1; 342 continue; 343 } 344 subdir = fdopendir(subfd); 345 if (subdir == NULL) { 346 ALOGE("Couldn't fdopendir %s: %s\n", name, strerror(errno)); 347 close(subfd); 348 result = -1; 349 continue; 350 } 351 if (_delete_dir_contents(subdir, exclusion_predicate)) { 352 result = -1; 353 } 354 closedir(subdir); 355 if (unlinkat(dfd, name, AT_REMOVEDIR) < 0) { 356 ALOGE("Couldn't unlinkat %s: %s\n", name, strerror(errno)); 357 result = -1; 358 } 359 } else { 360 if (unlinkat(dfd, name, 0) < 0) { 361 ALOGE("Couldn't unlinkat %s: %s\n", name, strerror(errno)); 362 result = -1; 363 } 364 } 365 } 366 367 return result; 368} 369 370int delete_dir_contents(const std::string& pathname, bool ignore_if_missing) { 371 return delete_dir_contents(pathname.c_str(), 0, NULL, ignore_if_missing); 372} 373 374int delete_dir_contents_and_dir(const std::string& pathname, bool ignore_if_missing) { 375 return delete_dir_contents(pathname.c_str(), 1, NULL, ignore_if_missing); 376} 377 378int delete_dir_contents(const char *pathname, 379 int also_delete_dir, 380 int (*exclusion_predicate)(const char*, const int), 381 bool ignore_if_missing) 382{ 383 int res = 0; 384 DIR *d; 385 386 d = opendir(pathname); 387 if (d == NULL) { 388 if (ignore_if_missing && (errno == ENOENT)) { 389 return 0; 390 } 391 ALOGE("Couldn't opendir %s: %s\n", pathname, strerror(errno)); 392 return -errno; 393 } 394 res = _delete_dir_contents(d, exclusion_predicate); 395 closedir(d); 396 if (also_delete_dir) { 397 if (rmdir(pathname)) { 398 ALOGE("Couldn't rmdir %s: %s\n", pathname, strerror(errno)); 399 res = -1; 400 } 401 } 402 return res; 403} 404 405int delete_dir_contents_fd(int dfd, const char *name) 406{ 407 int fd, res; 408 DIR *d; 409 410 fd = openat(dfd, name, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); 411 if (fd < 0) { 412 ALOGE("Couldn't openat %s: %s\n", name, strerror(errno)); 413 return -1; 414 } 415 d = fdopendir(fd); 416 if (d == NULL) { 417 ALOGE("Couldn't fdopendir %s: %s\n", name, strerror(errno)); 418 close(fd); 419 return -1; 420 } 421 res = _delete_dir_contents(d, 0); 422 closedir(d); 423 return res; 424} 425 426static int _copy_owner_permissions(int srcfd, int dstfd) 427{ 428 struct stat st; 429 if (fstat(srcfd, &st) != 0) { 430 return -1; 431 } 432 if (fchmod(dstfd, st.st_mode) != 0) { 433 return -1; 434 } 435 return 0; 436} 437 438static int _copy_dir_files(int sdfd, int ddfd, uid_t owner, gid_t group) 439{ 440 int result = 0; 441 if (_copy_owner_permissions(sdfd, ddfd) != 0) { 442 ALOGE("_copy_dir_files failed to copy dir permissions\n"); 443 } 444 if (fchown(ddfd, owner, group) != 0) { 445 ALOGE("_copy_dir_files failed to change dir owner\n"); 446 } 447 448 DIR *ds = fdopendir(sdfd); 449 if (ds == NULL) { 450 ALOGE("Couldn't fdopendir: %s\n", strerror(errno)); 451 return -1; 452 } 453 struct dirent *de; 454 while ((de = readdir(ds))) { 455 if (de->d_type != DT_REG) { 456 continue; 457 } 458 459 const char *name = de->d_name; 460 int fsfd = openat(sdfd, name, O_RDONLY | O_NOFOLLOW | O_CLOEXEC); 461 int fdfd = openat(ddfd, name, O_WRONLY | O_NOFOLLOW | O_CLOEXEC | O_CREAT, 0600); 462 if (fsfd == -1 || fdfd == -1) { 463 ALOGW("Couldn't copy %s: %s\n", name, strerror(errno)); 464 } else { 465 if (_copy_owner_permissions(fsfd, fdfd) != 0) { 466 ALOGE("Failed to change file permissions\n"); 467 } 468 if (fchown(fdfd, owner, group) != 0) { 469 ALOGE("Failed to change file owner\n"); 470 } 471 472 char buf[8192]; 473 ssize_t size; 474 while ((size = read(fsfd, buf, sizeof(buf))) > 0) { 475 write(fdfd, buf, size); 476 } 477 if (size < 0) { 478 ALOGW("Couldn't copy %s: %s\n", name, strerror(errno)); 479 result = -1; 480 } 481 } 482 close(fdfd); 483 close(fsfd); 484 } 485 486 return result; 487} 488 489int copy_dir_files(const char *srcname, 490 const char *dstname, 491 uid_t owner, 492 uid_t group) 493{ 494 int res = 0; 495 DIR *ds = NULL; 496 DIR *dd = NULL; 497 498 ds = opendir(srcname); 499 if (ds == NULL) { 500 ALOGE("Couldn't opendir %s: %s\n", srcname, strerror(errno)); 501 return -errno; 502 } 503 504 mkdir(dstname, 0600); 505 dd = opendir(dstname); 506 if (dd == NULL) { 507 ALOGE("Couldn't opendir %s: %s\n", dstname, strerror(errno)); 508 closedir(ds); 509 return -errno; 510 } 511 512 int sdfd = dirfd(ds); 513 int ddfd = dirfd(dd); 514 if (sdfd != -1 && ddfd != -1) { 515 res = _copy_dir_files(sdfd, ddfd, owner, group); 516 } else { 517 res = -errno; 518 } 519 closedir(dd); 520 closedir(ds); 521 return res; 522} 523 524int64_t data_disk_free(const std::string& data_path) 525{ 526 struct statfs sfs; 527 if (statfs(data_path.c_str(), &sfs) == 0) { 528 return sfs.f_bavail * sfs.f_bsize; 529 } else { 530 PLOG(ERROR) << "Couldn't statfs " << data_path; 531 return -1; 532 } 533} 534 535cache_t* start_cache_collection() 536{ 537 cache_t* cache = (cache_t*)calloc(1, sizeof(cache_t)); 538 return cache; 539} 540 541#define CACHE_BLOCK_SIZE (512*1024) 542 543static void* _cache_malloc(cache_t* cache, size_t len) 544{ 545 len = (len+3)&~3; 546 if (len > (CACHE_BLOCK_SIZE/2)) { 547 // It doesn't make sense to try to put this allocation into one 548 // of our blocks, because it is so big. Instead, make a new dedicated 549 // block for it. 550 int8_t* res = (int8_t*)malloc(len+sizeof(void*)); 551 if (res == NULL) { 552 return NULL; 553 } 554 CACHE_NOISY(ALOGI("Allocated large cache mem block: %p size %d", res, len)); 555 // Link it into our list of blocks, not disrupting the current one. 556 if (cache->memBlocks == NULL) { 557 *(void**)res = NULL; 558 cache->memBlocks = res; 559 } else { 560 *(void**)res = *(void**)cache->memBlocks; 561 *(void**)cache->memBlocks = res; 562 } 563 return res + sizeof(void*); 564 } 565 int8_t* res = cache->curMemBlockAvail; 566 int8_t* nextPos = res + len; 567 if (cache->memBlocks == NULL || nextPos > cache->curMemBlockEnd) { 568 int8_t* newBlock = (int8_t*) malloc(CACHE_BLOCK_SIZE); 569 if (newBlock == NULL) { 570 return NULL; 571 } 572 CACHE_NOISY(ALOGI("Allocated new cache mem block: %p", newBlock)); 573 *(void**)newBlock = cache->memBlocks; 574 cache->memBlocks = newBlock; 575 res = cache->curMemBlockAvail = newBlock + sizeof(void*); 576 cache->curMemBlockEnd = newBlock + CACHE_BLOCK_SIZE; 577 nextPos = res + len; 578 } 579 CACHE_NOISY(ALOGI("cache_malloc: ret %p size %d, block=%p, nextPos=%p", 580 res, len, cache->memBlocks, nextPos)); 581 cache->curMemBlockAvail = nextPos; 582 return res; 583} 584 585static void* _cache_realloc(cache_t* cache, void* cur, size_t origLen, size_t len) 586{ 587 // This isn't really a realloc, but it is good enough for our purposes here. 588 void* alloc = _cache_malloc(cache, len); 589 if (alloc != NULL && cur != NULL) { 590 memcpy(alloc, cur, origLen < len ? origLen : len); 591 } 592 return alloc; 593} 594 595static void _inc_num_cache_collected(cache_t* cache) 596{ 597 cache->numCollected++; 598 if ((cache->numCollected%20000) == 0) { 599 ALOGI("Collected cache so far: %zd directories, %zd files", 600 cache->numDirs, cache->numFiles); 601 } 602} 603 604static cache_dir_t* _add_cache_dir_t(cache_t* cache, cache_dir_t* parent, const char *name) 605{ 606 size_t nameLen = strlen(name); 607 cache_dir_t* dir = (cache_dir_t*)_cache_malloc(cache, sizeof(cache_dir_t)+nameLen+1); 608 if (dir != NULL) { 609 dir->parent = parent; 610 dir->childCount = 0; 611 dir->hiddenCount = 0; 612 dir->deleted = 0; 613 strcpy(dir->name, name); 614 if (cache->numDirs >= cache->availDirs) { 615 size_t newAvail = cache->availDirs < 1000 ? 1000 : cache->availDirs*2; 616 cache_dir_t** newDirs = (cache_dir_t**)_cache_realloc(cache, cache->dirs, 617 cache->availDirs*sizeof(cache_dir_t*), newAvail*sizeof(cache_dir_t*)); 618 if (newDirs == NULL) { 619 ALOGE("Failure growing cache dirs array for %s\n", name); 620 return NULL; 621 } 622 cache->availDirs = newAvail; 623 cache->dirs = newDirs; 624 } 625 cache->dirs[cache->numDirs] = dir; 626 cache->numDirs++; 627 if (parent != NULL) { 628 parent->childCount++; 629 } 630 _inc_num_cache_collected(cache); 631 } else { 632 ALOGE("Failure allocating cache_dir_t for %s\n", name); 633 } 634 return dir; 635} 636 637static cache_file_t* _add_cache_file_t(cache_t* cache, cache_dir_t* dir, time_t modTime, 638 const char *name) 639{ 640 size_t nameLen = strlen(name); 641 cache_file_t* file = (cache_file_t*)_cache_malloc(cache, sizeof(cache_file_t)+nameLen+1); 642 if (file != NULL) { 643 file->dir = dir; 644 file->modTime = modTime; 645 strcpy(file->name, name); 646 if (cache->numFiles >= cache->availFiles) { 647 size_t newAvail = cache->availFiles < 1000 ? 1000 : cache->availFiles*2; 648 cache_file_t** newFiles = (cache_file_t**)_cache_realloc(cache, cache->files, 649 cache->availFiles*sizeof(cache_file_t*), newAvail*sizeof(cache_file_t*)); 650 if (newFiles == NULL) { 651 ALOGE("Failure growing cache file array for %s\n", name); 652 return NULL; 653 } 654 cache->availFiles = newAvail; 655 cache->files = newFiles; 656 } 657 CACHE_NOISY(ALOGI("Setting file %p at position %d in array %p", file, 658 cache->numFiles, cache->files)); 659 cache->files[cache->numFiles] = file; 660 cache->numFiles++; 661 dir->childCount++; 662 _inc_num_cache_collected(cache); 663 } else { 664 ALOGE("Failure allocating cache_file_t for %s\n", name); 665 } 666 return file; 667} 668 669static int _add_cache_files(cache_t *cache, cache_dir_t *parentDir, const char *dirName, 670 DIR* dir, char *pathBase, char *pathPos, size_t pathAvailLen) 671{ 672 struct dirent *de; 673 cache_dir_t* cacheDir = NULL; 674 int dfd; 675 676 CACHE_NOISY(ALOGI("_add_cache_files: parent=%p dirName=%s dir=%p pathBase=%s", 677 parentDir, dirName, dir, pathBase)); 678 679 dfd = dirfd(dir); 680 681 if (dfd < 0) return 0; 682 683 // Sub-directories always get added to the data structure, so if they 684 // are empty we will know about them to delete them later. 685 cacheDir = _add_cache_dir_t(cache, parentDir, dirName); 686 687 while ((de = readdir(dir))) { 688 const char *name = de->d_name; 689 690 if (de->d_type == DT_DIR) { 691 int subfd; 692 DIR *subdir; 693 694 /* always skip "." and ".." */ 695 if (name[0] == '.') { 696 if (name[1] == 0) continue; 697 if ((name[1] == '.') && (name[2] == 0)) continue; 698 } 699 700 subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); 701 if (subfd < 0) { 702 ALOGE("Couldn't openat %s: %s\n", name, strerror(errno)); 703 continue; 704 } 705 subdir = fdopendir(subfd); 706 if (subdir == NULL) { 707 ALOGE("Couldn't fdopendir %s: %s\n", name, strerror(errno)); 708 close(subfd); 709 continue; 710 } 711 if (cacheDir == NULL) { 712 cacheDir = _add_cache_dir_t(cache, parentDir, dirName); 713 } 714 if (cacheDir != NULL) { 715 // Update pathBase for the new path... this may change dirName 716 // if that is also pointing to the path, but we are done with it 717 // now. 718 size_t finallen = snprintf(pathPos, pathAvailLen, "/%s", name); 719 CACHE_NOISY(ALOGI("Collecting dir %s\n", pathBase)); 720 if (finallen < pathAvailLen) { 721 _add_cache_files(cache, cacheDir, name, subdir, pathBase, 722 pathPos+finallen, pathAvailLen-finallen); 723 } else { 724 // Whoops, the final path is too long! We'll just delete 725 // this directory. 726 ALOGW("Cache dir %s truncated in path %s; deleting dir\n", 727 name, pathBase); 728 _delete_dir_contents(subdir, NULL); 729 if (unlinkat(dfd, name, AT_REMOVEDIR) < 0) { 730 ALOGE("Couldn't unlinkat %s: %s\n", name, strerror(errno)); 731 } 732 } 733 } 734 closedir(subdir); 735 } else if (de->d_type == DT_REG) { 736 // Skip files that start with '.'; they will be deleted if 737 // their entire directory is deleted. This allows for metadata 738 // like ".nomedia" to remain in the directory until the entire 739 // directory is deleted. 740 if (cacheDir == NULL) { 741 cacheDir = _add_cache_dir_t(cache, parentDir, dirName); 742 } 743 if (name[0] == '.') { 744 cacheDir->hiddenCount++; 745 continue; 746 } 747 if (cacheDir != NULL) { 748 // Build final full path for file... this may change dirName 749 // if that is also pointing to the path, but we are done with it 750 // now. 751 size_t finallen = snprintf(pathPos, pathAvailLen, "/%s", name); 752 CACHE_NOISY(ALOGI("Collecting file %s\n", pathBase)); 753 if (finallen < pathAvailLen) { 754 struct stat s; 755 if (stat(pathBase, &s) >= 0) { 756 _add_cache_file_t(cache, cacheDir, s.st_mtime, name); 757 } else { 758 ALOGW("Unable to stat cache file %s; deleting\n", pathBase); 759 if (unlink(pathBase) < 0) { 760 ALOGE("Couldn't unlink %s: %s\n", pathBase, strerror(errno)); 761 } 762 } 763 } else { 764 // Whoops, the final path is too long! We'll just delete 765 // this file. 766 ALOGW("Cache file %s truncated in path %s; deleting\n", 767 name, pathBase); 768 if (unlinkat(dfd, name, 0) < 0) { 769 *pathPos = 0; 770 ALOGE("Couldn't unlinkat %s in %s: %s\n", name, pathBase, 771 strerror(errno)); 772 } 773 } 774 } 775 } else { 776 cacheDir->hiddenCount++; 777 } 778 } 779 return 0; 780} 781 782void add_cache_files(cache_t* cache, const std::string& data_path) { 783 DIR *d; 784 struct dirent *de; 785 char dirname[PATH_MAX]; 786 787 const char* basepath = data_path.c_str(); 788 CACHE_NOISY(ALOGI("add_cache_files: basepath=%s\n", basepath)); 789 790 d = opendir(basepath); 791 if (d == NULL) { 792 return; 793 } 794 795 while ((de = readdir(d))) { 796 if (de->d_type == DT_DIR) { 797 DIR* subdir; 798 const char *name = de->d_name; 799 char* pathpos; 800 801 /* always skip "." and ".." */ 802 if (name[0] == '.') { 803 if (name[1] == 0) continue; 804 if ((name[1] == '.') && (name[2] == 0)) continue; 805 } 806 807 strcpy(dirname, basepath); 808 pathpos = dirname + strlen(dirname); 809 if ((*(pathpos-1)) != '/') { 810 *pathpos = '/'; 811 pathpos++; 812 *pathpos = 0; 813 } 814 815 // TODO: also try searching using xattr when CE is locked 816 snprintf(pathpos, sizeof(dirname)-(pathpos-dirname), "%s/cache", name); 817 CACHE_NOISY(ALOGI("Adding cache files from dir: %s\n", dirname)); 818 819 subdir = opendir(dirname); 820 if (subdir != NULL) { 821 size_t dirnameLen = strlen(dirname); 822 _add_cache_files(cache, NULL, dirname, subdir, dirname, dirname+dirnameLen, 823 PATH_MAX - dirnameLen); 824 closedir(subdir); 825 } 826 } 827 } 828 829 closedir(d); 830} 831 832static char *create_dir_path(char path[PATH_MAX], cache_dir_t* dir) 833{ 834 char *pos = path; 835 if (dir->parent != NULL) { 836 pos = create_dir_path(path, dir->parent); 837 } 838 // Note that we don't need to worry about going beyond the buffer, 839 // since when we were constructing the cache entries our maximum 840 // buffer size for full paths was PATH_MAX. 841 strcpy(pos, dir->name); 842 pos += strlen(pos); 843 *pos = '/'; 844 pos++; 845 *pos = 0; 846 return pos; 847} 848 849static void delete_cache_dir(char path[PATH_MAX], cache_dir_t* dir) 850{ 851 if (dir->parent != NULL) { 852 create_dir_path(path, dir); 853 ALOGI("DEL DIR %s\n", path); 854 if (dir->hiddenCount <= 0) { 855 if (rmdir(path)) { 856 ALOGE("Couldn't rmdir %s: %s\n", path, strerror(errno)); 857 return; 858 } 859 } else { 860 // The directory contains hidden files so we need to delete 861 // them along with the directory itself. 862 if (delete_dir_contents(path, 1, NULL)) { 863 return; 864 } 865 } 866 dir->parent->childCount--; 867 dir->deleted = 1; 868 if (dir->parent->childCount <= 0) { 869 delete_cache_dir(path, dir->parent); 870 } 871 } else if (dir->hiddenCount > 0) { 872 // This is a root directory, but it has hidden files. Get rid of 873 // all of those files, but not the directory itself. 874 create_dir_path(path, dir); 875 ALOGI("DEL CONTENTS %s\n", path); 876 delete_dir_contents(path, 0, NULL); 877 } 878} 879 880static int cache_modtime_sort(const void *lhsP, const void *rhsP) 881{ 882 const cache_file_t *lhs = *(const cache_file_t**)lhsP; 883 const cache_file_t *rhs = *(const cache_file_t**)rhsP; 884 return lhs->modTime < rhs->modTime ? -1 : (lhs->modTime > rhs->modTime ? 1 : 0); 885} 886 887void clear_cache_files(const std::string& data_path, cache_t* cache, int64_t free_size) 888{ 889 size_t i; 890 int skip = 0; 891 char path[PATH_MAX]; 892 893 ALOGI("Collected cache files: %zd directories, %zd files", 894 cache->numDirs, cache->numFiles); 895 896 CACHE_NOISY(ALOGI("Sorting files...")); 897 qsort(cache->files, cache->numFiles, sizeof(cache_file_t*), 898 cache_modtime_sort); 899 900 CACHE_NOISY(ALOGI("Cleaning empty directories...")); 901 for (i=cache->numDirs; i>0; i--) { 902 cache_dir_t* dir = cache->dirs[i-1]; 903 if (dir->childCount <= 0 && !dir->deleted) { 904 delete_cache_dir(path, dir); 905 } 906 } 907 908 CACHE_NOISY(ALOGI("Trimming files...")); 909 for (i=0; i<cache->numFiles; i++) { 910 skip++; 911 if (skip > 10) { 912 if (data_disk_free(data_path) > free_size) { 913 return; 914 } 915 skip = 0; 916 } 917 cache_file_t* file = cache->files[i]; 918 strcpy(create_dir_path(path, file->dir), file->name); 919 ALOGI("DEL (mod %d) %s\n", (int)file->modTime, path); 920 if (unlink(path) < 0) { 921 ALOGE("Couldn't unlink %s: %s\n", path, strerror(errno)); 922 } 923 file->dir->childCount--; 924 if (file->dir->childCount <= 0) { 925 delete_cache_dir(path, file->dir); 926 } 927 } 928} 929 930void finish_cache_collection(cache_t* cache) 931{ 932 CACHE_NOISY(size_t i;) 933 934 CACHE_NOISY(ALOGI("clear_cache_files: %d dirs, %d files\n", cache->numDirs, cache->numFiles)); 935 CACHE_NOISY( 936 for (i=0; i<cache->numDirs; i++) { 937 cache_dir_t* dir = cache->dirs[i]; 938 ALOGI("dir #%d: %p %s parent=%p\n", i, dir, dir->name, dir->parent); 939 }) 940 CACHE_NOISY( 941 for (i=0; i<cache->numFiles; i++) { 942 cache_file_t* file = cache->files[i]; 943 ALOGI("file #%d: %p %s time=%d dir=%p\n", i, file, file->name, 944 (int)file->modTime, file->dir); 945 }) 946 void* block = cache->memBlocks; 947 while (block != NULL) { 948 void* nextBlock = *(void**)block; 949 CACHE_NOISY(ALOGI("Freeing cache mem block: %p", block)); 950 free(block); 951 block = nextBlock; 952 } 953 free(cache); 954} 955 956/** 957 * Validate that the path is valid in the context of the provided directory. 958 * The path is allowed to have at most one subdirectory and no indirections 959 * to top level directories (i.e. have ".."). 960 */ 961static int validate_path(const dir_rec_t* dir, const char* path, int maxSubdirs) { 962 size_t dir_len = dir->len; 963 const char* subdir = strchr(path + dir_len, '/'); 964 965 // Only allow the path to have at most one subdirectory. 966 if (subdir != NULL) { 967 ++subdir; 968 if ((--maxSubdirs == 0) && strchr(subdir, '/') != NULL) { 969 ALOGE("invalid apk path '%s' (subdir?)\n", path); 970 return -1; 971 } 972 } 973 974 // Directories can't have a period directly after the directory markers to prevent "..". 975 if ((path[dir_len] == '.') || ((subdir != NULL) && (*subdir == '.'))) { 976 ALOGE("invalid apk path '%s' (trickery)\n", path); 977 return -1; 978 } 979 980 return 0; 981} 982 983/** 984 * Checks whether a path points to a system app (.apk file). Returns 0 985 * if it is a system app or -1 if it is not. 986 */ 987int validate_system_app_path(const char* path) { 988 size_t i; 989 990 for (i = 0; i < android_system_dirs.count; i++) { 991 const size_t dir_len = android_system_dirs.dirs[i].len; 992 if (!strncmp(path, android_system_dirs.dirs[i].path, dir_len)) { 993 return validate_path(android_system_dirs.dirs + i, path, 1); 994 } 995 } 996 997 return -1; 998} 999 1000/** 1001 * Get the contents of a environment variable that contains a path. Caller 1002 * owns the string that is inserted into the directory record. Returns 1003 * 0 on success and -1 on error. 1004 */ 1005int get_path_from_env(dir_rec_t* rec, const char* var) { 1006 const char* path = getenv(var); 1007 int ret = get_path_from_string(rec, path); 1008 if (ret < 0) { 1009 ALOGW("Problem finding value for environment variable %s\n", var); 1010 } 1011 return ret; 1012} 1013 1014/** 1015 * Puts the string into the record as a directory. Appends '/' to the end 1016 * of all paths. Caller owns the string that is inserted into the directory 1017 * record. A null value will result in an error. 1018 * 1019 * Returns 0 on success and -1 on error. 1020 */ 1021int get_path_from_string(dir_rec_t* rec, const char* path) { 1022 if (path == NULL) { 1023 return -1; 1024 } else { 1025 const size_t path_len = strlen(path); 1026 if (path_len <= 0) { 1027 return -1; 1028 } 1029 1030 // Make sure path is absolute. 1031 if (path[0] != '/') { 1032 return -1; 1033 } 1034 1035 if (path[path_len - 1] == '/') { 1036 // Path ends with a forward slash. Make our own copy. 1037 1038 rec->path = strdup(path); 1039 if (rec->path == NULL) { 1040 return -1; 1041 } 1042 1043 rec->len = path_len; 1044 } else { 1045 // Path does not end with a slash. Generate a new string. 1046 char *dst; 1047 1048 // Add space for slash and terminating null. 1049 size_t dst_size = path_len + 2; 1050 1051 rec->path = (char*) malloc(dst_size); 1052 if (rec->path == NULL) { 1053 return -1; 1054 } 1055 1056 dst = rec->path; 1057 1058 if (append_and_increment(&dst, path, &dst_size) < 0 1059 || append_and_increment(&dst, "/", &dst_size)) { 1060 ALOGE("Error canonicalizing path"); 1061 return -1; 1062 } 1063 1064 rec->len = dst - rec->path; 1065 } 1066 } 1067 return 0; 1068} 1069 1070int copy_and_append(dir_rec_t* dst, const dir_rec_t* src, const char* suffix) { 1071 dst->len = src->len + strlen(suffix); 1072 const size_t dstSize = dst->len + 1; 1073 dst->path = (char*) malloc(dstSize); 1074 1075 if (dst->path == NULL 1076 || snprintf(dst->path, dstSize, "%s%s", src->path, suffix) 1077 != (ssize_t) dst->len) { 1078 ALOGE("Could not allocate memory to hold appended path; aborting\n"); 1079 return -1; 1080 } 1081 1082 return 0; 1083} 1084 1085/** 1086 * Check whether path points to a valid path for an APK file. The path must 1087 * begin with a whitelisted prefix path and must be no deeper than |maxSubdirs| within 1088 * that path. Returns -1 when an invalid path is encountered and 0 when a valid path 1089 * is encountered. 1090 */ 1091static int validate_apk_path_internal(const char *path, int maxSubdirs) { 1092 const dir_rec_t* dir = NULL; 1093 if (!strncmp(path, android_app_dir.path, android_app_dir.len)) { 1094 dir = &android_app_dir; 1095 } else if (!strncmp(path, android_app_private_dir.path, android_app_private_dir.len)) { 1096 dir = &android_app_private_dir; 1097 } else if (!strncmp(path, android_app_ephemeral_dir.path, android_app_ephemeral_dir.len)) { 1098 dir = &android_app_ephemeral_dir; 1099 } else if (!strncmp(path, android_asec_dir.path, android_asec_dir.len)) { 1100 dir = &android_asec_dir; 1101 } else if (!strncmp(path, android_mnt_expand_dir.path, android_mnt_expand_dir.len)) { 1102 dir = &android_mnt_expand_dir; 1103 if (maxSubdirs < 2) { 1104 maxSubdirs = 2; 1105 } 1106 } else { 1107 return -1; 1108 } 1109 1110 return validate_path(dir, path, maxSubdirs); 1111} 1112 1113int validate_apk_path(const char* path) { 1114 return validate_apk_path_internal(path, 1 /* maxSubdirs */); 1115} 1116 1117int validate_apk_path_subdirs(const char* path) { 1118 return validate_apk_path_internal(path, 3 /* maxSubdirs */); 1119} 1120 1121int append_and_increment(char** dst, const char* src, size_t* dst_size) { 1122 ssize_t ret = strlcpy(*dst, src, *dst_size); 1123 if (ret < 0 || (size_t) ret >= *dst_size) { 1124 return -1; 1125 } 1126 *dst += ret; 1127 *dst_size -= ret; 1128 return 0; 1129} 1130 1131char *build_string2(const char *s1, const char *s2) { 1132 if (s1 == NULL || s2 == NULL) return NULL; 1133 1134 int len_s1 = strlen(s1); 1135 int len_s2 = strlen(s2); 1136 int len = len_s1 + len_s2 + 1; 1137 char *result = (char *) malloc(len); 1138 if (result == NULL) return NULL; 1139 1140 strcpy(result, s1); 1141 strcpy(result + len_s1, s2); 1142 1143 return result; 1144} 1145 1146char *build_string3(const char *s1, const char *s2, const char *s3) { 1147 if (s1 == NULL || s2 == NULL || s3 == NULL) return NULL; 1148 1149 int len_s1 = strlen(s1); 1150 int len_s2 = strlen(s2); 1151 int len_s3 = strlen(s3); 1152 int len = len_s1 + len_s2 + len_s3 + 1; 1153 char *result = (char *) malloc(len); 1154 if (result == NULL) return NULL; 1155 1156 strcpy(result, s1); 1157 strcpy(result + len_s1, s2); 1158 strcpy(result + len_s1 + len_s2, s3); 1159 1160 return result; 1161} 1162 1163int ensure_config_user_dirs(userid_t userid) { 1164 // writable by system, readable by any app within the same user 1165 const int uid = multiuser_get_uid(userid, AID_SYSTEM); 1166 const int gid = multiuser_get_uid(userid, AID_EVERYBODY); 1167 1168 // Ensure /data/misc/user/<userid> exists 1169 auto path = create_data_misc_legacy_path(userid); 1170 return fs_prepare_dir(path.c_str(), 0750, uid, gid); 1171} 1172 1173int wait_child(pid_t pid) 1174{ 1175 int status; 1176 pid_t got_pid; 1177 1178 while (1) { 1179 got_pid = waitpid(pid, &status, 0); 1180 if (got_pid == -1 && errno == EINTR) { 1181 printf("waitpid interrupted, retrying\n"); 1182 } else { 1183 break; 1184 } 1185 } 1186 if (got_pid != pid) { 1187 ALOGW("waitpid failed: wanted %d, got %d: %s\n", 1188 (int) pid, (int) got_pid, strerror(errno)); 1189 return 1; 1190 } 1191 1192 if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { 1193 return 0; 1194 } else { 1195 return status; /* always nonzero */ 1196 } 1197} 1198 1199} // namespace installd 1200} // namespace android 1201