• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "InstalldNativeService.h"
18 
19 #define ATRACE_TAG ATRACE_TAG_PACKAGE_MANAGER
20 
21 #include <algorithm>
22 #include <errno.h>
23 #include <fstream>
24 #include <fts.h>
25 #include <functional>
26 #include <inttypes.h>
27 #include <regex>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <sys/capability.h>
31 #include <sys/file.h>
32 #include <sys/ioctl.h>
33 #include <sys/mman.h>
34 #include <sys/quota.h>
35 #include <sys/resource.h>
36 #include <sys/stat.h>
37 #include <sys/statvfs.h>
38 #include <sys/types.h>
39 #include <sys/wait.h>
40 #include <sys/xattr.h>
41 #include <unistd.h>
42 
43 #include <android-base/logging.h>
44 #include <android-base/properties.h>
45 #include <android-base/stringprintf.h>
46 #include <android-base/strings.h>
47 #include <android-base/unique_fd.h>
48 #include <cutils/ashmem.h>
49 #include <cutils/fs.h>
50 #include <cutils/properties.h>
51 #include <cutils/sched_policy.h>
52 #include <log/log.h>               // TODO: Move everything to base/logging.
53 #include <logwrap/logwrap.h>
54 #include <private/android_filesystem_config.h>
55 #include <selinux/android.h>
56 #include <system/thread_defs.h>
57 #include <utils/Trace.h>
58 
59 #include "dexopt.h"
60 #include "globals.h"
61 #include "installd_deps.h"
62 #include "otapreopt_utils.h"
63 #include "utils.h"
64 
65 #include "CacheTracker.h"
66 #include "MatchExtensionGen.h"
67 
68 #ifndef LOG_TAG
69 #define LOG_TAG "installd"
70 #endif
71 
72 using android::base::StringPrintf;
73 using std::endl;
74 
75 namespace android {
76 namespace installd {
77 
78 static constexpr const char* kCpPath = "/system/bin/cp";
79 static constexpr const char* kXattrDefault = "user.default";
80 static constexpr const char* kPropHasReserved = "vold.has_reserved";
81 
82 static constexpr const int MIN_RESTRICTED_HOME_SDK_VERSION = 24; // > M
83 
84 static constexpr const char* PKG_LIB_POSTFIX = "/lib";
85 static constexpr const char* CACHE_DIR_POSTFIX = "/cache";
86 static constexpr const char* CODE_CACHE_DIR_POSTFIX = "/code_cache";
87 
88 static constexpr const char *kIdMapPath = "/system/bin/idmap";
89 static constexpr const char* IDMAP_PREFIX = "/data/resource-cache/";
90 static constexpr const char* IDMAP_SUFFIX = "@idmap";
91 
92 // fsverity assumes the page size is always 4096. If not, the feature can not be
93 // enabled.
94 static constexpr int kVerityPageSize = 4096;
95 static constexpr size_t kSha256Size = 32;
96 static constexpr const char* kPropApkVerityMode = "ro.apk_verity.mode";
97 
98 // NOTE: keep in sync with Installer
99 static constexpr int FLAG_CLEAR_CACHE_ONLY = 1 << 8;
100 static constexpr int FLAG_CLEAR_CODE_CACHE_ONLY = 1 << 9;
101 static constexpr int FLAG_USE_QUOTA = 1 << 12;
102 static constexpr int FLAG_FREE_CACHE_V2 = 1 << 13;
103 static constexpr int FLAG_FREE_CACHE_V2_DEFY_QUOTA = 1 << 14;
104 static constexpr int FLAG_FREE_CACHE_NOOP = 1 << 15;
105 static constexpr int FLAG_FORCE = 1 << 16;
106 
107 namespace {
108 
109 constexpr const char* kDump = "android.permission.DUMP";
110 
ok()111 static binder::Status ok() {
112     return binder::Status::ok();
113 }
114 
exception(uint32_t code,const std::string & msg)115 static binder::Status exception(uint32_t code, const std::string& msg) {
116     LOG(ERROR) << msg << " (" << code << ")";
117     return binder::Status::fromExceptionCode(code, String8(msg.c_str()));
118 }
119 
error()120 static binder::Status error() {
121     return binder::Status::fromServiceSpecificError(errno);
122 }
123 
error(const std::string & msg)124 static binder::Status error(const std::string& msg) {
125     PLOG(ERROR) << msg;
126     return binder::Status::fromServiceSpecificError(errno, String8(msg.c_str()));
127 }
128 
error(uint32_t code,const std::string & msg)129 static binder::Status error(uint32_t code, const std::string& msg) {
130     LOG(ERROR) << msg << " (" << code << ")";
131     return binder::Status::fromServiceSpecificError(code, String8(msg.c_str()));
132 }
133 
checkPermission(const char * permission)134 binder::Status checkPermission(const char* permission) {
135     pid_t pid;
136     uid_t uid;
137 
138     if (checkCallingPermission(String16(permission), reinterpret_cast<int32_t*>(&pid),
139             reinterpret_cast<int32_t*>(&uid))) {
140         return ok();
141     } else {
142         return exception(binder::Status::EX_SECURITY,
143                 StringPrintf("UID %d / PID %d lacks permission %s", uid, pid, permission));
144     }
145 }
146 
checkUid(uid_t expectedUid)147 binder::Status checkUid(uid_t expectedUid) {
148     uid_t uid = IPCThreadState::self()->getCallingUid();
149     if (uid == expectedUid || uid == AID_ROOT) {
150         return ok();
151     } else {
152         return exception(binder::Status::EX_SECURITY,
153                 StringPrintf("UID %d is not expected UID %d", uid, expectedUid));
154     }
155 }
156 
checkArgumentUuid(const std::unique_ptr<std::string> & uuid)157 binder::Status checkArgumentUuid(const std::unique_ptr<std::string>& uuid) {
158     if (!uuid || is_valid_filename(*uuid)) {
159         return ok();
160     } else {
161         return exception(binder::Status::EX_ILLEGAL_ARGUMENT,
162                 StringPrintf("UUID %s is malformed", uuid->c_str()));
163     }
164 }
165 
checkArgumentPackageName(const std::string & packageName)166 binder::Status checkArgumentPackageName(const std::string& packageName) {
167     if (is_valid_package_name(packageName.c_str())) {
168         return ok();
169     } else {
170         return exception(binder::Status::EX_ILLEGAL_ARGUMENT,
171                 StringPrintf("Package name %s is malformed", packageName.c_str()));
172     }
173 }
174 
checkArgumentPath(const std::string & path)175 binder::Status checkArgumentPath(const std::string& path) {
176     if (path.empty()) {
177         return exception(binder::Status::EX_ILLEGAL_ARGUMENT, "Missing path");
178     }
179     if (path[0] != '/') {
180         return exception(binder::Status::EX_ILLEGAL_ARGUMENT,
181                 StringPrintf("Path %s is relative", path.c_str()));
182     }
183     if ((path + '/').find("/../") != std::string::npos) {
184         return exception(binder::Status::EX_ILLEGAL_ARGUMENT,
185                 StringPrintf("Path %s is shady", path.c_str()));
186     }
187     for (const char& c : path) {
188         if (c == '\0' || c == '\n') {
189             return exception(binder::Status::EX_ILLEGAL_ARGUMENT,
190                     StringPrintf("Path %s is malformed", path.c_str()));
191         }
192     }
193     return ok();
194 }
195 
checkArgumentPath(const std::unique_ptr<std::string> & path)196 binder::Status checkArgumentPath(const std::unique_ptr<std::string>& path) {
197     if (path) {
198         return checkArgumentPath(*path);
199     } else {
200         return ok();
201     }
202 }
203 
204 #define ENFORCE_UID(uid) {                                  \
205     binder::Status status = checkUid((uid));                \
206     if (!status.isOk()) {                                   \
207         return status;                                      \
208     }                                                       \
209 }
210 
211 #define CHECK_ARGUMENT_UUID(uuid) {                         \
212     binder::Status status = checkArgumentUuid((uuid));      \
213     if (!status.isOk()) {                                   \
214         return status;                                      \
215     }                                                       \
216 }
217 
218 #define CHECK_ARGUMENT_PACKAGE_NAME(packageName) {          \
219     binder::Status status =                                 \
220             checkArgumentPackageName((packageName));        \
221     if (!status.isOk()) {                                   \
222         return status;                                      \
223     }                                                       \
224 }
225 
226 #define CHECK_ARGUMENT_PATH(path) {                         \
227     binder::Status status = checkArgumentPath((path));      \
228     if (!status.isOk()) {                                   \
229         return status;                                      \
230     }                                                       \
231 }
232 
233 #define ASSERT_PAGE_SIZE_4K() {                             \
234     if (getpagesize() != kVerityPageSize) {                 \
235         return error("FSVerity only supports 4K pages");     \
236     }                                                       \
237 }
238 
239 }  // namespace
240 
start()241 status_t InstalldNativeService::start() {
242     IPCThreadState::self()->disableBackgroundScheduling(true);
243     status_t ret = BinderService<InstalldNativeService>::publish();
244     if (ret != android::OK) {
245         return ret;
246     }
247     sp<ProcessState> ps(ProcessState::self());
248     ps->startThreadPool();
249     ps->giveThreadPoolName();
250     return android::OK;
251 }
252 
dump(int fd,const Vector<String16> &)253 status_t InstalldNativeService::dump(int fd, const Vector<String16> & /* args */) {
254     auto out = std::fstream(StringPrintf("/proc/self/fd/%d", fd));
255     const binder::Status dump_permission = checkPermission(kDump);
256     if (!dump_permission.isOk()) {
257         out << dump_permission.toString8() << endl;
258         return PERMISSION_DENIED;
259     }
260     std::lock_guard<std::recursive_mutex> lock(mLock);
261 
262     out << "installd is happy!" << endl;
263 
264     {
265         std::lock_guard<std::recursive_mutex> lock(mMountsLock);
266         out << endl << "Storage mounts:" << endl;
267         for (const auto& n : mStorageMounts) {
268             out << "    " << n.first << " = " << n.second << endl;
269         }
270 
271         out << endl << "Quota reverse mounts:" << endl;
272         for (const auto& n : mQuotaReverseMounts) {
273             out << "    " << n.first << " = " << n.second << endl;
274         }
275     }
276 
277     {
278         std::lock_guard<std::recursive_mutex> lock(mQuotasLock);
279         out << endl << "Per-UID cache quotas:" << endl;
280         for (const auto& n : mCacheQuotas) {
281             out << "    " << n.first << " = " << n.second << endl;
282         }
283     }
284 
285     out << endl;
286     out.flush();
287 
288     return NO_ERROR;
289 }
290 
291 /**
292  * Perform restorecon of the given path, but only perform recursive restorecon
293  * if the label of that top-level file actually changed.  This can save us
294  * significant time by avoiding no-op traversals of large filesystem trees.
295  */
restorecon_app_data_lazy(const std::string & path,const std::string & seInfo,uid_t uid,bool existing)296 static int restorecon_app_data_lazy(const std::string& path, const std::string& seInfo, uid_t uid,
297         bool existing) {
298     int res = 0;
299     char* before = nullptr;
300     char* after = nullptr;
301 
302     // Note that SELINUX_ANDROID_RESTORECON_DATADATA flag is set by
303     // libselinux. Not needed here.
304 
305     if (lgetfilecon(path.c_str(), &before) < 0) {
306         PLOG(ERROR) << "Failed before getfilecon for " << path;
307         goto fail;
308     }
309     if (selinux_android_restorecon_pkgdir(path.c_str(), seInfo.c_str(), uid, 0) < 0) {
310         PLOG(ERROR) << "Failed top-level restorecon for " << path;
311         goto fail;
312     }
313     if (lgetfilecon(path.c_str(), &after) < 0) {
314         PLOG(ERROR) << "Failed after getfilecon for " << path;
315         goto fail;
316     }
317 
318     // If the initial top-level restorecon above changed the label, then go
319     // back and restorecon everything recursively
320     if (strcmp(before, after)) {
321         if (existing) {
322             LOG(DEBUG) << "Detected label change from " << before << " to " << after << " at "
323                     << path << "; running recursive restorecon";
324         }
325         if (selinux_android_restorecon_pkgdir(path.c_str(), seInfo.c_str(), uid,
326                 SELINUX_ANDROID_RESTORECON_RECURSE) < 0) {
327             PLOG(ERROR) << "Failed recursive restorecon for " << path;
328             goto fail;
329         }
330     }
331 
332     goto done;
333 fail:
334     res = -1;
335 done:
336     free(before);
337     free(after);
338     return res;
339 }
340 
restorecon_app_data_lazy(const std::string & parent,const char * name,const std::string & seInfo,uid_t uid,bool existing)341 static int restorecon_app_data_lazy(const std::string& parent, const char* name,
342         const std::string& seInfo, uid_t uid, bool existing) {
343     return restorecon_app_data_lazy(StringPrintf("%s/%s", parent.c_str(), name), seInfo, uid,
344             existing);
345 }
346 
prepare_app_dir(const std::string & path,mode_t target_mode,uid_t uid)347 static int prepare_app_dir(const std::string& path, mode_t target_mode, uid_t uid) {
348     if (fs_prepare_dir_strict(path.c_str(), target_mode, uid, uid) != 0) {
349         PLOG(ERROR) << "Failed to prepare " << path;
350         return -1;
351     }
352     return 0;
353 }
354 
355 /**
356  * Ensure that we have a hard-limit quota to protect against abusive apps;
357  * they should never use more than 90% of blocks or 50% of inodes.
358  */
prepare_app_quota(const std::unique_ptr<std::string> & uuid ATTRIBUTE_UNUSED,const std::string & device,uid_t uid)359 static int prepare_app_quota(const std::unique_ptr<std::string>& uuid ATTRIBUTE_UNUSED,
360         const std::string& device, uid_t uid) {
361     // Skip when reserved blocks are protecting us against abusive apps
362     if (android::base::GetBoolProperty(kPropHasReserved, false)) return 0;
363     // Skip when device no quotas present
364     if (device.empty()) return 0;
365 
366     struct dqblk dq;
367     if (quotactl(QCMD(Q_GETQUOTA, USRQUOTA), device.c_str(), uid,
368             reinterpret_cast<char*>(&dq)) != 0) {
369         PLOG(WARNING) << "Failed to find quota for " << uid;
370         return -1;
371     }
372 
373 #if APPLY_HARD_QUOTAS
374     if ((dq.dqb_bhardlimit == 0) || (dq.dqb_ihardlimit == 0)) {
375         auto path = create_data_path(uuid ? uuid->c_str() : nullptr);
376         struct statvfs stat;
377         if (statvfs(path.c_str(), &stat) != 0) {
378             PLOG(WARNING) << "Failed to statvfs " << path;
379             return -1;
380         }
381 
382         dq.dqb_valid = QIF_LIMITS;
383         dq.dqb_bhardlimit =
384             (((static_cast<uint64_t>(stat.f_blocks) * stat.f_frsize) / 10) * 9) / QIF_DQBLKSIZE;
385         dq.dqb_ihardlimit = (stat.f_files / 2);
386         if (quotactl(QCMD(Q_SETQUOTA, USRQUOTA), device.c_str(), uid,
387                 reinterpret_cast<char*>(&dq)) != 0) {
388             PLOG(WARNING) << "Failed to set hard quota for " << uid;
389             return -1;
390         } else {
391             LOG(DEBUG) << "Applied hard quotas for " << uid;
392             return 0;
393         }
394     } else {
395         // Hard quota already set; assume it's reasonable
396         return 0;
397     }
398 #else
399     // Hard quotas disabled
400     return 0;
401 #endif
402 }
403 
prepare_app_profile_dir(const std::string & packageName,int32_t appId,int32_t userId)404 static bool prepare_app_profile_dir(const std::string& packageName, int32_t appId, int32_t userId) {
405     if (!property_get_bool("dalvik.vm.usejitprofiles", false)) {
406         return true;
407     }
408 
409     int32_t uid = multiuser_get_uid(userId, appId);
410     int shared_app_gid = multiuser_get_shared_gid(userId, appId);
411     if (shared_app_gid == -1) {
412         // TODO(calin): this should no longer be possible but do not continue if we don't get
413         // a valid shared gid.
414         PLOG(WARNING) << "Invalid shared_app_gid for " << packageName;
415         return true;
416     }
417 
418     const std::string profile_dir =
419             create_primary_current_profile_package_dir_path(userId, packageName);
420     // read-write-execute only for the app user.
421     if (fs_prepare_dir_strict(profile_dir.c_str(), 0700, uid, uid) != 0) {
422         PLOG(ERROR) << "Failed to prepare " << profile_dir;
423         return false;
424     }
425 
426     const std::string ref_profile_path =
427             create_primary_reference_profile_package_dir_path(packageName);
428 
429     // Prepare the reference profile directory. Note that we use the non strict version of
430     // fs_prepare_dir. This will fix the permission and the ownership to the correct values.
431     // This is particularly important given that in O there were some fixes for how the
432     // shared_app_gid is computed.
433     //
434     // Note that by the time we get here we know that we are using a correct uid (otherwise
435     // prepare_app_dir and the above fs_prepare_file_strict which check the uid). So we
436     // are sure that the gid being used belongs to the owning app and not someone else.
437     //
438     // dex2oat/profman runs under the shared app gid and it needs to read/write reference profiles.
439     if (fs_prepare_dir(ref_profile_path.c_str(), 0770, AID_SYSTEM, shared_app_gid) != 0) {
440         PLOG(ERROR) << "Failed to prepare " << ref_profile_path;
441         return false;
442     }
443 
444     return true;
445 }
446 
createAppData(const std::unique_ptr<std::string> & uuid,const std::string & packageName,int32_t userId,int32_t flags,int32_t appId,const std::string & seInfo,int32_t targetSdkVersion,int64_t * _aidl_return)447 binder::Status InstalldNativeService::createAppData(const std::unique_ptr<std::string>& uuid,
448         const std::string& packageName, int32_t userId, int32_t flags, int32_t appId,
449         const std::string& seInfo, int32_t targetSdkVersion, int64_t* _aidl_return) {
450     ENFORCE_UID(AID_SYSTEM);
451     CHECK_ARGUMENT_UUID(uuid);
452     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
453     std::lock_guard<std::recursive_mutex> lock(mLock);
454 
455     const char* uuid_ = uuid ? uuid->c_str() : nullptr;
456     const char* pkgname = packageName.c_str();
457 
458     // Assume invalid inode unless filled in below
459     if (_aidl_return != nullptr) *_aidl_return = -1;
460 
461     int32_t uid = multiuser_get_uid(userId, appId);
462     int32_t cacheGid = multiuser_get_cache_gid(userId, appId);
463     mode_t targetMode = targetSdkVersion >= MIN_RESTRICTED_HOME_SDK_VERSION ? 0700 : 0751;
464 
465     // If UID doesn't have a specific cache GID, use UID value
466     if (cacheGid == -1) {
467         cacheGid = uid;
468     }
469 
470     if (flags & FLAG_STORAGE_CE) {
471         auto path = create_data_user_ce_package_path(uuid_, userId, pkgname);
472         bool existing = (access(path.c_str(), F_OK) == 0);
473 
474         if (prepare_app_dir(path, targetMode, uid) ||
475                 prepare_app_cache_dir(path, "cache", 02771, uid, cacheGid) ||
476                 prepare_app_cache_dir(path, "code_cache", 02771, uid, cacheGid)) {
477             return error("Failed to prepare " + path);
478         }
479 
480         // Consider restorecon over contents if label changed
481         if (restorecon_app_data_lazy(path, seInfo, uid, existing) ||
482                 restorecon_app_data_lazy(path, "cache", seInfo, uid, existing) ||
483                 restorecon_app_data_lazy(path, "code_cache", seInfo, uid, existing)) {
484             return error("Failed to restorecon " + path);
485         }
486 
487         // Remember inode numbers of cache directories so that we can clear
488         // contents while CE storage is locked
489         if (write_path_inode(path, "cache", kXattrInodeCache) ||
490                 write_path_inode(path, "code_cache", kXattrInodeCodeCache)) {
491             return error("Failed to write_path_inode for " + path);
492         }
493 
494         // And return the CE inode of the top-level data directory so we can
495         // clear contents while CE storage is locked
496         if ((_aidl_return != nullptr)
497                 && get_path_inode(path, reinterpret_cast<ino_t*>(_aidl_return)) != 0) {
498             return error("Failed to get_path_inode for " + path);
499         }
500     }
501     if (flags & FLAG_STORAGE_DE) {
502         auto path = create_data_user_de_package_path(uuid_, userId, pkgname);
503         bool existing = (access(path.c_str(), F_OK) == 0);
504 
505         if (prepare_app_dir(path, targetMode, uid) ||
506                 prepare_app_cache_dir(path, "cache", 02771, uid, cacheGid) ||
507                 prepare_app_cache_dir(path, "code_cache", 02771, uid, cacheGid)) {
508             return error("Failed to prepare " + path);
509         }
510 
511         // Consider restorecon over contents if label changed
512         if (restorecon_app_data_lazy(path, seInfo, uid, existing) ||
513                 restorecon_app_data_lazy(path, "cache", seInfo, uid, existing) ||
514                 restorecon_app_data_lazy(path, "code_cache", seInfo, uid, existing)) {
515             return error("Failed to restorecon " + path);
516         }
517 
518         if (prepare_app_quota(uuid, findQuotaDeviceForUuid(uuid), uid)) {
519             return error("Failed to set hard quota " + path);
520         }
521 
522         if (!prepare_app_profile_dir(packageName, appId, userId)) {
523             return error("Failed to prepare profiles for " + packageName);
524         }
525     }
526     return ok();
527 }
528 
migrateAppData(const std::unique_ptr<std::string> & uuid,const std::string & packageName,int32_t userId,int32_t flags)529 binder::Status InstalldNativeService::migrateAppData(const std::unique_ptr<std::string>& uuid,
530         const std::string& packageName, int32_t userId, int32_t flags) {
531     ENFORCE_UID(AID_SYSTEM);
532     CHECK_ARGUMENT_UUID(uuid);
533     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
534     std::lock_guard<std::recursive_mutex> lock(mLock);
535 
536     const char* uuid_ = uuid ? uuid->c_str() : nullptr;
537     const char* pkgname = packageName.c_str();
538 
539     // This method only exists to upgrade system apps that have requested
540     // forceDeviceEncrypted, so their default storage always lives in a
541     // consistent location.  This only works on non-FBE devices, since we
542     // never want to risk exposing data on a device with real CE/DE storage.
543 
544     auto ce_path = create_data_user_ce_package_path(uuid_, userId, pkgname);
545     auto de_path = create_data_user_de_package_path(uuid_, userId, pkgname);
546 
547     // If neither directory is marked as default, assume CE is default
548     if (getxattr(ce_path.c_str(), kXattrDefault, nullptr, 0) == -1
549             && getxattr(de_path.c_str(), kXattrDefault, nullptr, 0) == -1) {
550         if (setxattr(ce_path.c_str(), kXattrDefault, nullptr, 0, 0) != 0) {
551             return error("Failed to mark default storage " + ce_path);
552         }
553     }
554 
555     // Migrate default data location if needed
556     auto target = (flags & FLAG_STORAGE_DE) ? de_path : ce_path;
557     auto source = (flags & FLAG_STORAGE_DE) ? ce_path : de_path;
558 
559     if (getxattr(target.c_str(), kXattrDefault, nullptr, 0) == -1) {
560         LOG(WARNING) << "Requested default storage " << target
561                 << " is not active; migrating from " << source;
562         if (delete_dir_contents_and_dir(target) != 0) {
563             return error("Failed to delete " + target);
564         }
565         if (rename(source.c_str(), target.c_str()) != 0) {
566             return error("Failed to rename " + source + " to " + target);
567         }
568     }
569 
570     return ok();
571 }
572 
573 
clearAppProfiles(const std::string & packageName,const std::string & profileName)574 binder::Status InstalldNativeService::clearAppProfiles(const std::string& packageName,
575         const std::string& profileName) {
576     ENFORCE_UID(AID_SYSTEM);
577     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
578     std::lock_guard<std::recursive_mutex> lock(mLock);
579 
580     binder::Status res = ok();
581     if (!clear_primary_reference_profile(packageName, profileName)) {
582         res = error("Failed to clear reference profile for " + packageName);
583     }
584     if (!clear_primary_current_profiles(packageName, profileName)) {
585         res = error("Failed to clear current profiles for " + packageName);
586     }
587     return res;
588 }
589 
clearAppData(const std::unique_ptr<std::string> & uuid,const std::string & packageName,int32_t userId,int32_t flags,int64_t ceDataInode)590 binder::Status InstalldNativeService::clearAppData(const std::unique_ptr<std::string>& uuid,
591         const std::string& packageName, int32_t userId, int32_t flags, int64_t ceDataInode) {
592     ENFORCE_UID(AID_SYSTEM);
593     CHECK_ARGUMENT_UUID(uuid);
594     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
595     std::lock_guard<std::recursive_mutex> lock(mLock);
596 
597     const char* uuid_ = uuid ? uuid->c_str() : nullptr;
598     const char* pkgname = packageName.c_str();
599 
600     binder::Status res = ok();
601     if (flags & FLAG_STORAGE_CE) {
602         auto path = create_data_user_ce_package_path(uuid_, userId, pkgname, ceDataInode);
603         if (flags & FLAG_CLEAR_CACHE_ONLY) {
604             path = read_path_inode(path, "cache", kXattrInodeCache);
605         } else if (flags & FLAG_CLEAR_CODE_CACHE_ONLY) {
606             path = read_path_inode(path, "code_cache", kXattrInodeCodeCache);
607         }
608         if (access(path.c_str(), F_OK) == 0) {
609             if (delete_dir_contents(path) != 0) {
610                 res = error("Failed to delete contents of " + path);
611             } else if ((flags & (FLAG_CLEAR_CACHE_ONLY | FLAG_CLEAR_CODE_CACHE_ONLY)) == 0) {
612                 remove_path_xattr(path, kXattrInodeCache);
613                 remove_path_xattr(path, kXattrInodeCodeCache);
614             }
615         }
616     }
617     if (flags & FLAG_STORAGE_DE) {
618         std::string suffix = "";
619         bool only_cache = false;
620         if (flags & FLAG_CLEAR_CACHE_ONLY) {
621             suffix = CACHE_DIR_POSTFIX;
622             only_cache = true;
623         } else if (flags & FLAG_CLEAR_CODE_CACHE_ONLY) {
624             suffix = CODE_CACHE_DIR_POSTFIX;
625             only_cache = true;
626         }
627 
628         auto path = create_data_user_de_package_path(uuid_, userId, pkgname) + suffix;
629         if (access(path.c_str(), F_OK) == 0) {
630             if (delete_dir_contents(path) != 0) {
631                 res = error("Failed to delete contents of " + path);
632             }
633         }
634     }
635     return res;
636 }
637 
destroy_app_reference_profile(const std::string & pkgname)638 static int destroy_app_reference_profile(const std::string& pkgname) {
639     return delete_dir_contents_and_dir(
640         create_primary_reference_profile_package_dir_path(pkgname),
641         /*ignore_if_missing*/ true);
642 }
643 
destroy_app_current_profiles(const std::string & pkgname,userid_t userid)644 static int destroy_app_current_profiles(const std::string& pkgname, userid_t userid) {
645     return delete_dir_contents_and_dir(
646         create_primary_current_profile_package_dir_path(userid, pkgname),
647         /*ignore_if_missing*/ true);
648 }
649 
destroyAppProfiles(const std::string & packageName)650 binder::Status InstalldNativeService::destroyAppProfiles(const std::string& packageName) {
651     ENFORCE_UID(AID_SYSTEM);
652     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
653     std::lock_guard<std::recursive_mutex> lock(mLock);
654 
655     binder::Status res = ok();
656     std::vector<userid_t> users = get_known_users(/*volume_uuid*/ nullptr);
657     for (auto user : users) {
658         if (destroy_app_current_profiles(packageName, user) != 0) {
659             res = error("Failed to destroy current profiles for " + packageName);
660         }
661     }
662     if (destroy_app_reference_profile(packageName) != 0) {
663         res = error("Failed to destroy reference profile for " + packageName);
664     }
665     return res;
666 }
667 
destroyAppData(const std::unique_ptr<std::string> & uuid,const std::string & packageName,int32_t userId,int32_t flags,int64_t ceDataInode)668 binder::Status InstalldNativeService::destroyAppData(const std::unique_ptr<std::string>& uuid,
669         const std::string& packageName, int32_t userId, int32_t flags, int64_t ceDataInode) {
670     ENFORCE_UID(AID_SYSTEM);
671     CHECK_ARGUMENT_UUID(uuid);
672     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
673     std::lock_guard<std::recursive_mutex> lock(mLock);
674 
675     const char* uuid_ = uuid ? uuid->c_str() : nullptr;
676     const char* pkgname = packageName.c_str();
677 
678     binder::Status res = ok();
679     if (flags & FLAG_STORAGE_CE) {
680         auto path = create_data_user_ce_package_path(uuid_, userId, pkgname, ceDataInode);
681         if (delete_dir_contents_and_dir(path) != 0) {
682             res = error("Failed to delete " + path);
683         }
684     }
685     if (flags & FLAG_STORAGE_DE) {
686         auto path = create_data_user_de_package_path(uuid_, userId, pkgname);
687         if (delete_dir_contents_and_dir(path) != 0) {
688             res = error("Failed to delete " + path);
689         }
690         destroy_app_current_profiles(packageName, userId);
691         // TODO(calin): If the package is still installed by other users it's probably
692         // beneficial to keep the reference profile around.
693         // Verify if it's ok to do that.
694         destroy_app_reference_profile(packageName);
695     }
696     return res;
697 }
698 
get_cache_gid(uid_t uid)699 static gid_t get_cache_gid(uid_t uid) {
700     int32_t gid = multiuser_get_cache_gid(multiuser_get_user_id(uid), multiuser_get_app_id(uid));
701     return (gid != -1) ? gid : uid;
702 }
703 
fixupAppData(const std::unique_ptr<std::string> & uuid,int32_t flags)704 binder::Status InstalldNativeService::fixupAppData(const std::unique_ptr<std::string>& uuid,
705         int32_t flags) {
706     ENFORCE_UID(AID_SYSTEM);
707     CHECK_ARGUMENT_UUID(uuid);
708     std::lock_guard<std::recursive_mutex> lock(mLock);
709 
710     const char* uuid_ = uuid ? uuid->c_str() : nullptr;
711     for (auto user : get_known_users(uuid_)) {
712         ATRACE_BEGIN("fixup user");
713         FTS* fts;
714         FTSENT* p;
715         auto ce_path = create_data_user_ce_path(uuid_, user);
716         auto de_path = create_data_user_de_path(uuid_, user);
717         char *argv[] = { (char*) ce_path.c_str(), (char*) de_path.c_str(), nullptr };
718         if (!(fts = fts_open(argv, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, NULL))) {
719             return error("Failed to fts_open");
720         }
721         while ((p = fts_read(fts)) != nullptr) {
722             if (p->fts_info == FTS_D && p->fts_level == 1) {
723                 // Track down inodes of cache directories
724                 uint64_t raw = 0;
725                 ino_t inode_cache = 0;
726                 ino_t inode_code_cache = 0;
727                 if (getxattr(p->fts_path, kXattrInodeCache, &raw, sizeof(raw)) == sizeof(raw)) {
728                     inode_cache = raw;
729                 }
730                 if (getxattr(p->fts_path, kXattrInodeCodeCache, &raw, sizeof(raw)) == sizeof(raw)) {
731                     inode_code_cache = raw;
732                 }
733 
734                 // Figure out expected GID of each child
735                 FTSENT* child = fts_children(fts, 0);
736                 while (child != nullptr) {
737                     if ((child->fts_statp->st_ino == inode_cache)
738                             || (child->fts_statp->st_ino == inode_code_cache)
739                             || !strcmp(child->fts_name, "cache")
740                             || !strcmp(child->fts_name, "code_cache")) {
741                         child->fts_number = get_cache_gid(p->fts_statp->st_uid);
742                     } else {
743                         child->fts_number = p->fts_statp->st_uid;
744                     }
745                     child = child->fts_link;
746                 }
747             } else if (p->fts_level >= 2) {
748                 if (p->fts_level > 2) {
749                     // Inherit GID from parent once we're deeper into tree
750                     p->fts_number = p->fts_parent->fts_number;
751                 }
752 
753                 uid_t uid = p->fts_parent->fts_statp->st_uid;
754                 gid_t cache_gid = get_cache_gid(uid);
755                 gid_t expected = p->fts_number;
756                 gid_t actual = p->fts_statp->st_gid;
757                 if (actual == expected) {
758 #if FIXUP_DEBUG
759                     LOG(DEBUG) << "Ignoring " << p->fts_path << " with expected GID " << expected;
760 #endif
761                     if (!(flags & FLAG_FORCE)) {
762                         fts_set(fts, p, FTS_SKIP);
763                     }
764                 } else if ((actual == uid) || (actual == cache_gid)) {
765                     // Only consider fixing up when current GID belongs to app
766                     if (p->fts_info != FTS_D) {
767                         LOG(INFO) << "Fixing " << p->fts_path << " with unexpected GID " << actual
768                                 << " instead of " << expected;
769                     }
770                     switch (p->fts_info) {
771                     case FTS_DP:
772                         // If we're moving towards cache GID, we need to set S_ISGID
773                         if (expected == cache_gid) {
774                             if (chmod(p->fts_path, 02771) != 0) {
775                                 PLOG(WARNING) << "Failed to chmod " << p->fts_path;
776                             }
777                         }
778                         // Intentional fall through to also set GID
779                     case FTS_F:
780                         if (chown(p->fts_path, -1, expected) != 0) {
781                             PLOG(WARNING) << "Failed to chown " << p->fts_path;
782                         }
783                         break;
784                     case FTS_SL:
785                     case FTS_SLNONE:
786                         if (lchown(p->fts_path, -1, expected) != 0) {
787                             PLOG(WARNING) << "Failed to chown " << p->fts_path;
788                         }
789                         break;
790                     }
791                 } else {
792                     // Ignore all other GID transitions, since they're kinda shady
793                     LOG(WARNING) << "Ignoring " << p->fts_path << " with unexpected GID " << actual
794                             << " instead of " << expected;
795                     if (!(flags & FLAG_FORCE)) {
796                         fts_set(fts, p, FTS_SKIP);
797                     }
798                 }
799             }
800         }
801         fts_close(fts);
802         ATRACE_END();
803     }
804     return ok();
805 }
806 
moveCompleteApp(const std::unique_ptr<std::string> & fromUuid,const std::unique_ptr<std::string> & toUuid,const std::string & packageName,const std::string & dataAppName,int32_t appId,const std::string & seInfo,int32_t targetSdkVersion)807 binder::Status InstalldNativeService::moveCompleteApp(const std::unique_ptr<std::string>& fromUuid,
808         const std::unique_ptr<std::string>& toUuid, const std::string& packageName,
809         const std::string& dataAppName, int32_t appId, const std::string& seInfo,
810         int32_t targetSdkVersion) {
811     ENFORCE_UID(AID_SYSTEM);
812     CHECK_ARGUMENT_UUID(fromUuid);
813     CHECK_ARGUMENT_UUID(toUuid);
814     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
815     std::lock_guard<std::recursive_mutex> lock(mLock);
816 
817     const char* from_uuid = fromUuid ? fromUuid->c_str() : nullptr;
818     const char* to_uuid = toUuid ? toUuid->c_str() : nullptr;
819     const char* package_name = packageName.c_str();
820     const char* data_app_name = dataAppName.c_str();
821 
822     binder::Status res = ok();
823     std::vector<userid_t> users = get_known_users(from_uuid);
824 
825     // Copy app
826     {
827         auto from = create_data_app_package_path(from_uuid, data_app_name);
828         auto to = create_data_app_package_path(to_uuid, data_app_name);
829         auto to_parent = create_data_app_path(to_uuid);
830 
831         char *argv[] = {
832             (char*) kCpPath,
833             (char*) "-F", /* delete any existing destination file first (--remove-destination) */
834             (char*) "-p", /* preserve timestamps, ownership, and permissions */
835             (char*) "-R", /* recurse into subdirectories (DEST must be a directory) */
836             (char*) "-P", /* Do not follow symlinks [default] */
837             (char*) "-d", /* don't dereference symlinks */
838             (char*) from.c_str(),
839             (char*) to_parent.c_str()
840         };
841 
842         LOG(DEBUG) << "Copying " << from << " to " << to;
843         int rc = android_fork_execvp(ARRAY_SIZE(argv), argv, NULL, false, true);
844         if (rc != 0) {
845             res = error(rc, "Failed copying " + from + " to " + to);
846             goto fail;
847         }
848 
849         if (selinux_android_restorecon(to.c_str(), SELINUX_ANDROID_RESTORECON_RECURSE) != 0) {
850             res = error("Failed to restorecon " + to);
851             goto fail;
852         }
853     }
854 
855     // Copy private data for all known users
856     for (auto user : users) {
857 
858         // Data source may not exist for all users; that's okay
859         auto from_ce = create_data_user_ce_package_path(from_uuid, user, package_name);
860         if (access(from_ce.c_str(), F_OK) != 0) {
861             LOG(INFO) << "Missing source " << from_ce;
862             continue;
863         }
864 
865         if (!createAppData(toUuid, packageName, user, FLAG_STORAGE_CE | FLAG_STORAGE_DE, appId,
866                 seInfo, targetSdkVersion, nullptr).isOk()) {
867             res = error("Failed to create package target");
868             goto fail;
869         }
870 
871         char *argv[] = {
872             (char*) kCpPath,
873             (char*) "-F", /* delete any existing destination file first (--remove-destination) */
874             (char*) "-p", /* preserve timestamps, ownership, and permissions */
875             (char*) "-R", /* recurse into subdirectories (DEST must be a directory) */
876             (char*) "-P", /* Do not follow symlinks [default] */
877             (char*) "-d", /* don't dereference symlinks */
878             nullptr,
879             nullptr
880         };
881 
882         {
883             auto from = create_data_user_de_package_path(from_uuid, user, package_name);
884             auto to = create_data_user_de_path(to_uuid, user);
885             argv[6] = (char*) from.c_str();
886             argv[7] = (char*) to.c_str();
887 
888             LOG(DEBUG) << "Copying " << from << " to " << to;
889             int rc = android_fork_execvp(ARRAY_SIZE(argv), argv, NULL, false, true);
890             if (rc != 0) {
891                 res = error(rc, "Failed copying " + from + " to " + to);
892                 goto fail;
893             }
894         }
895         {
896             auto from = create_data_user_ce_package_path(from_uuid, user, package_name);
897             auto to = create_data_user_ce_path(to_uuid, user);
898             argv[6] = (char*) from.c_str();
899             argv[7] = (char*) to.c_str();
900 
901             LOG(DEBUG) << "Copying " << from << " to " << to;
902             int rc = android_fork_execvp(ARRAY_SIZE(argv), argv, NULL, false, true);
903             if (rc != 0) {
904                 res = error(rc, "Failed copying " + from + " to " + to);
905                 goto fail;
906             }
907         }
908 
909         if (!restoreconAppData(toUuid, packageName, user, FLAG_STORAGE_CE | FLAG_STORAGE_DE,
910                 appId, seInfo).isOk()) {
911             res = error("Failed to restorecon");
912             goto fail;
913         }
914     }
915 
916     // We let the framework scan the new location and persist that before
917     // deleting the data in the old location; this ordering ensures that
918     // we can recover from things like battery pulls.
919     return ok();
920 
921 fail:
922     // Nuke everything we might have already copied
923     {
924         auto to = create_data_app_package_path(to_uuid, data_app_name);
925         if (delete_dir_contents(to.c_str(), 1, NULL) != 0) {
926             LOG(WARNING) << "Failed to rollback " << to;
927         }
928     }
929     for (auto user : users) {
930         {
931             auto to = create_data_user_de_package_path(to_uuid, user, package_name);
932             if (delete_dir_contents(to.c_str(), 1, NULL) != 0) {
933                 LOG(WARNING) << "Failed to rollback " << to;
934             }
935         }
936         {
937             auto to = create_data_user_ce_package_path(to_uuid, user, package_name);
938             if (delete_dir_contents(to.c_str(), 1, NULL) != 0) {
939                 LOG(WARNING) << "Failed to rollback " << to;
940             }
941         }
942     }
943     return res;
944 }
945 
createUserData(const std::unique_ptr<std::string> & uuid,int32_t userId,int32_t userSerial ATTRIBUTE_UNUSED,int32_t flags)946 binder::Status InstalldNativeService::createUserData(const std::unique_ptr<std::string>& uuid,
947         int32_t userId, int32_t userSerial ATTRIBUTE_UNUSED, int32_t flags) {
948     ENFORCE_UID(AID_SYSTEM);
949     CHECK_ARGUMENT_UUID(uuid);
950     std::lock_guard<std::recursive_mutex> lock(mLock);
951 
952     const char* uuid_ = uuid ? uuid->c_str() : nullptr;
953     if (flags & FLAG_STORAGE_DE) {
954         if (uuid_ == nullptr) {
955             if (ensure_config_user_dirs(userId) != 0) {
956                 return error(StringPrintf("Failed to ensure dirs for %d", userId));
957             }
958         }
959     }
960 
961     // Data under /data/media doesn't have an app, but we still want
962     // to limit it to prevent abuse.
963     if (prepare_app_quota(uuid, findQuotaDeviceForUuid(uuid),
964             multiuser_get_uid(userId, AID_MEDIA_RW))) {
965         return error("Failed to set hard quota for media_rw");
966     }
967 
968     return ok();
969 }
970 
destroyUserData(const std::unique_ptr<std::string> & uuid,int32_t userId,int32_t flags)971 binder::Status InstalldNativeService::destroyUserData(const std::unique_ptr<std::string>& uuid,
972         int32_t userId, int32_t flags) {
973     ENFORCE_UID(AID_SYSTEM);
974     CHECK_ARGUMENT_UUID(uuid);
975     std::lock_guard<std::recursive_mutex> lock(mLock);
976 
977     const char* uuid_ = uuid ? uuid->c_str() : nullptr;
978     binder::Status res = ok();
979     if (flags & FLAG_STORAGE_DE) {
980         auto path = create_data_user_de_path(uuid_, userId);
981         if (delete_dir_contents_and_dir(path, true) != 0) {
982             res = error("Failed to delete " + path);
983         }
984         if (uuid_ == nullptr) {
985             path = create_data_misc_legacy_path(userId);
986             if (delete_dir_contents_and_dir(path, true) != 0) {
987                 res = error("Failed to delete " + path);
988             }
989             path = create_primary_cur_profile_dir_path(userId);
990             if (delete_dir_contents_and_dir(path, true) != 0) {
991                 res = error("Failed to delete " + path);
992             }
993         }
994     }
995     if (flags & FLAG_STORAGE_CE) {
996         auto path = create_data_user_ce_path(uuid_, userId);
997         if (delete_dir_contents_and_dir(path, true) != 0) {
998             res = error("Failed to delete " + path);
999         }
1000         path = findDataMediaPath(uuid, userId);
1001         if (delete_dir_contents_and_dir(path, true) != 0) {
1002             res = error("Failed to delete " + path);
1003         }
1004     }
1005     return res;
1006 }
1007 
freeCache(const std::unique_ptr<std::string> & uuid,int64_t targetFreeBytes,int64_t cacheReservedBytes,int32_t flags)1008 binder::Status InstalldNativeService::freeCache(const std::unique_ptr<std::string>& uuid,
1009         int64_t targetFreeBytes, int64_t cacheReservedBytes, int32_t flags) {
1010     ENFORCE_UID(AID_SYSTEM);
1011     CHECK_ARGUMENT_UUID(uuid);
1012     std::lock_guard<std::recursive_mutex> lock(mLock);
1013 
1014     const char* uuid_ = uuid ? uuid->c_str() : nullptr;
1015     auto data_path = create_data_path(uuid_);
1016     auto device = findQuotaDeviceForUuid(uuid);
1017     auto noop = (flags & FLAG_FREE_CACHE_NOOP);
1018 
1019     int64_t free = data_disk_free(data_path);
1020     if (free < 0) {
1021         return error("Failed to determine free space for " + data_path);
1022     }
1023 
1024     int64_t cleared = 0;
1025     int64_t needed = targetFreeBytes - free;
1026     LOG(DEBUG) << "Device " << data_path << " has " << free << " free; requested "
1027             << targetFreeBytes << "; needed " << needed;
1028 
1029     if (free >= targetFreeBytes) {
1030         return ok();
1031     }
1032 
1033     if (flags & FLAG_FREE_CACHE_V2) {
1034         // This new cache strategy fairly removes files from UIDs by deleting
1035         // files from the UIDs which are most over their allocated quota
1036 
1037         // 1. Create trackers for every known UID
1038         ATRACE_BEGIN("create");
1039         std::unordered_map<uid_t, std::shared_ptr<CacheTracker>> trackers;
1040         for (auto user : get_known_users(uuid_)) {
1041             FTS *fts;
1042             FTSENT *p;
1043             auto ce_path = create_data_user_ce_path(uuid_, user);
1044             auto de_path = create_data_user_de_path(uuid_, user);
1045             auto media_path = findDataMediaPath(uuid, user) + "/Android/data/";
1046             char *argv[] = { (char*) ce_path.c_str(), (char*) de_path.c_str(),
1047                     (char*) media_path.c_str(), nullptr };
1048             if (!(fts = fts_open(argv, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, NULL))) {
1049                 return error("Failed to fts_open");
1050             }
1051             while ((p = fts_read(fts)) != NULL) {
1052                 if (p->fts_info == FTS_D && p->fts_level == 1) {
1053                     uid_t uid = p->fts_statp->st_uid;
1054                     if (multiuser_get_app_id(uid) == AID_MEDIA_RW) {
1055                         uid = (multiuser_get_app_id(p->fts_statp->st_gid) - AID_EXT_GID_START)
1056                                 + AID_APP_START;
1057                     }
1058                     auto search = trackers.find(uid);
1059                     if (search != trackers.end()) {
1060                         search->second->addDataPath(p->fts_path);
1061                     } else {
1062                         auto tracker = std::shared_ptr<CacheTracker>(new CacheTracker(
1063                                 multiuser_get_user_id(uid), multiuser_get_app_id(uid), device));
1064                         tracker->addDataPath(p->fts_path);
1065                         {
1066                             std::lock_guard<std::recursive_mutex> lock(mQuotasLock);
1067                             tracker->cacheQuota = mCacheQuotas[uid];
1068                         }
1069                         if (tracker->cacheQuota == 0) {
1070 #if MEASURE_DEBUG
1071                             LOG(WARNING) << "UID " << uid << " has no cache quota; assuming 64MB";
1072 #endif
1073                             tracker->cacheQuota = 67108864;
1074                         }
1075                         trackers[uid] = tracker;
1076                     }
1077                     fts_set(fts, p, FTS_SKIP);
1078                 }
1079             }
1080             fts_close(fts);
1081         }
1082         ATRACE_END();
1083 
1084         // 2. Populate tracker stats and insert into priority queue
1085         ATRACE_BEGIN("populate");
1086         int64_t cacheTotal = 0;
1087         auto cmp = [](std::shared_ptr<CacheTracker> left, std::shared_ptr<CacheTracker> right) {
1088             return (left->getCacheRatio() < right->getCacheRatio());
1089         };
1090         std::priority_queue<std::shared_ptr<CacheTracker>,
1091                 std::vector<std::shared_ptr<CacheTracker>>, decltype(cmp)> queue(cmp);
1092         for (const auto& it : trackers) {
1093             it.second->loadStats();
1094             queue.push(it.second);
1095             cacheTotal += it.second->cacheUsed;
1096         }
1097         ATRACE_END();
1098 
1099         // 3. Bounce across the queue, freeing items from whichever tracker is
1100         // the most over their assigned quota
1101         ATRACE_BEGIN("bounce");
1102         std::shared_ptr<CacheTracker> active;
1103         while (active || !queue.empty()) {
1104             // Only look at apps under quota when explicitly requested
1105             if (active && (active->getCacheRatio() < 10000)
1106                     && !(flags & FLAG_FREE_CACHE_V2_DEFY_QUOTA)) {
1107                 LOG(DEBUG) << "Active ratio " << active->getCacheRatio()
1108                         << " isn't over quota, and defy not requested";
1109                 break;
1110             }
1111 
1112             // Only keep clearing when we haven't pushed into reserved area
1113             if (cacheReservedBytes > 0 && cleared >= (cacheTotal - cacheReservedBytes)) {
1114                 LOG(DEBUG) << "Refusing to clear cached data in reserved space";
1115                 break;
1116             }
1117 
1118             // Find the best tracker to work with; this might involve swapping
1119             // if the active tracker is no longer the most over quota
1120             bool nextBetter = active && !queue.empty()
1121                     && active->getCacheRatio() < queue.top()->getCacheRatio();
1122             if (!active || nextBetter) {
1123                 if (active) {
1124                     // Current tracker still has items, so we'll consider it
1125                     // again later once it bubbles up to surface
1126                     queue.push(active);
1127                 }
1128                 active = queue.top(); queue.pop();
1129                 active->ensureItems();
1130                 continue;
1131             }
1132 
1133             // If no items remain, go find another tracker
1134             if (active->items.empty()) {
1135                 active = nullptr;
1136                 continue;
1137             } else {
1138                 auto item = active->items.back();
1139                 active->items.pop_back();
1140 
1141                 LOG(DEBUG) << "Purging " << item->toString() << " from " << active->toString();
1142                 if (!noop) {
1143                     item->purge();
1144                 }
1145                 active->cacheUsed -= item->size;
1146                 needed -= item->size;
1147                 cleared += item->size;
1148             }
1149 
1150             // Verify that we're actually done before bailing, since sneaky
1151             // apps might be using hardlinks
1152             if (needed <= 0) {
1153                 free = data_disk_free(data_path);
1154                 needed = targetFreeBytes - free;
1155                 if (needed <= 0) {
1156                     break;
1157                 } else {
1158                     LOG(WARNING) << "Expected to be done but still need " << needed;
1159                 }
1160             }
1161         }
1162         ATRACE_END();
1163 
1164     } else {
1165         return error("Legacy cache logic no longer supported");
1166     }
1167 
1168     free = data_disk_free(data_path);
1169     if (free >= targetFreeBytes) {
1170         return ok();
1171     } else {
1172         return error(StringPrintf("Failed to free up %" PRId64 " on %s; final free space %" PRId64,
1173                 targetFreeBytes, data_path.c_str(), free));
1174     }
1175 }
1176 
rmdex(const std::string & codePath,const std::string & instructionSet)1177 binder::Status InstalldNativeService::rmdex(const std::string& codePath,
1178         const std::string& instructionSet) {
1179     ENFORCE_UID(AID_SYSTEM);
1180     CHECK_ARGUMENT_PATH(codePath);
1181     std::lock_guard<std::recursive_mutex> lock(mLock);
1182 
1183     char dex_path[PKG_PATH_MAX];
1184 
1185     const char* path = codePath.c_str();
1186     const char* instruction_set = instructionSet.c_str();
1187 
1188     if (validate_apk_path(path) && validate_system_app_path(path)) {
1189         return error("Invalid path " + codePath);
1190     }
1191 
1192     if (!create_cache_path(dex_path, path, instruction_set)) {
1193         return error("Failed to create cache path for " + codePath);
1194     }
1195 
1196     ALOGV("unlink %s\n", dex_path);
1197     if (unlink(dex_path) < 0) {
1198         // It's ok if we don't have a dalvik cache path. Report error only when the path exists
1199         // but could not be unlinked.
1200         if (errno != ENOENT) {
1201             return error(StringPrintf("Failed to unlink %s", dex_path));
1202         }
1203     }
1204     return ok();
1205 }
1206 
1207 struct stats {
1208     int64_t codeSize;
1209     int64_t dataSize;
1210     int64_t cacheSize;
1211 };
1212 
1213 #if MEASURE_DEBUG
toString(std::vector<int64_t> values)1214 static std::string toString(std::vector<int64_t> values) {
1215     std::stringstream res;
1216     res << "[";
1217     for (size_t i = 0; i < values.size(); i++) {
1218         res << values[i];
1219         if (i < values.size() - 1) {
1220             res << ",";
1221         }
1222     }
1223     res << "]";
1224     return res.str();
1225 }
1226 #endif
1227 
collectQuotaStats(const std::string & device,int32_t userId,int32_t appId,struct stats * stats,struct stats * extStats)1228 static void collectQuotaStats(const std::string& device, int32_t userId,
1229         int32_t appId, struct stats* stats, struct stats* extStats) {
1230     if (device.empty()) return;
1231 
1232     struct dqblk dq;
1233 
1234     if (stats != nullptr) {
1235         uid_t uid = multiuser_get_uid(userId, appId);
1236         if (quotactl(QCMD(Q_GETQUOTA, USRQUOTA), device.c_str(), uid,
1237                 reinterpret_cast<char*>(&dq)) != 0) {
1238             if (errno != ESRCH) {
1239                 PLOG(ERROR) << "Failed to quotactl " << device << " for UID " << uid;
1240             }
1241         } else {
1242 #if MEASURE_DEBUG
1243             LOG(DEBUG) << "quotactl() for UID " << uid << " " << dq.dqb_curspace;
1244 #endif
1245             stats->dataSize += dq.dqb_curspace;
1246         }
1247 
1248         int cacheGid = multiuser_get_cache_gid(userId, appId);
1249         if (cacheGid != -1) {
1250             if (quotactl(QCMD(Q_GETQUOTA, GRPQUOTA), device.c_str(), cacheGid,
1251                     reinterpret_cast<char*>(&dq)) != 0) {
1252                 if (errno != ESRCH) {
1253                     PLOG(ERROR) << "Failed to quotactl " << device << " for GID " << cacheGid;
1254                 }
1255             } else {
1256 #if MEASURE_DEBUG
1257                 LOG(DEBUG) << "quotactl() for GID " << cacheGid << " " << dq.dqb_curspace;
1258 #endif
1259                 stats->cacheSize += dq.dqb_curspace;
1260             }
1261         }
1262 
1263         int sharedGid = multiuser_get_shared_gid(0, appId);
1264         if (sharedGid != -1) {
1265             if (quotactl(QCMD(Q_GETQUOTA, GRPQUOTA), device.c_str(), sharedGid,
1266                     reinterpret_cast<char*>(&dq)) != 0) {
1267                 if (errno != ESRCH) {
1268                     PLOG(ERROR) << "Failed to quotactl " << device << " for GID " << sharedGid;
1269                 }
1270             } else {
1271 #if MEASURE_DEBUG
1272                 LOG(DEBUG) << "quotactl() for GID " << sharedGid << " " << dq.dqb_curspace;
1273 #endif
1274                 stats->codeSize += dq.dqb_curspace;
1275             }
1276         }
1277     }
1278 
1279     if (extStats != nullptr) {
1280         int extGid = multiuser_get_ext_gid(userId, appId);
1281         if (extGid != -1) {
1282             if (quotactl(QCMD(Q_GETQUOTA, GRPQUOTA), device.c_str(), extGid,
1283                     reinterpret_cast<char*>(&dq)) != 0) {
1284                 if (errno != ESRCH) {
1285                     PLOG(ERROR) << "Failed to quotactl " << device << " for GID " << extGid;
1286                 }
1287             } else {
1288 #if MEASURE_DEBUG
1289                 LOG(DEBUG) << "quotactl() for GID " << extGid << " " << dq.dqb_curspace;
1290 #endif
1291                 extStats->dataSize += dq.dqb_curspace;
1292             }
1293         }
1294 
1295         int extCacheGid = multiuser_get_ext_cache_gid(userId, appId);
1296         if (extCacheGid != -1) {
1297             if (quotactl(QCMD(Q_GETQUOTA, GRPQUOTA), device.c_str(), extCacheGid,
1298                     reinterpret_cast<char*>(&dq)) != 0) {
1299                 if (errno != ESRCH) {
1300                     PLOG(ERROR) << "Failed to quotactl " << device << " for GID " << extCacheGid;
1301                 }
1302             } else {
1303 #if MEASURE_DEBUG
1304                 LOG(DEBUG) << "quotactl() for GID " << extCacheGid << " " << dq.dqb_curspace;
1305 #endif
1306                 extStats->dataSize += dq.dqb_curspace;
1307                 extStats->cacheSize += dq.dqb_curspace;
1308             }
1309         }
1310     }
1311 }
1312 
collectManualStats(const std::string & path,struct stats * stats)1313 static void collectManualStats(const std::string& path, struct stats* stats) {
1314     DIR *d;
1315     int dfd;
1316     struct dirent *de;
1317     struct stat s;
1318 
1319     d = opendir(path.c_str());
1320     if (d == nullptr) {
1321         if (errno != ENOENT) {
1322             PLOG(WARNING) << "Failed to open " << path;
1323         }
1324         return;
1325     }
1326     dfd = dirfd(d);
1327     while ((de = readdir(d))) {
1328         const char *name = de->d_name;
1329 
1330         int64_t size = 0;
1331         if (fstatat(dfd, name, &s, AT_SYMLINK_NOFOLLOW) == 0) {
1332             size = s.st_blocks * 512;
1333         }
1334 
1335         if (de->d_type == DT_DIR) {
1336             if (!strcmp(name, ".")) {
1337                 // Don't recurse, but still count node size
1338             } else if (!strcmp(name, "..")) {
1339                 // Don't recurse or count node size
1340                 continue;
1341             } else {
1342                 // Measure all children nodes
1343                 size = 0;
1344                 calculate_tree_size(StringPrintf("%s/%s", path.c_str(), name), &size);
1345             }
1346 
1347             if (!strcmp(name, "cache") || !strcmp(name, "code_cache")) {
1348                 stats->cacheSize += size;
1349             }
1350         }
1351 
1352         // Legacy symlink isn't owned by app
1353         if (de->d_type == DT_LNK && !strcmp(name, "lib")) {
1354             continue;
1355         }
1356 
1357         // Everything found inside is considered data
1358         stats->dataSize += size;
1359     }
1360     closedir(d);
1361 }
1362 
collectManualStatsForUser(const std::string & path,struct stats * stats,bool exclude_apps=false)1363 static void collectManualStatsForUser(const std::string& path, struct stats* stats,
1364         bool exclude_apps = false) {
1365     DIR *d;
1366     int dfd;
1367     struct dirent *de;
1368     struct stat s;
1369 
1370     d = opendir(path.c_str());
1371     if (d == nullptr) {
1372         if (errno != ENOENT) {
1373             PLOG(WARNING) << "Failed to open " << path;
1374         }
1375         return;
1376     }
1377     dfd = dirfd(d);
1378     while ((de = readdir(d))) {
1379         if (de->d_type == DT_DIR) {
1380             const char *name = de->d_name;
1381             if (fstatat(dfd, name, &s, AT_SYMLINK_NOFOLLOW) != 0) {
1382                 continue;
1383             }
1384             int32_t user_uid = multiuser_get_app_id(s.st_uid);
1385             if (!strcmp(name, ".") || !strcmp(name, "..")) {
1386                 continue;
1387             } else if (exclude_apps && (user_uid >= AID_APP_START && user_uid <= AID_APP_END)) {
1388                 continue;
1389             } else {
1390                 collectManualStats(StringPrintf("%s/%s", path.c_str(), name), stats);
1391             }
1392         }
1393     }
1394     closedir(d);
1395 }
1396 
collectManualExternalStatsForUser(const std::string & path,struct stats * stats)1397 static void collectManualExternalStatsForUser(const std::string& path, struct stats* stats) {
1398     FTS *fts;
1399     FTSENT *p;
1400     char *argv[] = { (char*) path.c_str(), nullptr };
1401     if (!(fts = fts_open(argv, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, NULL))) {
1402         PLOG(ERROR) << "Failed to fts_open " << path;
1403         return;
1404     }
1405     while ((p = fts_read(fts)) != NULL) {
1406         p->fts_number = p->fts_parent->fts_number;
1407         switch (p->fts_info) {
1408         case FTS_D:
1409             if (p->fts_level == 4
1410                     && !strcmp(p->fts_name, "cache")
1411                     && !strcmp(p->fts_parent->fts_parent->fts_name, "data")
1412                     && !strcmp(p->fts_parent->fts_parent->fts_parent->fts_name, "Android")) {
1413                 p->fts_number = 1;
1414             }
1415             // Fall through to count the directory
1416         case FTS_DEFAULT:
1417         case FTS_F:
1418         case FTS_SL:
1419         case FTS_SLNONE:
1420             int64_t size = (p->fts_statp->st_blocks * 512);
1421             if (p->fts_number == 1) {
1422                 stats->cacheSize += size;
1423             }
1424             stats->dataSize += size;
1425             break;
1426         }
1427     }
1428     fts_close(fts);
1429 }
1430 
getAppSize(const std::unique_ptr<std::string> & uuid,const std::vector<std::string> & packageNames,int32_t userId,int32_t flags,int32_t appId,const std::vector<int64_t> & ceDataInodes,const std::vector<std::string> & codePaths,std::vector<int64_t> * _aidl_return)1431 binder::Status InstalldNativeService::getAppSize(const std::unique_ptr<std::string>& uuid,
1432         const std::vector<std::string>& packageNames, int32_t userId, int32_t flags,
1433         int32_t appId, const std::vector<int64_t>& ceDataInodes,
1434         const std::vector<std::string>& codePaths, std::vector<int64_t>* _aidl_return) {
1435     ENFORCE_UID(AID_SYSTEM);
1436     CHECK_ARGUMENT_UUID(uuid);
1437     for (const auto& packageName : packageNames) {
1438         CHECK_ARGUMENT_PACKAGE_NAME(packageName);
1439     }
1440     for (const auto& codePath : codePaths) {
1441         CHECK_ARGUMENT_PATH(codePath);
1442     }
1443     // NOTE: Locking is relaxed on this method, since it's limited to
1444     // read-only measurements without mutation.
1445 
1446     // When modifying this logic, always verify using tests:
1447     // runtest -x frameworks/base/services/tests/servicestests/src/com/android/server/pm/InstallerTest.java -m testGetAppSize
1448 
1449 #if MEASURE_DEBUG
1450     LOG(INFO) << "Measuring user " << userId << " app " << appId;
1451 #endif
1452 
1453     // Here's a summary of the common storage locations across the platform,
1454     // and how they're each tagged:
1455     //
1456     // /data/app/com.example                           UID system
1457     // /data/app/com.example/oat                       UID system
1458     // /data/user/0/com.example                        UID u0_a10      GID u0_a10
1459     // /data/user/0/com.example/cache                  UID u0_a10      GID u0_a10_cache
1460     // /data/media/0/foo.txt                           UID u0_media_rw
1461     // /data/media/0/bar.jpg                           UID u0_media_rw GID u0_media_image
1462     // /data/media/0/Android/data/com.example          UID u0_media_rw GID u0_a10_ext
1463     // /data/media/0/Android/data/com.example/cache    UID u0_media_rw GID u0_a10_ext_cache
1464     // /data/media/obb/com.example                     UID system
1465 
1466     struct stats stats;
1467     struct stats extStats;
1468     memset(&stats, 0, sizeof(stats));
1469     memset(&extStats, 0, sizeof(extStats));
1470 
1471     const char* uuid_ = uuid ? uuid->c_str() : nullptr;
1472 
1473     auto device = findQuotaDeviceForUuid(uuid);
1474     if (device.empty()) {
1475         flags &= ~FLAG_USE_QUOTA;
1476     }
1477 
1478     ATRACE_BEGIN("obb");
1479     for (const auto& packageName : packageNames) {
1480         auto obbCodePath = create_data_media_obb_path(uuid_, packageName.c_str());
1481         calculate_tree_size(obbCodePath, &extStats.codeSize);
1482     }
1483     ATRACE_END();
1484 
1485     if (flags & FLAG_USE_QUOTA && appId >= AID_APP_START) {
1486         ATRACE_BEGIN("code");
1487         for (const auto& codePath : codePaths) {
1488             calculate_tree_size(codePath, &stats.codeSize, -1,
1489                     multiuser_get_shared_gid(0, appId));
1490         }
1491         ATRACE_END();
1492 
1493         ATRACE_BEGIN("quota");
1494         collectQuotaStats(device, userId, appId, &stats, &extStats);
1495         ATRACE_END();
1496     } else {
1497         ATRACE_BEGIN("code");
1498         for (const auto& codePath : codePaths) {
1499             calculate_tree_size(codePath, &stats.codeSize);
1500         }
1501         ATRACE_END();
1502 
1503         for (size_t i = 0; i < packageNames.size(); i++) {
1504             const char* pkgname = packageNames[i].c_str();
1505 
1506             ATRACE_BEGIN("data");
1507             auto cePath = create_data_user_ce_package_path(uuid_, userId, pkgname, ceDataInodes[i]);
1508             collectManualStats(cePath, &stats);
1509             auto dePath = create_data_user_de_package_path(uuid_, userId, pkgname);
1510             collectManualStats(dePath, &stats);
1511             ATRACE_END();
1512 
1513             if (!uuid) {
1514                 ATRACE_BEGIN("profiles");
1515                 calculate_tree_size(
1516                         create_primary_current_profile_package_dir_path(userId, pkgname),
1517                         &stats.dataSize);
1518                 calculate_tree_size(
1519                         create_primary_reference_profile_package_dir_path(pkgname),
1520                         &stats.codeSize);
1521                 ATRACE_END();
1522             }
1523 
1524             ATRACE_BEGIN("external");
1525             auto extPath = create_data_media_package_path(uuid_, userId, "data", pkgname);
1526             collectManualStats(extPath, &extStats);
1527             auto mediaPath = create_data_media_package_path(uuid_, userId, "media", pkgname);
1528             calculate_tree_size(mediaPath, &extStats.dataSize);
1529             ATRACE_END();
1530         }
1531 
1532         if (!uuid) {
1533             ATRACE_BEGIN("dalvik");
1534             int32_t sharedGid = multiuser_get_shared_gid(0, appId);
1535             if (sharedGid != -1) {
1536                 calculate_tree_size(create_data_dalvik_cache_path(), &stats.codeSize,
1537                         sharedGid, -1);
1538             }
1539             ATRACE_END();
1540         }
1541     }
1542 
1543     std::vector<int64_t> ret;
1544     ret.push_back(stats.codeSize);
1545     ret.push_back(stats.dataSize);
1546     ret.push_back(stats.cacheSize);
1547     ret.push_back(extStats.codeSize);
1548     ret.push_back(extStats.dataSize);
1549     ret.push_back(extStats.cacheSize);
1550 #if MEASURE_DEBUG
1551     LOG(DEBUG) << "Final result " << toString(ret);
1552 #endif
1553     *_aidl_return = ret;
1554     return ok();
1555 }
1556 
getUserSize(const std::unique_ptr<std::string> & uuid,int32_t userId,int32_t flags,const std::vector<int32_t> & appIds,std::vector<int64_t> * _aidl_return)1557 binder::Status InstalldNativeService::getUserSize(const std::unique_ptr<std::string>& uuid,
1558         int32_t userId, int32_t flags, const std::vector<int32_t>& appIds,
1559         std::vector<int64_t>* _aidl_return) {
1560     ENFORCE_UID(AID_SYSTEM);
1561     CHECK_ARGUMENT_UUID(uuid);
1562     // NOTE: Locking is relaxed on this method, since it's limited to
1563     // read-only measurements without mutation.
1564 
1565     // When modifying this logic, always verify using tests:
1566     // runtest -x frameworks/base/services/tests/servicestests/src/com/android/server/pm/InstallerTest.java -m testGetUserSize
1567 
1568 #if MEASURE_DEBUG
1569     LOG(INFO) << "Measuring user " << userId;
1570 #endif
1571 
1572     struct stats stats;
1573     struct stats extStats;
1574     memset(&stats, 0, sizeof(stats));
1575     memset(&extStats, 0, sizeof(extStats));
1576 
1577     const char* uuid_ = uuid ? uuid->c_str() : nullptr;
1578 
1579     auto device = findQuotaDeviceForUuid(uuid);
1580     if (device.empty()) {
1581         flags &= ~FLAG_USE_QUOTA;
1582     }
1583 
1584     if (flags & FLAG_USE_QUOTA) {
1585         struct dqblk dq;
1586 
1587         ATRACE_BEGIN("obb");
1588         if (quotactl(QCMD(Q_GETQUOTA, GRPQUOTA), device.c_str(), AID_MEDIA_OBB,
1589                 reinterpret_cast<char*>(&dq)) != 0) {
1590             if (errno != ESRCH) {
1591                 PLOG(ERROR) << "Failed to quotactl " << device << " for GID " << AID_MEDIA_OBB;
1592             }
1593         } else {
1594 #if MEASURE_DEBUG
1595             LOG(DEBUG) << "quotactl() for GID " << AID_MEDIA_OBB << " " << dq.dqb_curspace;
1596 #endif
1597             extStats.codeSize += dq.dqb_curspace;
1598         }
1599         ATRACE_END();
1600 
1601         ATRACE_BEGIN("code");
1602         calculate_tree_size(create_data_app_path(uuid_), &stats.codeSize, -1, -1, true);
1603         ATRACE_END();
1604 
1605         ATRACE_BEGIN("data");
1606         auto cePath = create_data_user_ce_path(uuid_, userId);
1607         collectManualStatsForUser(cePath, &stats, true);
1608         auto dePath = create_data_user_de_path(uuid_, userId);
1609         collectManualStatsForUser(dePath, &stats, true);
1610         ATRACE_END();
1611 
1612         if (!uuid) {
1613             ATRACE_BEGIN("profile");
1614             auto userProfilePath = create_primary_cur_profile_dir_path(userId);
1615             calculate_tree_size(userProfilePath, &stats.dataSize, -1, -1, true);
1616             auto refProfilePath = create_primary_ref_profile_dir_path();
1617             calculate_tree_size(refProfilePath, &stats.codeSize, -1, -1, true);
1618             ATRACE_END();
1619         }
1620 
1621         ATRACE_BEGIN("external");
1622         uid_t uid = multiuser_get_uid(userId, AID_MEDIA_RW);
1623         if (quotactl(QCMD(Q_GETQUOTA, USRQUOTA), device.c_str(), uid,
1624                 reinterpret_cast<char*>(&dq)) != 0) {
1625             if (errno != ESRCH) {
1626                 PLOG(ERROR) << "Failed to quotactl " << device << " for UID " << uid;
1627             }
1628         } else {
1629 #if MEASURE_DEBUG
1630             LOG(DEBUG) << "quotactl() for UID " << uid << " " << dq.dqb_curspace;
1631 #endif
1632             extStats.dataSize += dq.dqb_curspace;
1633         }
1634         ATRACE_END();
1635 
1636         if (!uuid) {
1637             ATRACE_BEGIN("dalvik");
1638             calculate_tree_size(create_data_dalvik_cache_path(), &stats.codeSize,
1639                     -1, -1, true);
1640             calculate_tree_size(create_primary_cur_profile_dir_path(userId), &stats.dataSize,
1641                     -1, -1, true);
1642             ATRACE_END();
1643         }
1644 
1645         ATRACE_BEGIN("quota");
1646         int64_t dataSize = extStats.dataSize;
1647         for (auto appId : appIds) {
1648             if (appId >= AID_APP_START) {
1649                 collectQuotaStats(device, userId, appId, &stats, &extStats);
1650 
1651 #if MEASURE_DEBUG
1652                 // Sleep to make sure we don't lose logs
1653                 usleep(1);
1654 #endif
1655             }
1656         }
1657         extStats.dataSize = dataSize;
1658         ATRACE_END();
1659     } else {
1660         ATRACE_BEGIN("obb");
1661         auto obbPath = create_data_path(uuid_) + "/media/obb";
1662         calculate_tree_size(obbPath, &extStats.codeSize);
1663         ATRACE_END();
1664 
1665         ATRACE_BEGIN("code");
1666         calculate_tree_size(create_data_app_path(uuid_), &stats.codeSize);
1667         ATRACE_END();
1668 
1669         ATRACE_BEGIN("data");
1670         auto cePath = create_data_user_ce_path(uuid_, userId);
1671         collectManualStatsForUser(cePath, &stats);
1672         auto dePath = create_data_user_de_path(uuid_, userId);
1673         collectManualStatsForUser(dePath, &stats);
1674         ATRACE_END();
1675 
1676         if (!uuid) {
1677             ATRACE_BEGIN("profile");
1678             auto userProfilePath = create_primary_cur_profile_dir_path(userId);
1679             calculate_tree_size(userProfilePath, &stats.dataSize);
1680             auto refProfilePath = create_primary_ref_profile_dir_path();
1681             calculate_tree_size(refProfilePath, &stats.codeSize);
1682             ATRACE_END();
1683         }
1684 
1685         ATRACE_BEGIN("external");
1686         auto dataMediaPath = create_data_media_path(uuid_, userId);
1687         collectManualExternalStatsForUser(dataMediaPath, &extStats);
1688 #if MEASURE_DEBUG
1689         LOG(DEBUG) << "Measured external data " << extStats.dataSize << " cache "
1690                 << extStats.cacheSize;
1691 #endif
1692         ATRACE_END();
1693 
1694         if (!uuid) {
1695             ATRACE_BEGIN("dalvik");
1696             calculate_tree_size(create_data_dalvik_cache_path(), &stats.codeSize);
1697             calculate_tree_size(create_primary_cur_profile_dir_path(userId), &stats.dataSize);
1698             ATRACE_END();
1699         }
1700     }
1701 
1702     std::vector<int64_t> ret;
1703     ret.push_back(stats.codeSize);
1704     ret.push_back(stats.dataSize);
1705     ret.push_back(stats.cacheSize);
1706     ret.push_back(extStats.codeSize);
1707     ret.push_back(extStats.dataSize);
1708     ret.push_back(extStats.cacheSize);
1709 #if MEASURE_DEBUG
1710     LOG(DEBUG) << "Final result " << toString(ret);
1711 #endif
1712     *_aidl_return = ret;
1713     return ok();
1714 }
1715 
getExternalSize(const std::unique_ptr<std::string> & uuid,int32_t userId,int32_t flags,const std::vector<int32_t> & appIds,std::vector<int64_t> * _aidl_return)1716 binder::Status InstalldNativeService::getExternalSize(const std::unique_ptr<std::string>& uuid,
1717         int32_t userId, int32_t flags, const std::vector<int32_t>& appIds,
1718         std::vector<int64_t>* _aidl_return) {
1719     ENFORCE_UID(AID_SYSTEM);
1720     CHECK_ARGUMENT_UUID(uuid);
1721     // NOTE: Locking is relaxed on this method, since it's limited to
1722     // read-only measurements without mutation.
1723 
1724     // When modifying this logic, always verify using tests:
1725     // runtest -x frameworks/base/services/tests/servicestests/src/com/android/server/pm/InstallerTest.java -m testGetExternalSize
1726 
1727 #if MEASURE_DEBUG
1728     LOG(INFO) << "Measuring external " << userId;
1729 #endif
1730 
1731     const char* uuid_ = uuid ? uuid->c_str() : nullptr;
1732 
1733     int64_t totalSize = 0;
1734     int64_t audioSize = 0;
1735     int64_t videoSize = 0;
1736     int64_t imageSize = 0;
1737     int64_t appSize = 0;
1738     int64_t obbSize = 0;
1739 
1740     auto device = findQuotaDeviceForUuid(uuid);
1741     if (device.empty()) {
1742         flags &= ~FLAG_USE_QUOTA;
1743     }
1744 
1745     if (flags & FLAG_USE_QUOTA) {
1746         struct dqblk dq;
1747 
1748         ATRACE_BEGIN("quota");
1749         uid_t uid = multiuser_get_uid(userId, AID_MEDIA_RW);
1750         if (quotactl(QCMD(Q_GETQUOTA, USRQUOTA), device.c_str(), uid,
1751                 reinterpret_cast<char*>(&dq)) != 0) {
1752             if (errno != ESRCH) {
1753                 PLOG(ERROR) << "Failed to quotactl " << device << " for UID " << uid;
1754             }
1755         } else {
1756 #if MEASURE_DEBUG
1757             LOG(DEBUG) << "quotactl() for UID " << uid << " " << dq.dqb_curspace;
1758 #endif
1759             totalSize = dq.dqb_curspace;
1760         }
1761 
1762         gid_t audioGid = multiuser_get_uid(userId, AID_MEDIA_AUDIO);
1763         if (quotactl(QCMD(Q_GETQUOTA, GRPQUOTA), device.c_str(), audioGid,
1764                 reinterpret_cast<char*>(&dq)) == 0) {
1765 #if MEASURE_DEBUG
1766             LOG(DEBUG) << "quotactl() for GID " << audioGid << " " << dq.dqb_curspace;
1767 #endif
1768             audioSize = dq.dqb_curspace;
1769         }
1770         gid_t videoGid = multiuser_get_uid(userId, AID_MEDIA_VIDEO);
1771         if (quotactl(QCMD(Q_GETQUOTA, GRPQUOTA), device.c_str(), videoGid,
1772                 reinterpret_cast<char*>(&dq)) == 0) {
1773 #if MEASURE_DEBUG
1774             LOG(DEBUG) << "quotactl() for GID " << videoGid << " " << dq.dqb_curspace;
1775 #endif
1776             videoSize = dq.dqb_curspace;
1777         }
1778         gid_t imageGid = multiuser_get_uid(userId, AID_MEDIA_IMAGE);
1779         if (quotactl(QCMD(Q_GETQUOTA, GRPQUOTA), device.c_str(), imageGid,
1780                 reinterpret_cast<char*>(&dq)) == 0) {
1781 #if MEASURE_DEBUG
1782             LOG(DEBUG) << "quotactl() for GID " << imageGid << " " << dq.dqb_curspace;
1783 #endif
1784             imageSize = dq.dqb_curspace;
1785         }
1786         if (quotactl(QCMD(Q_GETQUOTA, GRPQUOTA), device.c_str(), AID_MEDIA_OBB,
1787                 reinterpret_cast<char*>(&dq)) == 0) {
1788 #if MEASURE_DEBUG
1789             LOG(DEBUG) << "quotactl() for GID " << AID_MEDIA_OBB << " " << dq.dqb_curspace;
1790 #endif
1791             obbSize = dq.dqb_curspace;
1792         }
1793         ATRACE_END();
1794 
1795         ATRACE_BEGIN("apps");
1796         struct stats extStats;
1797         memset(&extStats, 0, sizeof(extStats));
1798         for (auto appId : appIds) {
1799             if (appId >= AID_APP_START) {
1800                 collectQuotaStats(device, userId, appId, nullptr, &extStats);
1801             }
1802         }
1803         appSize = extStats.dataSize;
1804         ATRACE_END();
1805     } else {
1806         ATRACE_BEGIN("manual");
1807         FTS *fts;
1808         FTSENT *p;
1809         auto path = create_data_media_path(uuid_, userId);
1810         char *argv[] = { (char*) path.c_str(), nullptr };
1811         if (!(fts = fts_open(argv, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, NULL))) {
1812             return error("Failed to fts_open " + path);
1813         }
1814         while ((p = fts_read(fts)) != NULL) {
1815             char* ext;
1816             int64_t size = (p->fts_statp->st_blocks * 512);
1817             switch (p->fts_info) {
1818             case FTS_F:
1819                 // Only categorize files not belonging to apps
1820                 if (p->fts_parent->fts_number == 0) {
1821                     ext = strrchr(p->fts_name, '.');
1822                     if (ext != nullptr) {
1823                         switch (MatchExtension(++ext)) {
1824                         case AID_MEDIA_AUDIO: audioSize += size; break;
1825                         case AID_MEDIA_VIDEO: videoSize += size; break;
1826                         case AID_MEDIA_IMAGE: imageSize += size; break;
1827                         }
1828                     }
1829                 }
1830                 // Fall through to always count against total
1831             case FTS_D:
1832                 // Ignore data belonging to specific apps
1833                 p->fts_number = p->fts_parent->fts_number;
1834                 if (p->fts_level == 1 && !strcmp(p->fts_name, "Android")) {
1835                     p->fts_number = 1;
1836                 }
1837             case FTS_DEFAULT:
1838             case FTS_SL:
1839             case FTS_SLNONE:
1840                 if (p->fts_parent->fts_number == 1) {
1841                     appSize += size;
1842                 }
1843                 totalSize += size;
1844                 break;
1845             }
1846         }
1847         fts_close(fts);
1848         ATRACE_END();
1849 
1850         ATRACE_BEGIN("obb");
1851         auto obbPath = create_data_media_obb_path(uuid_, "");
1852         calculate_tree_size(obbPath, &obbSize);
1853         ATRACE_END();
1854     }
1855 
1856     std::vector<int64_t> ret;
1857     ret.push_back(totalSize);
1858     ret.push_back(audioSize);
1859     ret.push_back(videoSize);
1860     ret.push_back(imageSize);
1861     ret.push_back(appSize);
1862     ret.push_back(obbSize);
1863 #if MEASURE_DEBUG
1864     LOG(DEBUG) << "Final result " << toString(ret);
1865 #endif
1866     *_aidl_return = ret;
1867     return ok();
1868 }
1869 
setAppQuota(const std::unique_ptr<std::string> & uuid,int32_t userId,int32_t appId,int64_t cacheQuota)1870 binder::Status InstalldNativeService::setAppQuota(const std::unique_ptr<std::string>& uuid,
1871         int32_t userId, int32_t appId, int64_t cacheQuota) {
1872     ENFORCE_UID(AID_SYSTEM);
1873     CHECK_ARGUMENT_UUID(uuid);
1874     std::lock_guard<std::recursive_mutex> lock(mQuotasLock);
1875 
1876     int32_t uid = multiuser_get_uid(userId, appId);
1877     mCacheQuotas[uid] = cacheQuota;
1878 
1879     return ok();
1880 }
1881 
1882 // Dumps the contents of a profile file, using pkgname's dex files for pretty
1883 // printing the result.
dumpProfiles(int32_t uid,const std::string & packageName,const std::string & profileName,const std::string & codePath,bool * _aidl_return)1884 binder::Status InstalldNativeService::dumpProfiles(int32_t uid, const std::string& packageName,
1885         const std::string& profileName, const std::string& codePath, bool* _aidl_return) {
1886     ENFORCE_UID(AID_SYSTEM);
1887     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
1888     CHECK_ARGUMENT_PATH(codePath);
1889     std::lock_guard<std::recursive_mutex> lock(mLock);
1890 
1891     *_aidl_return = dump_profiles(uid, packageName, profileName, codePath);
1892     return ok();
1893 }
1894 
1895 // Copy the contents of a system profile over the data profile.
copySystemProfile(const std::string & systemProfile,int32_t packageUid,const std::string & packageName,const std::string & profileName,bool * _aidl_return)1896 binder::Status InstalldNativeService::copySystemProfile(const std::string& systemProfile,
1897         int32_t packageUid, const std::string& packageName, const std::string& profileName,
1898         bool* _aidl_return) {
1899     ENFORCE_UID(AID_SYSTEM);
1900     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
1901     std::lock_guard<std::recursive_mutex> lock(mLock);
1902     *_aidl_return = copy_system_profile(systemProfile, packageUid, packageName, profileName);
1903     return ok();
1904 }
1905 
1906 // TODO: Consider returning error codes.
mergeProfiles(int32_t uid,const std::string & packageName,const std::string & profileName,bool * _aidl_return)1907 binder::Status InstalldNativeService::mergeProfiles(int32_t uid, const std::string& packageName,
1908         const std::string& profileName, bool* _aidl_return) {
1909     ENFORCE_UID(AID_SYSTEM);
1910     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
1911     std::lock_guard<std::recursive_mutex> lock(mLock);
1912 
1913     *_aidl_return = analyze_primary_profiles(uid, packageName, profileName);
1914     return ok();
1915 }
1916 
createProfileSnapshot(int32_t appId,const std::string & packageName,const std::string & profileName,const std::string & classpath,bool * _aidl_return)1917 binder::Status InstalldNativeService::createProfileSnapshot(int32_t appId,
1918         const std::string& packageName, const std::string& profileName,
1919         const std::string& classpath, bool* _aidl_return) {
1920     ENFORCE_UID(AID_SYSTEM);
1921     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
1922     std::lock_guard<std::recursive_mutex> lock(mLock);
1923 
1924     *_aidl_return = create_profile_snapshot(appId, packageName, profileName, classpath);
1925     return ok();
1926 }
1927 
destroyProfileSnapshot(const std::string & packageName,const std::string & profileName)1928 binder::Status InstalldNativeService::destroyProfileSnapshot(const std::string& packageName,
1929         const std::string& profileName) {
1930     ENFORCE_UID(AID_SYSTEM);
1931     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
1932     std::lock_guard<std::recursive_mutex> lock(mLock);
1933 
1934     std::string snapshot = create_snapshot_profile_path(packageName, profileName);
1935     if ((unlink(snapshot.c_str()) != 0) && (errno != ENOENT)) {
1936         return error("Failed to destroy profile snapshot for " + packageName + ":" + profileName);
1937     }
1938     return ok();
1939 }
1940 
getCStr(const std::unique_ptr<std::string> & data,const char * default_value=nullptr)1941 static const char* getCStr(const std::unique_ptr<std::string>& data,
1942         const char* default_value = nullptr) {
1943     return data == nullptr ? default_value : data->c_str();
1944 }
dexopt(const std::string & apkPath,int32_t uid,const std::unique_ptr<std::string> & packageName,const std::string & instructionSet,int32_t dexoptNeeded,const std::unique_ptr<std::string> & outputPath,int32_t dexFlags,const std::string & compilerFilter,const std::unique_ptr<std::string> & uuid,const std::unique_ptr<std::string> & classLoaderContext,const std::unique_ptr<std::string> & seInfo,bool downgrade,int32_t targetSdkVersion,const std::unique_ptr<std::string> & profileName,const std::unique_ptr<std::string> & dexMetadataPath,const std::unique_ptr<std::string> & compilationReason)1945 binder::Status InstalldNativeService::dexopt(const std::string& apkPath, int32_t uid,
1946         const std::unique_ptr<std::string>& packageName, const std::string& instructionSet,
1947         int32_t dexoptNeeded, const std::unique_ptr<std::string>& outputPath, int32_t dexFlags,
1948         const std::string& compilerFilter, const std::unique_ptr<std::string>& uuid,
1949         const std::unique_ptr<std::string>& classLoaderContext,
1950         const std::unique_ptr<std::string>& seInfo, bool downgrade, int32_t targetSdkVersion,
1951         const std::unique_ptr<std::string>& profileName,
1952         const std::unique_ptr<std::string>& dexMetadataPath,
1953         const std::unique_ptr<std::string>& compilationReason) {
1954     ENFORCE_UID(AID_SYSTEM);
1955     CHECK_ARGUMENT_UUID(uuid);
1956     CHECK_ARGUMENT_PATH(apkPath);
1957     if (packageName && *packageName != "*") {
1958         CHECK_ARGUMENT_PACKAGE_NAME(*packageName);
1959     }
1960     CHECK_ARGUMENT_PATH(outputPath);
1961     CHECK_ARGUMENT_PATH(dexMetadataPath);
1962     std::lock_guard<std::recursive_mutex> lock(mLock);
1963 
1964     const char* apk_path = apkPath.c_str();
1965     const char* pkgname = getCStr(packageName, "*");
1966     const char* instruction_set = instructionSet.c_str();
1967     const char* oat_dir = getCStr(outputPath);
1968     const char* compiler_filter = compilerFilter.c_str();
1969     const char* volume_uuid = getCStr(uuid);
1970     const char* class_loader_context = getCStr(classLoaderContext);
1971     const char* se_info = getCStr(seInfo);
1972     const char* profile_name = getCStr(profileName);
1973     const char* dm_path = getCStr(dexMetadataPath);
1974     const char* compilation_reason = getCStr(compilationReason);
1975     std::string error_msg;
1976     int res = android::installd::dexopt(apk_path, uid, pkgname, instruction_set, dexoptNeeded,
1977             oat_dir, dexFlags, compiler_filter, volume_uuid, class_loader_context, se_info,
1978             downgrade, targetSdkVersion, profile_name, dm_path, compilation_reason, &error_msg);
1979     return res ? error(res, error_msg) : ok();
1980 }
1981 
markBootComplete(const std::string & instructionSet)1982 binder::Status InstalldNativeService::markBootComplete(const std::string& instructionSet) {
1983     ENFORCE_UID(AID_SYSTEM);
1984     std::lock_guard<std::recursive_mutex> lock(mLock);
1985 
1986     const char* instruction_set = instructionSet.c_str();
1987 
1988     char boot_marker_path[PKG_PATH_MAX];
1989     sprintf(boot_marker_path,
1990           "%s/%s/%s/.booting",
1991           android_data_dir.c_str(),
1992           DALVIK_CACHE,
1993           instruction_set);
1994 
1995     ALOGV("mark_boot_complete : %s", boot_marker_path);
1996     if (unlink(boot_marker_path) != 0) {
1997         return error(StringPrintf("Failed to unlink %s", boot_marker_path));
1998     }
1999     return ok();
2000 }
2001 
linkNativeLibraryDirectory(const std::unique_ptr<std::string> & uuid,const std::string & packageName,const std::string & nativeLibPath32,int32_t userId)2002 binder::Status InstalldNativeService::linkNativeLibraryDirectory(
2003         const std::unique_ptr<std::string>& uuid, const std::string& packageName,
2004         const std::string& nativeLibPath32, int32_t userId) {
2005     ENFORCE_UID(AID_SYSTEM);
2006     CHECK_ARGUMENT_UUID(uuid);
2007     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
2008     CHECK_ARGUMENT_PATH(nativeLibPath32);
2009     std::lock_guard<std::recursive_mutex> lock(mLock);
2010 
2011     const char* uuid_ = uuid ? uuid->c_str() : nullptr;
2012     const char* pkgname = packageName.c_str();
2013     const char* asecLibDir = nativeLibPath32.c_str();
2014     struct stat s, libStat;
2015     binder::Status res = ok();
2016 
2017     auto _pkgdir = create_data_user_ce_package_path(uuid_, userId, pkgname);
2018     auto _libsymlink = _pkgdir + PKG_LIB_POSTFIX;
2019 
2020     const char* pkgdir = _pkgdir.c_str();
2021     const char* libsymlink = _libsymlink.c_str();
2022 
2023     if (stat(pkgdir, &s) < 0) {
2024         return error("Failed to stat " + _pkgdir);
2025     }
2026 
2027     if (chown(pkgdir, AID_INSTALL, AID_INSTALL) < 0) {
2028         return error("Failed to chown " + _pkgdir);
2029     }
2030 
2031     if (chmod(pkgdir, 0700) < 0) {
2032         res = error("Failed to chmod " + _pkgdir);
2033         goto out;
2034     }
2035 
2036     if (lstat(libsymlink, &libStat) < 0) {
2037         if (errno != ENOENT) {
2038             res = error("Failed to stat " + _libsymlink);
2039             goto out;
2040         }
2041     } else {
2042         if (S_ISDIR(libStat.st_mode)) {
2043             if (delete_dir_contents(libsymlink, 1, NULL) < 0) {
2044                 res = error("Failed to delete " + _libsymlink);
2045                 goto out;
2046             }
2047         } else if (S_ISLNK(libStat.st_mode)) {
2048             if (unlink(libsymlink) < 0) {
2049                 res = error("Failed to unlink " + _libsymlink);
2050                 goto out;
2051             }
2052         }
2053     }
2054 
2055     if (symlink(asecLibDir, libsymlink) < 0) {
2056         res = error("Failed to symlink " + _libsymlink + " to " + nativeLibPath32);
2057         goto out;
2058     }
2059 
2060 out:
2061     if (chmod(pkgdir, s.st_mode) < 0) {
2062         auto msg = "Failed to cleanup chmod " + _pkgdir;
2063         if (res.isOk()) {
2064             res = error(msg);
2065         } else {
2066             PLOG(ERROR) << msg;
2067         }
2068     }
2069 
2070     if (chown(pkgdir, s.st_uid, s.st_gid) < 0) {
2071         auto msg = "Failed to cleanup chown " + _pkgdir;
2072         if (res.isOk()) {
2073             res = error(msg);
2074         } else {
2075             PLOG(ERROR) << msg;
2076         }
2077     }
2078 
2079     return res;
2080 }
2081 
run_idmap(const char * target_apk,const char * overlay_apk,int idmap_fd)2082 static void run_idmap(const char *target_apk, const char *overlay_apk, int idmap_fd)
2083 {
2084     execl(kIdMapPath, kIdMapPath, "--fd", target_apk, overlay_apk,
2085             StringPrintf("%d", idmap_fd).c_str(), (char*)NULL);
2086     PLOG(ERROR) << "execl (" << kIdMapPath << ") failed";
2087 }
2088 
run_verify_idmap(const char * target_apk,const char * overlay_apk,int idmap_fd)2089 static void run_verify_idmap(const char *target_apk, const char *overlay_apk, int idmap_fd)
2090 {
2091     execl(kIdMapPath, kIdMapPath, "--verify", target_apk, overlay_apk,
2092             StringPrintf("%d", idmap_fd).c_str(), (char*)NULL);
2093     PLOG(ERROR) << "execl (" << kIdMapPath << ") failed";
2094 }
2095 
delete_stale_idmap(const char * target_apk,const char * overlay_apk,const char * idmap_path,int32_t uid)2096 static bool delete_stale_idmap(const char* target_apk, const char* overlay_apk,
2097         const char* idmap_path, int32_t uid) {
2098     int idmap_fd = open(idmap_path, O_RDWR);
2099     if (idmap_fd < 0) {
2100         PLOG(ERROR) << "idmap open failed: " << idmap_path;
2101         unlink(idmap_path);
2102         return true;
2103     }
2104 
2105     pid_t pid;
2106     pid = fork();
2107     if (pid == 0) {
2108         /* child -- drop privileges before continuing */
2109         if (setgid(uid) != 0) {
2110             LOG(ERROR) << "setgid(" << uid << ") failed during idmap";
2111             exit(1);
2112         }
2113         if (setuid(uid) != 0) {
2114             LOG(ERROR) << "setuid(" << uid << ") failed during idmap";
2115             exit(1);
2116         }
2117         if (flock(idmap_fd, LOCK_EX | LOCK_NB) != 0) {
2118             PLOG(ERROR) << "flock(" << idmap_path << ") failed during idmap";
2119             exit(1);
2120         }
2121 
2122         run_verify_idmap(target_apk, overlay_apk, idmap_fd);
2123         exit(1); /* only if exec call to deleting stale idmap failed */
2124     } else {
2125         int status = wait_child(pid);
2126         close(idmap_fd);
2127 
2128         if (status != 0) {
2129             // Failed on verifying if idmap is made from target_apk and overlay_apk.
2130             LOG(DEBUG) << "delete stale idmap: " << idmap_path;
2131             unlink(idmap_path);
2132             return true;
2133         }
2134     }
2135     return false;
2136 }
2137 
2138 // Transform string /a/b/c.apk to (prefix)/a@b@c.apk@(suffix)
2139 // eg /a/b/c.apk to /data/resource-cache/a@b@c.apk@idmap
flatten_path(const char * prefix,const char * suffix,const char * overlay_path,char * idmap_path,size_t N)2140 static int flatten_path(const char *prefix, const char *suffix,
2141         const char *overlay_path, char *idmap_path, size_t N)
2142 {
2143     if (overlay_path == NULL || idmap_path == NULL) {
2144         return -1;
2145     }
2146     const size_t len_overlay_path = strlen(overlay_path);
2147     // will access overlay_path + 1 further below; requires absolute path
2148     if (len_overlay_path < 2 || *overlay_path != '/') {
2149         return -1;
2150     }
2151     const size_t len_idmap_root = strlen(prefix);
2152     const size_t len_suffix = strlen(suffix);
2153     if (SIZE_MAX - len_idmap_root < len_overlay_path ||
2154             SIZE_MAX - (len_idmap_root + len_overlay_path) < len_suffix) {
2155         // additions below would cause overflow
2156         return -1;
2157     }
2158     if (N < len_idmap_root + len_overlay_path + len_suffix) {
2159         return -1;
2160     }
2161     memset(idmap_path, 0, N);
2162     snprintf(idmap_path, N, "%s%s%s", prefix, overlay_path + 1, suffix);
2163     char *ch = idmap_path + len_idmap_root;
2164     while (*ch != '\0') {
2165         if (*ch == '/') {
2166             *ch = '@';
2167         }
2168         ++ch;
2169     }
2170     return 0;
2171 }
2172 
idmap(const std::string & targetApkPath,const std::string & overlayApkPath,int32_t uid)2173 binder::Status InstalldNativeService::idmap(const std::string& targetApkPath,
2174         const std::string& overlayApkPath, int32_t uid) {
2175     ENFORCE_UID(AID_SYSTEM);
2176     CHECK_ARGUMENT_PATH(targetApkPath);
2177     CHECK_ARGUMENT_PATH(overlayApkPath);
2178     std::lock_guard<std::recursive_mutex> lock(mLock);
2179 
2180     const char* target_apk = targetApkPath.c_str();
2181     const char* overlay_apk = overlayApkPath.c_str();
2182     ALOGV("idmap target_apk=%s overlay_apk=%s uid=%d\n", target_apk, overlay_apk, uid);
2183 
2184     int idmap_fd = -1;
2185     char idmap_path[PATH_MAX];
2186     struct stat idmap_stat;
2187     bool outdated = false;
2188 
2189     if (flatten_path(IDMAP_PREFIX, IDMAP_SUFFIX, overlay_apk,
2190                 idmap_path, sizeof(idmap_path)) == -1) {
2191         ALOGE("idmap cannot generate idmap path for overlay %s\n", overlay_apk);
2192         goto fail;
2193     }
2194 
2195     if (stat(idmap_path, &idmap_stat) < 0) {
2196         outdated = true;
2197     } else {
2198         outdated = delete_stale_idmap(target_apk, overlay_apk, idmap_path, uid);
2199     }
2200 
2201     if (outdated) {
2202         idmap_fd = open(idmap_path, O_RDWR | O_CREAT | O_EXCL, 0644);
2203     } else {
2204         idmap_fd = open(idmap_path, O_RDWR);
2205     }
2206 
2207     if (idmap_fd < 0) {
2208         ALOGE("idmap cannot open '%s' for output: %s\n", idmap_path, strerror(errno));
2209         goto fail;
2210     }
2211     if (fchown(idmap_fd, AID_SYSTEM, uid) < 0) {
2212         ALOGE("idmap cannot chown '%s'\n", idmap_path);
2213         goto fail;
2214     }
2215     if (fchmod(idmap_fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0) {
2216         ALOGE("idmap cannot chmod '%s'\n", idmap_path);
2217         goto fail;
2218     }
2219 
2220     if (!outdated) {
2221         close(idmap_fd);
2222         return ok();
2223     }
2224 
2225     pid_t pid;
2226     pid = fork();
2227     if (pid == 0) {
2228         /* child -- drop privileges before continuing */
2229         if (setgid(uid) != 0) {
2230             ALOGE("setgid(%d) failed during idmap\n", uid);
2231             exit(1);
2232         }
2233         if (setuid(uid) != 0) {
2234             ALOGE("setuid(%d) failed during idmap\n", uid);
2235             exit(1);
2236         }
2237         if (flock(idmap_fd, LOCK_EX | LOCK_NB) != 0) {
2238             ALOGE("flock(%s) failed during idmap: %s\n", idmap_path, strerror(errno));
2239             exit(1);
2240         }
2241 
2242         run_idmap(target_apk, overlay_apk, idmap_fd);
2243         exit(1); /* only if exec call to idmap failed */
2244     } else {
2245         int status = wait_child(pid);
2246         if (status != 0) {
2247             ALOGE("idmap failed, status=0x%04x\n", status);
2248             goto fail;
2249         }
2250     }
2251 
2252     close(idmap_fd);
2253     return ok();
2254 fail:
2255     if (idmap_fd >= 0) {
2256         close(idmap_fd);
2257         unlink(idmap_path);
2258     }
2259     return error();
2260 }
2261 
removeIdmap(const std::string & overlayApkPath)2262 binder::Status InstalldNativeService::removeIdmap(const std::string& overlayApkPath) {
2263     ENFORCE_UID(AID_SYSTEM);
2264     CHECK_ARGUMENT_PATH(overlayApkPath);
2265     std::lock_guard<std::recursive_mutex> lock(mLock);
2266 
2267     const char* overlay_apk = overlayApkPath.c_str();
2268     char idmap_path[PATH_MAX];
2269 
2270     if (flatten_path(IDMAP_PREFIX, IDMAP_SUFFIX, overlay_apk,
2271                 idmap_path, sizeof(idmap_path)) == -1) {
2272         ALOGE("idmap cannot generate idmap path for overlay %s\n", overlay_apk);
2273         return error();
2274     }
2275     if (unlink(idmap_path) < 0) {
2276         ALOGE("couldn't unlink idmap file %s\n", idmap_path);
2277         return error();
2278     }
2279     return ok();
2280 }
2281 
restoreconAppData(const std::unique_ptr<std::string> & uuid,const std::string & packageName,int32_t userId,int32_t flags,int32_t appId,const std::string & seInfo)2282 binder::Status InstalldNativeService::restoreconAppData(const std::unique_ptr<std::string>& uuid,
2283         const std::string& packageName, int32_t userId, int32_t flags, int32_t appId,
2284         const std::string& seInfo) {
2285     ENFORCE_UID(AID_SYSTEM);
2286     CHECK_ARGUMENT_UUID(uuid);
2287     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
2288     std::lock_guard<std::recursive_mutex> lock(mLock);
2289 
2290     binder::Status res = ok();
2291 
2292     // SELINUX_ANDROID_RESTORECON_DATADATA flag is set by libselinux. Not needed here.
2293     unsigned int seflags = SELINUX_ANDROID_RESTORECON_RECURSE;
2294     const char* uuid_ = uuid ? uuid->c_str() : nullptr;
2295     const char* pkgName = packageName.c_str();
2296     const char* seinfo = seInfo.c_str();
2297 
2298     uid_t uid = multiuser_get_uid(userId, appId);
2299     if (flags & FLAG_STORAGE_CE) {
2300         auto path = create_data_user_ce_package_path(uuid_, userId, pkgName);
2301         if (selinux_android_restorecon_pkgdir(path.c_str(), seinfo, uid, seflags) < 0) {
2302             res = error("restorecon failed for " + path);
2303         }
2304     }
2305     if (flags & FLAG_STORAGE_DE) {
2306         auto path = create_data_user_de_package_path(uuid_, userId, pkgName);
2307         if (selinux_android_restorecon_pkgdir(path.c_str(), seinfo, uid, seflags) < 0) {
2308             res = error("restorecon failed for " + path);
2309         }
2310     }
2311     return res;
2312 }
2313 
createOatDir(const std::string & oatDir,const std::string & instructionSet)2314 binder::Status InstalldNativeService::createOatDir(const std::string& oatDir,
2315         const std::string& instructionSet) {
2316     ENFORCE_UID(AID_SYSTEM);
2317     CHECK_ARGUMENT_PATH(oatDir);
2318     std::lock_guard<std::recursive_mutex> lock(mLock);
2319 
2320     const char* oat_dir = oatDir.c_str();
2321     const char* instruction_set = instructionSet.c_str();
2322     char oat_instr_dir[PKG_PATH_MAX];
2323 
2324     if (validate_apk_path(oat_dir)) {
2325         return error("Invalid path " + oatDir);
2326     }
2327     if (fs_prepare_dir(oat_dir, S_IRWXU | S_IRWXG | S_IXOTH, AID_SYSTEM, AID_INSTALL)) {
2328         return error("Failed to prepare " + oatDir);
2329     }
2330     if (selinux_android_restorecon(oat_dir, 0)) {
2331         return error("Failed to restorecon " + oatDir);
2332     }
2333     snprintf(oat_instr_dir, PKG_PATH_MAX, "%s/%s", oat_dir, instruction_set);
2334     if (fs_prepare_dir(oat_instr_dir, S_IRWXU | S_IRWXG | S_IXOTH, AID_SYSTEM, AID_INSTALL)) {
2335         return error(StringPrintf("Failed to prepare %s", oat_instr_dir));
2336     }
2337     return ok();
2338 }
2339 
rmPackageDir(const std::string & packageDir)2340 binder::Status InstalldNativeService::rmPackageDir(const std::string& packageDir) {
2341     ENFORCE_UID(AID_SYSTEM);
2342     CHECK_ARGUMENT_PATH(packageDir);
2343     std::lock_guard<std::recursive_mutex> lock(mLock);
2344 
2345     if (validate_apk_path(packageDir.c_str())) {
2346         return error("Invalid path " + packageDir);
2347     }
2348     if (delete_dir_contents_and_dir(packageDir) != 0) {
2349         return error("Failed to delete " + packageDir);
2350     }
2351     return ok();
2352 }
2353 
linkFile(const std::string & relativePath,const std::string & fromBase,const std::string & toBase)2354 binder::Status InstalldNativeService::linkFile(const std::string& relativePath,
2355         const std::string& fromBase, const std::string& toBase) {
2356     ENFORCE_UID(AID_SYSTEM);
2357     CHECK_ARGUMENT_PATH(fromBase);
2358     CHECK_ARGUMENT_PATH(toBase);
2359     std::lock_guard<std::recursive_mutex> lock(mLock);
2360 
2361     const char* relative_path = relativePath.c_str();
2362     const char* from_base = fromBase.c_str();
2363     const char* to_base = toBase.c_str();
2364     char from_path[PKG_PATH_MAX];
2365     char to_path[PKG_PATH_MAX];
2366     snprintf(from_path, PKG_PATH_MAX, "%s/%s", from_base, relative_path);
2367     snprintf(to_path, PKG_PATH_MAX, "%s/%s", to_base, relative_path);
2368 
2369     if (validate_apk_path_subdirs(from_path)) {
2370         return error(StringPrintf("Invalid from path %s", from_path));
2371     }
2372 
2373     if (validate_apk_path_subdirs(to_path)) {
2374         return error(StringPrintf("Invalid to path %s", to_path));
2375     }
2376 
2377     if (link(from_path, to_path) < 0) {
2378         return error(StringPrintf("Failed to link from %s to %s", from_path, to_path));
2379     }
2380 
2381     return ok();
2382 }
2383 
moveAb(const std::string & apkPath,const std::string & instructionSet,const std::string & outputPath)2384 binder::Status InstalldNativeService::moveAb(const std::string& apkPath,
2385         const std::string& instructionSet, const std::string& outputPath) {
2386     ENFORCE_UID(AID_SYSTEM);
2387     CHECK_ARGUMENT_PATH(apkPath);
2388     CHECK_ARGUMENT_PATH(outputPath);
2389     std::lock_guard<std::recursive_mutex> lock(mLock);
2390 
2391     const char* apk_path = apkPath.c_str();
2392     const char* instruction_set = instructionSet.c_str();
2393     const char* oat_dir = outputPath.c_str();
2394 
2395     bool success = move_ab(apk_path, instruction_set, oat_dir);
2396     return success ? ok() : error();
2397 }
2398 
deleteOdex(const std::string & apkPath,const std::string & instructionSet,const std::unique_ptr<std::string> & outputPath)2399 binder::Status InstalldNativeService::deleteOdex(const std::string& apkPath,
2400         const std::string& instructionSet, const std::unique_ptr<std::string>& outputPath) {
2401     ENFORCE_UID(AID_SYSTEM);
2402     CHECK_ARGUMENT_PATH(apkPath);
2403     CHECK_ARGUMENT_PATH(outputPath);
2404     std::lock_guard<std::recursive_mutex> lock(mLock);
2405 
2406     const char* apk_path = apkPath.c_str();
2407     const char* instruction_set = instructionSet.c_str();
2408     const char* oat_dir = outputPath ? outputPath->c_str() : nullptr;
2409 
2410     bool res = delete_odex(apk_path, instruction_set, oat_dir);
2411     return res ? ok() : error();
2412 }
2413 
2414 // This kernel feature is experimental.
2415 // TODO: remove local definition once upstreamed
2416 #ifndef FS_IOC_ENABLE_VERITY
2417 
2418 #define FS_IOC_ENABLE_VERITY           _IO('f', 133)
2419 #define FS_IOC_SET_VERITY_MEASUREMENT  _IOW('f', 134, struct fsverity_measurement)
2420 
2421 #define FS_VERITY_ALG_SHA256           1
2422 
2423 struct fsverity_measurement {
2424     __u16 digest_algorithm;
2425     __u16 digest_size;
2426     __u32 reserved1;
2427     __u64 reserved2[3];
2428     __u8 digest[];
2429 };
2430 
2431 #endif
2432 
installApkVerity(const std::string & filePath,const::android::base::unique_fd & verityInputAshmem,int32_t contentSize)2433 binder::Status InstalldNativeService::installApkVerity(const std::string& filePath,
2434         const ::android::base::unique_fd& verityInputAshmem, int32_t contentSize) {
2435     ENFORCE_UID(AID_SYSTEM);
2436     CHECK_ARGUMENT_PATH(filePath);
2437     std::lock_guard<std::recursive_mutex> lock(mLock);
2438 
2439     if (!android::base::GetBoolProperty(kPropApkVerityMode, false)) {
2440         return ok();
2441     }
2442 #ifndef NDEBUG
2443     ASSERT_PAGE_SIZE_4K();
2444 #endif
2445     // TODO: also check fsverity support in the current file system if compiled with DEBUG.
2446     // TODO: change ashmem to some temporary file to support huge apk.
2447     if (!ashmem_valid(verityInputAshmem.get())) {
2448         return error("FD is not an ashmem");
2449     }
2450 
2451     // 1. Seek to the next page boundary beyond the end of the file.
2452     ::android::base::unique_fd wfd(open(filePath.c_str(), O_WRONLY));
2453     if (wfd.get() < 0) {
2454         return error("Failed to open " + filePath);
2455     }
2456     struct stat st;
2457     if (fstat(wfd.get(), &st) < 0) {
2458         return error("Failed to stat " + filePath);
2459     }
2460     // fsverity starts from the block boundary.
2461     off_t padding = kVerityPageSize - st.st_size % kVerityPageSize;
2462     if (padding == kVerityPageSize) {
2463         padding = 0;
2464     }
2465     if (lseek(wfd.get(), st.st_size + padding, SEEK_SET) < 0) {
2466         return error("Failed to lseek " + filePath);
2467     }
2468 
2469     // 2. Write everything in the ashmem to the file.  Note that allocated
2470     //    ashmem size is multiple of page size, which is different from the
2471     //    actual content size.
2472     int shmSize = ashmem_get_size_region(verityInputAshmem.get());
2473     if (shmSize < 0) {
2474         return error("Failed to get ashmem size: " + std::to_string(shmSize));
2475     }
2476     if (contentSize < 0) {
2477         return error("Invalid content size: " + std::to_string(contentSize));
2478     }
2479     if (contentSize > shmSize) {
2480         return error("Content size overflow: " + std::to_string(contentSize) + " > " +
2481                      std::to_string(shmSize));
2482     }
2483     auto data = std::unique_ptr<void, std::function<void (void *)>>(
2484         mmap(NULL, contentSize, PROT_READ, MAP_SHARED, verityInputAshmem.get(), 0),
2485         [contentSize] (void* ptr) {
2486           if (ptr != MAP_FAILED) {
2487             munmap(ptr, contentSize);
2488           }
2489         });
2490 
2491     if (data.get() == MAP_FAILED) {
2492         return error("Failed to mmap the ashmem");
2493     }
2494     char* cursor = reinterpret_cast<char*>(data.get());
2495     int remaining = contentSize;
2496     while (remaining > 0) {
2497         int ret = TEMP_FAILURE_RETRY(write(wfd.get(), cursor, remaining));
2498         if (ret < 0) {
2499             return error("Failed to write to " + filePath + " (" + std::to_string(remaining) +
2500                          + "/" + std::to_string(contentSize) + ")");
2501         }
2502         cursor += ret;
2503         remaining -= ret;
2504     }
2505     wfd.reset();
2506 
2507     // 3. Enable fsverity (needs readonly fd. Once it's done, the file becomes immutable.
2508     ::android::base::unique_fd rfd(open(filePath.c_str(), O_RDONLY));
2509     if (ioctl(rfd.get(), FS_IOC_ENABLE_VERITY, nullptr) < 0) {
2510         return error("Failed to enable fsverity on " + filePath);
2511     }
2512     return ok();
2513 }
2514 
assertFsverityRootHashMatches(const std::string & filePath,const std::vector<uint8_t> & expectedHash)2515 binder::Status InstalldNativeService::assertFsverityRootHashMatches(const std::string& filePath,
2516         const std::vector<uint8_t>& expectedHash) {
2517     ENFORCE_UID(AID_SYSTEM);
2518     CHECK_ARGUMENT_PATH(filePath);
2519     std::lock_guard<std::recursive_mutex> lock(mLock);
2520 
2521     if (!android::base::GetBoolProperty(kPropApkVerityMode, false)) {
2522         return ok();
2523     }
2524     // TODO: also check fsverity support in the current file system if compiled with DEBUG.
2525     if (expectedHash.size() != kSha256Size) {
2526         return error("verity hash size should be " + std::to_string(kSha256Size) + " but is " +
2527                      std::to_string(expectedHash.size()));
2528     }
2529 
2530     ::android::base::unique_fd fd(open(filePath.c_str(), O_RDONLY));
2531     if (fd.get() < 0) {
2532         return error("Failed to open " + filePath + ": " + strerror(errno));
2533     }
2534 
2535     unsigned int buffer_size = sizeof(fsverity_measurement) + kSha256Size;
2536     std::vector<char> buffer(buffer_size, 0);
2537 
2538     fsverity_measurement* config = reinterpret_cast<fsverity_measurement*>(buffer.data());
2539     config->digest_algorithm = FS_VERITY_ALG_SHA256;
2540     config->digest_size = kSha256Size;
2541     memcpy(config->digest, expectedHash.data(), kSha256Size);
2542     if (ioctl(fd.get(), FS_IOC_SET_VERITY_MEASUREMENT, config) < 0) {
2543         // This includes an expected failure case with no FSVerity setup. It normally happens when
2544         // the apk does not contains the Merkle tree root hash.
2545         return error("Failed to measure fsverity on " + filePath + ": " + strerror(errno));
2546     }
2547     return ok();  // hashes match
2548 }
2549 
reconcileSecondaryDexFile(const std::string & dexPath,const std::string & packageName,int32_t uid,const std::vector<std::string> & isas,const std::unique_ptr<std::string> & volumeUuid,int32_t storage_flag,bool * _aidl_return)2550 binder::Status InstalldNativeService::reconcileSecondaryDexFile(
2551         const std::string& dexPath, const std::string& packageName, int32_t uid,
2552         const std::vector<std::string>& isas, const std::unique_ptr<std::string>& volumeUuid,
2553         int32_t storage_flag, bool* _aidl_return) {
2554     ENFORCE_UID(AID_SYSTEM);
2555     CHECK_ARGUMENT_UUID(volumeUuid);
2556     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
2557     CHECK_ARGUMENT_PATH(dexPath);
2558     std::lock_guard<std::recursive_mutex> lock(mLock);
2559 
2560     bool result = android::installd::reconcile_secondary_dex_file(
2561             dexPath, packageName, uid, isas, volumeUuid, storage_flag, _aidl_return);
2562     return result ? ok() : error();
2563 }
2564 
hashSecondaryDexFile(const std::string & dexPath,const std::string & packageName,int32_t uid,const std::unique_ptr<std::string> & volumeUuid,int32_t storageFlag,std::vector<uint8_t> * _aidl_return)2565 binder::Status InstalldNativeService::hashSecondaryDexFile(
2566         const std::string& dexPath, const std::string& packageName, int32_t uid,
2567         const std::unique_ptr<std::string>& volumeUuid, int32_t storageFlag,
2568         std::vector<uint8_t>* _aidl_return) {
2569     ENFORCE_UID(AID_SYSTEM);
2570     CHECK_ARGUMENT_UUID(volumeUuid);
2571     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
2572     CHECK_ARGUMENT_PATH(dexPath);
2573 
2574     // mLock is not taken here since we will never modify the file system.
2575     // If a file is modified just as we are reading it this may result in an
2576     // anomalous hash, but that's ok.
2577     bool result = android::installd::hash_secondary_dex_file(
2578         dexPath, packageName, uid, volumeUuid, storageFlag, _aidl_return);
2579     return result ? ok() : error();
2580 }
2581 
invalidateMounts()2582 binder::Status InstalldNativeService::invalidateMounts() {
2583     ENFORCE_UID(AID_SYSTEM);
2584     std::lock_guard<std::recursive_mutex> lock(mMountsLock);
2585 
2586     mStorageMounts.clear();
2587     mQuotaReverseMounts.clear();
2588 
2589     std::ifstream in("/proc/mounts");
2590     if (!in.is_open()) {
2591         return error("Failed to read mounts");
2592     }
2593 
2594     std::string source;
2595     std::string target;
2596     std::string ignored;
2597     while (!in.eof()) {
2598         std::getline(in, source, ' ');
2599         std::getline(in, target, ' ');
2600         std::getline(in, ignored);
2601 
2602 #if !BYPASS_SDCARDFS
2603         if (target.compare(0, 21, "/mnt/runtime/default/") == 0) {
2604             LOG(DEBUG) << "Found storage mount " << source << " at " << target;
2605             mStorageMounts[source] = target;
2606         }
2607 #endif
2608 
2609 #if !BYPASS_QUOTA
2610         if (source.compare(0, 11, "/dev/block/") == 0) {
2611             struct dqblk dq;
2612             if (quotactl(QCMD(Q_GETQUOTA, USRQUOTA), source.c_str(), 0,
2613                     reinterpret_cast<char*>(&dq)) == 0) {
2614                 LOG(DEBUG) << "Found quota mount " << source << " at " << target;
2615                 mQuotaReverseMounts[target] = source;
2616 
2617                 // ext4 only enables DQUOT_USAGE_ENABLED by default, so we
2618                 // need to kick it again to enable DQUOT_LIMITS_ENABLED. We
2619                 // only need hard limits enabled when we're not being protected
2620                 // by reserved blocks.
2621                 if (!android::base::GetBoolProperty(kPropHasReserved, false)) {
2622                     if (quotactl(QCMD(Q_QUOTAON, USRQUOTA), source.c_str(), QFMT_VFS_V1,
2623                             nullptr) != 0 && errno != EBUSY) {
2624                         PLOG(ERROR) << "Failed to enable USRQUOTA on " << source;
2625                     }
2626                     if (quotactl(QCMD(Q_QUOTAON, GRPQUOTA), source.c_str(), QFMT_VFS_V1,
2627                             nullptr) != 0 && errno != EBUSY) {
2628                         PLOG(ERROR) << "Failed to enable GRPQUOTA on " << source;
2629                     }
2630                 }
2631             }
2632         }
2633 #endif
2634     }
2635     return ok();
2636 }
2637 
findDataMediaPath(const std::unique_ptr<std::string> & uuid,userid_t userid)2638 std::string InstalldNativeService::findDataMediaPath(
2639         const std::unique_ptr<std::string>& uuid, userid_t userid) {
2640     std::lock_guard<std::recursive_mutex> lock(mMountsLock);
2641     const char* uuid_ = uuid ? uuid->c_str() : nullptr;
2642     auto path = StringPrintf("%s/media", create_data_path(uuid_).c_str());
2643     auto resolved = mStorageMounts[path];
2644     if (resolved.empty()) {
2645         LOG(WARNING) << "Failed to find storage mount for " << path;
2646         resolved = path;
2647     }
2648     return StringPrintf("%s/%u", resolved.c_str(), userid);
2649 }
2650 
findQuotaDeviceForUuid(const std::unique_ptr<std::string> & uuid)2651 std::string InstalldNativeService::findQuotaDeviceForUuid(
2652         const std::unique_ptr<std::string>& uuid) {
2653     std::lock_guard<std::recursive_mutex> lock(mMountsLock);
2654     auto path = create_data_path(uuid ? uuid->c_str() : nullptr);
2655     return mQuotaReverseMounts[path];
2656 }
2657 
isQuotaSupported(const std::unique_ptr<std::string> & volumeUuid,bool * _aidl_return)2658 binder::Status InstalldNativeService::isQuotaSupported(
2659         const std::unique_ptr<std::string>& volumeUuid, bool* _aidl_return) {
2660     *_aidl_return = !findQuotaDeviceForUuid(volumeUuid).empty();
2661     return ok();
2662 }
2663 
prepareAppProfile(const std::string & packageName,int32_t userId,int32_t appId,const std::string & profileName,const std::string & codePath,const std::unique_ptr<std::string> & dexMetadata,bool * _aidl_return)2664 binder::Status InstalldNativeService::prepareAppProfile(const std::string& packageName,
2665         int32_t userId, int32_t appId, const std::string& profileName, const std::string& codePath,
2666         const std::unique_ptr<std::string>& dexMetadata, bool* _aidl_return) {
2667     ENFORCE_UID(AID_SYSTEM);
2668     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
2669     CHECK_ARGUMENT_PATH(codePath);
2670     std::lock_guard<std::recursive_mutex> lock(mLock);
2671 
2672     *_aidl_return = prepare_app_profile(packageName, userId, appId, profileName, codePath,
2673         dexMetadata);
2674     return ok();
2675 }
2676 
2677 }  // namespace installd
2678 }  // namespace android
2679