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