utils.cpp 37 KB

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