1 /*
2 ** Copyright 2008, The Android Open Source Project
3 **
4 ** Licensed under the Apache License, Version 2.0 (the "License");
5 ** you may not use this file except in compliance with the License.
6 ** You may obtain a copy of the License at
7 **
8 **     http://www.apache.org/licenses/LICENSE-2.0
9 **
10 ** Unless required by applicable law or agreed to in writing, software
11 ** distributed under the License is distributed on an "AS IS" BASIS,
12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 ** See the License for the specific language governing permissions and
14 ** limitations under the License.
15 */
16 
17 #include "utils.h"
18 
19 #include <errno.h>
20 #include <fcntl.h>
21 #include <fts.h>
22 #include <stdlib.h>
23 #include <sys/capability.h>
24 #include <sys/stat.h>
25 #include <sys/wait.h>
26 #include <sys/xattr.h>
27 #include <sys/statvfs.h>
28 
29 #include <android-base/file.h>
30 #include <android-base/logging.h>
31 #include <android-base/strings.h>
32 #include <android-base/stringprintf.h>
33 #include <android-base/unique_fd.h>
34 #include <cutils/fs.h>
35 #include <cutils/properties.h>
36 #include <log/log.h>
37 #include <private/android_filesystem_config.h>
38 #include <private/android_projectid_config.h>
39 
40 #include "dexopt_return_codes.h"
41 #include "globals.h"  // extern variables.
42 #include "QuotaUtils.h"
43 
44 #ifndef LOG_TAG
45 #define LOG_TAG "installd"
46 #endif
47 
48 #define DEBUG_XATTRS 0
49 
50 using android::base::EndsWith;
51 using android::base::Fdopendir;
52 using android::base::StringPrintf;
53 using android::base::unique_fd;
54 
55 namespace android {
56 namespace installd {
57 
58 /**
59  * Check that given string is valid filename, and that it attempts no
60  * parent or child directory traversal.
61  */
is_valid_filename(const std::string & name)62 bool is_valid_filename(const std::string& name) {
63     if (name.empty() || (name == ".") || (name == "..")
64             || (name.find('/') != std::string::npos)) {
65         return false;
66     } else {
67         return true;
68     }
69 }
70 
check_package_name(const char * package_name)71 static void check_package_name(const char* package_name) {
72     CHECK(is_valid_filename(package_name));
73     CHECK(is_valid_package_name(package_name));
74 }
75 
resolve_ce_path_by_inode_or_fallback(const std::string & root_path,ino_t ce_data_inode,const std::string & fallback)76 static std::string resolve_ce_path_by_inode_or_fallback(const std::string& root_path,
77         ino_t ce_data_inode, const std::string& fallback) {
78     if (ce_data_inode != 0) {
79         DIR* dir = opendir(root_path.c_str());
80         if (dir == nullptr) {
81             PLOG(ERROR) << "Failed to opendir " << root_path;
82             return fallback;
83         }
84 
85         struct dirent* ent;
86         while ((ent = readdir(dir))) {
87             if (ent->d_ino == ce_data_inode) {
88                 auto resolved = StringPrintf("%s/%s", root_path.c_str(), ent->d_name);
89                 if (resolved != fallback) {
90                     LOG(DEBUG) << "Resolved path " << resolved << " for inode " << ce_data_inode
91                             << " instead of " << fallback;
92                 }
93                 closedir(dir);
94                 return resolved;
95             }
96         }
97         LOG(WARNING) << "Failed to resolve inode " << ce_data_inode << "; using " << fallback;
98         closedir(dir);
99         return fallback;
100     } else {
101         return fallback;
102     }
103 }
104 
105 /**
106  * Create the path name where package app contents should be stored for
107  * the given volume UUID and package name.  An empty UUID is assumed to
108  * be internal storage.
109  */
create_data_app_package_path(const char * volume_uuid,const char * package_name)110 std::string create_data_app_package_path(const char* volume_uuid,
111         const char* package_name) {
112     check_package_name(package_name);
113     return StringPrintf("%s/%s",
114             create_data_app_path(volume_uuid).c_str(), package_name);
115 }
116 
117 /**
118  * Create the path name where package data should be stored for the given
119  * volume UUID, package name, and user ID. An empty UUID is assumed to be
120  * internal storage.
121  */
create_data_user_ce_package_path(const char * volume_uuid,userid_t user,const char * package_name)122 std::string create_data_user_ce_package_path(const char* volume_uuid,
123         userid_t user, const char* package_name) {
124     check_package_name(package_name);
125     return StringPrintf("%s/%s",
126             create_data_user_ce_path(volume_uuid, user).c_str(), package_name);
127 }
128 
129 /**
130  * Create the path name where package data should be stored for the given
131  * volume UUID, package name, and user ID. An empty UUID is assumed to be
132  * internal storage.
133  * Compared to create_data_user_ce_package_path this method always return the
134  * ".../user/..." directory.
135  */
create_data_user_ce_package_path_as_user_link(const char * volume_uuid,userid_t userid,const char * package_name)136 std::string create_data_user_ce_package_path_as_user_link(
137         const char* volume_uuid, userid_t userid, const char* package_name) {
138     check_package_name(package_name);
139     std::string data(create_data_path(volume_uuid));
140     return StringPrintf("%s/user/%u/%s", data.c_str(), userid, package_name);
141 }
142 
create_data_user_ce_package_path(const char * volume_uuid,userid_t user,const char * package_name,ino_t ce_data_inode)143 std::string create_data_user_ce_package_path(const char* volume_uuid, userid_t user,
144         const char* package_name, ino_t ce_data_inode) {
145     // For testing purposes, rely on the inode when defined; this could be
146     // optimized to use access() in the future.
147     auto fallback = create_data_user_ce_package_path(volume_uuid, user, package_name);
148     auto user_path = create_data_user_ce_path(volume_uuid, user);
149     return resolve_ce_path_by_inode_or_fallback(user_path, ce_data_inode, fallback);
150 }
151 
create_data_user_de_package_path(const char * volume_uuid,userid_t user,const char * package_name)152 std::string create_data_user_de_package_path(const char* volume_uuid,
153         userid_t user, const char* package_name) {
154     check_package_name(package_name);
155     return StringPrintf("%s/%s",
156             create_data_user_de_path(volume_uuid, user).c_str(), package_name);
157 }
158 
create_data_path(const char * volume_uuid)159 std::string create_data_path(const char* volume_uuid) {
160     if (volume_uuid == nullptr) {
161         return "/data";
162     } else if (!strcmp(volume_uuid, "TEST")) {
163         CHECK(property_get_bool("ro.debuggable", false));
164         return "/data/local/tmp";
165     } else {
166         CHECK(is_valid_filename(volume_uuid));
167         return StringPrintf("/mnt/expand/%s", volume_uuid);
168     }
169 }
170 
171 /**
172  * Create the path name for app data.
173  */
create_data_app_path(const char * volume_uuid)174 std::string create_data_app_path(const char* volume_uuid) {
175     return StringPrintf("%s/app", create_data_path(volume_uuid).c_str());
176 }
177 
178 /**
179  * Create the path name for user data for a certain userid.
180  * Keep same implementation as vold to minimize path walking overhead
181  */
create_data_user_ce_path(const char * volume_uuid,userid_t userid)182 std::string create_data_user_ce_path(const char* volume_uuid, userid_t userid) {
183     std::string data(create_data_path(volume_uuid));
184     if (volume_uuid == nullptr && userid == 0) {
185         std::string legacy = StringPrintf("%s/data", data.c_str());
186         struct stat sb;
187         if (lstat(legacy.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode)) {
188             /* /data/data is dir, return /data/data for legacy system */
189             return legacy;
190         }
191     }
192     return StringPrintf("%s/user/%u", data.c_str(), userid);
193 }
194 
195 /**
196  * Create the path name for device encrypted user data for a certain userid.
197  */
create_data_user_de_path(const char * volume_uuid,userid_t userid)198 std::string create_data_user_de_path(const char* volume_uuid, userid_t userid) {
199     std::string data(create_data_path(volume_uuid));
200     return StringPrintf("%s/user_de/%u", data.c_str(), userid);
201 }
202 
create_data_misc_ce_rollback_base_path(const char * volume_uuid,userid_t user)203 std::string create_data_misc_ce_rollback_base_path(const char* volume_uuid, userid_t user) {
204     return StringPrintf("%s/misc_ce/%u/rollback", create_data_path(volume_uuid).c_str(), user);
205 }
206 
create_data_misc_de_rollback_base_path(const char * volume_uuid,userid_t user)207 std::string create_data_misc_de_rollback_base_path(const char* volume_uuid, userid_t user) {
208     return StringPrintf("%s/misc_de/%u/rollback", create_data_path(volume_uuid).c_str(), user);
209 }
210 
create_data_misc_ce_rollback_path(const char * volume_uuid,userid_t user,int32_t snapshot_id)211 std::string create_data_misc_ce_rollback_path(const char* volume_uuid, userid_t user,
212         int32_t snapshot_id) {
213     return StringPrintf("%s/%d", create_data_misc_ce_rollback_base_path(volume_uuid, user).c_str(),
214           snapshot_id);
215 }
216 
create_data_misc_de_rollback_path(const char * volume_uuid,userid_t user,int32_t snapshot_id)217 std::string create_data_misc_de_rollback_path(const char* volume_uuid, userid_t user,
218         int32_t snapshot_id) {
219     return StringPrintf("%s/%d", create_data_misc_de_rollback_base_path(volume_uuid, user).c_str(),
220           snapshot_id);
221 }
222 
create_data_misc_ce_rollback_package_path(const char * volume_uuid,userid_t user,int32_t snapshot_id,const char * package_name)223 std::string create_data_misc_ce_rollback_package_path(const char* volume_uuid,
224         userid_t user, int32_t snapshot_id, const char* package_name) {
225     return StringPrintf("%s/%s",
226            create_data_misc_ce_rollback_path(volume_uuid, user, snapshot_id).c_str(), package_name);
227 }
228 
create_data_misc_ce_rollback_package_path(const char * volume_uuid,userid_t user,int32_t snapshot_id,const char * package_name,ino_t ce_rollback_inode)229 std::string create_data_misc_ce_rollback_package_path(const char* volume_uuid,
230         userid_t user, int32_t snapshot_id, const char* package_name, ino_t ce_rollback_inode) {
231     auto fallback = create_data_misc_ce_rollback_package_path(volume_uuid, user, snapshot_id,
232             package_name);
233     auto user_path = create_data_misc_ce_rollback_path(volume_uuid, user, snapshot_id);
234     return resolve_ce_path_by_inode_or_fallback(user_path, ce_rollback_inode, fallback);
235 }
236 
create_data_misc_de_rollback_package_path(const char * volume_uuid,userid_t user,int32_t snapshot_id,const char * package_name)237 std::string create_data_misc_de_rollback_package_path(const char* volume_uuid,
238         userid_t user, int32_t snapshot_id, const char* package_name) {
239     return StringPrintf("%s/%s",
240            create_data_misc_de_rollback_path(volume_uuid, user, snapshot_id).c_str(), package_name);
241 }
242 
243 /**
244  * Create the path name for media for a certain userid.
245  */
create_data_media_path(const char * volume_uuid,userid_t userid)246 std::string create_data_media_path(const char* volume_uuid, userid_t userid) {
247     return StringPrintf("%s/media/%u", create_data_path(volume_uuid).c_str(), userid);
248 }
249 
create_data_media_package_path(const char * volume_uuid,userid_t userid,const char * data_type,const char * package_name)250 std::string create_data_media_package_path(const char* volume_uuid, userid_t userid,
251         const char* data_type, const char* package_name) {
252     return StringPrintf("%s/Android/%s/%s", create_data_media_path(volume_uuid, userid).c_str(),
253             data_type, package_name);
254 }
255 
create_data_misc_legacy_path(userid_t userid)256 std::string create_data_misc_legacy_path(userid_t userid) {
257     return StringPrintf("%s/misc/user/%u", create_data_path(nullptr).c_str(), userid);
258 }
259 
create_primary_cur_profile_dir_path(userid_t userid)260 std::string create_primary_cur_profile_dir_path(userid_t userid) {
261     return StringPrintf("%s/cur/%u", android_profiles_dir.c_str(), userid);
262 }
263 
create_primary_current_profile_package_dir_path(userid_t user,const std::string & package_name)264 std::string create_primary_current_profile_package_dir_path(userid_t user,
265         const std::string& package_name) {
266     check_package_name(package_name.c_str());
267     return StringPrintf("%s/%s",
268             create_primary_cur_profile_dir_path(user).c_str(), package_name.c_str());
269 }
270 
create_primary_ref_profile_dir_path()271 std::string create_primary_ref_profile_dir_path() {
272     return StringPrintf("%s/ref", android_profiles_dir.c_str());
273 }
274 
create_primary_reference_profile_package_dir_path(const std::string & package_name)275 std::string create_primary_reference_profile_package_dir_path(const std::string& package_name) {
276     check_package_name(package_name.c_str());
277     return StringPrintf("%s/ref/%s", android_profiles_dir.c_str(), package_name.c_str());
278 }
279 
create_data_dalvik_cache_path()280 std::string create_data_dalvik_cache_path() {
281     return "/data/dalvik-cache";
282 }
283 
284 // Keep profile paths in sync with ActivityThread and LoadedApk.
285 const std::string PROFILE_EXT = ".prof";
286 const std::string CURRENT_PROFILE_EXT = ".cur";
287 const std::string SNAPSHOT_PROFILE_EXT = ".snapshot";
288 
289 // Gets the parent directory and the file name for the given secondary dex path.
290 // Returns true on success, false on failure (if the dex_path does not have the expected
291 // structure).
get_secondary_dex_location(const std::string & dex_path,std::string * out_dir_name,std::string * out_file_name)292 static bool get_secondary_dex_location(const std::string& dex_path,
293         std::string* out_dir_name, std::string* out_file_name) {
294    size_t dirIndex = dex_path.rfind('/');
295    if (dirIndex == std::string::npos) {
296         return false;
297    }
298    if (dirIndex == dex_path.size() - 1) {
299         return false;
300    }
301    *out_dir_name = dex_path.substr(0, dirIndex);
302    *out_file_name = dex_path.substr(dirIndex + 1);
303 
304    return true;
305 }
306 
create_current_profile_path(userid_t user,const std::string & package_name,const std::string & location,bool is_secondary_dex)307 std::string create_current_profile_path(userid_t user, const std::string& package_name,
308         const std::string& location, bool is_secondary_dex) {
309     if (is_secondary_dex) {
310         // Secondary dex current profiles are stored next to the dex files under the oat folder.
311         std::string dex_dir;
312         std::string dex_name;
313         CHECK(get_secondary_dex_location(location, &dex_dir, &dex_name))
314                 << "Unexpected dir structure for secondary dex " << location;
315         return StringPrintf("%s/oat/%s%s%s",
316                 dex_dir.c_str(), dex_name.c_str(), CURRENT_PROFILE_EXT.c_str(),
317                 PROFILE_EXT.c_str());
318     } else {
319         // Profiles for primary apks are under /data/misc/profiles/cur.
320         std::string profile_dir = create_primary_current_profile_package_dir_path(
321                 user, package_name);
322         return StringPrintf("%s/%s", profile_dir.c_str(), location.c_str());
323     }
324 }
325 
create_reference_profile_path(const std::string & package_name,const std::string & location,bool is_secondary_dex)326 std::string create_reference_profile_path(const std::string& package_name,
327         const std::string& location, bool is_secondary_dex) {
328     if (is_secondary_dex) {
329         // Secondary dex reference profiles are stored next to the dex files under the oat folder.
330         std::string dex_dir;
331         std::string dex_name;
332         CHECK(get_secondary_dex_location(location, &dex_dir, &dex_name))
333                 << "Unexpected dir structure for secondary dex " << location;
334         return StringPrintf("%s/oat/%s%s",
335                 dex_dir.c_str(), dex_name.c_str(), PROFILE_EXT.c_str());
336     } else {
337         // Reference profiles for primary apks are stored in /data/misc/profile/ref.
338         std::string profile_dir = create_primary_reference_profile_package_dir_path(package_name);
339         return StringPrintf("%s/%s", profile_dir.c_str(), location.c_str());
340     }
341 }
342 
create_snapshot_profile_path(const std::string & package,const std::string & profile_name)343 std::string create_snapshot_profile_path(const std::string& package,
344         const std::string& profile_name) {
345     std::string ref_profile = create_reference_profile_path(package, profile_name,
346             /*is_secondary_dex*/ false);
347     return ref_profile + SNAPSHOT_PROFILE_EXT;
348 }
349 
get_known_users(const char * volume_uuid)350 std::vector<userid_t> get_known_users(const char* volume_uuid) {
351     std::vector<userid_t> users;
352 
353     // We always have an owner
354     users.push_back(0);
355 
356     std::string path(create_data_path(volume_uuid) + "/" + SECONDARY_USER_PREFIX);
357     DIR* dir = opendir(path.c_str());
358     if (dir == nullptr) {
359         // Unable to discover other users, but at least return owner
360         PLOG(ERROR) << "Failed to opendir " << path;
361         return users;
362     }
363 
364     struct dirent* ent;
365     while ((ent = readdir(dir))) {
366         if (ent->d_type != DT_DIR) {
367             continue;
368         }
369 
370         char* end;
371         userid_t user = strtol(ent->d_name, &end, 10);
372         if (*end == '\0' && user != 0) {
373             LOG(DEBUG) << "Found valid user " << user;
374             users.push_back(user);
375         }
376     }
377     closedir(dir);
378 
379     return users;
380 }
381 
calculate_tree_size(const std::string & path,int64_t * size,int32_t include_gid,int32_t exclude_gid,bool exclude_apps)382 int calculate_tree_size(const std::string& path, int64_t* size,
383         int32_t include_gid, int32_t exclude_gid, bool exclude_apps) {
384     FTS *fts;
385     FTSENT *p;
386     int64_t matchedSize = 0;
387     char *argv[] = { (char*) path.c_str(), nullptr };
388     if (!(fts = fts_open(argv, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, nullptr))) {
389         if (errno != ENOENT) {
390             PLOG(ERROR) << "Failed to fts_open " << path;
391         }
392         return -1;
393     }
394     while ((p = fts_read(fts)) != nullptr) {
395         switch (p->fts_info) {
396         case FTS_D:
397         case FTS_DEFAULT:
398         case FTS_F:
399         case FTS_SL:
400         case FTS_SLNONE:
401             int32_t uid = p->fts_statp->st_uid;
402             int32_t gid = p->fts_statp->st_gid;
403             int32_t user_uid = multiuser_get_app_id(uid);
404             int32_t user_gid = multiuser_get_app_id(gid);
405             if (exclude_apps && ((user_uid >= AID_APP_START && user_uid <= AID_APP_END)
406                     || (user_gid >= AID_CACHE_GID_START && user_gid <= AID_CACHE_GID_END)
407                     || (user_gid >= AID_SHARED_GID_START && user_gid <= AID_SHARED_GID_END))) {
408                 // Don't traverse inside or measure
409                 fts_set(fts, p, FTS_SKIP);
410                 break;
411             }
412             if (include_gid != -1 && gid != include_gid) {
413                 break;
414             }
415             if (exclude_gid != -1 && gid == exclude_gid) {
416                 break;
417             }
418             matchedSize += (p->fts_statp->st_blocks * 512);
419             break;
420         }
421     }
422     fts_close(fts);
423 #if MEASURE_DEBUG
424     if ((include_gid == -1) && (exclude_gid == -1)) {
425         LOG(DEBUG) << "Measured " << path << " size " << matchedSize;
426     } else {
427         LOG(DEBUG) << "Measured " << path << " size " << matchedSize << "; include " << include_gid
428                 << " exclude " << exclude_gid;
429     }
430 #endif
431     *size += matchedSize;
432     return 0;
433 }
434 
435 /**
436  * Checks whether the package name is valid. Returns -1 on error and
437  * 0 on success.
438  */
is_valid_package_name(const std::string & packageName)439 bool is_valid_package_name(const std::string& packageName) {
440     // This logic is borrowed from PackageParser.java
441     bool hasSep = false;
442     bool front = true;
443 
444     auto it = packageName.begin();
445     for (; it != packageName.end() && *it != '-'; it++) {
446         char c = *it;
447         if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
448             front = false;
449             continue;
450         }
451         if (!front) {
452             if ((c >= '0' && c <= '9') || c == '_') {
453                 continue;
454             }
455         }
456         if (c == '.') {
457             hasSep = true;
458             front = true;
459             continue;
460         }
461         LOG(WARNING) << "Bad package character " << c << " in " << packageName;
462         return false;
463     }
464 
465     if (front) {
466         LOG(WARNING) << "Missing separator in " << packageName;
467         return false;
468     }
469 
470     for (; it != packageName.end(); it++) {
471         char c = *it;
472         if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) continue;
473         if ((c >= '0' && c <= '9') || c == '_' || c == '-' || c == '=') continue;
474         LOG(WARNING) << "Bad suffix character " << c << " in " << packageName;
475         return false;
476     }
477 
478     return true;
479 }
480 
_delete_dir_contents(DIR * d,int (* exclusion_predicate)(const char * name,const int is_dir))481 static int _delete_dir_contents(DIR *d,
482                                 int (*exclusion_predicate)(const char *name, const int is_dir))
483 {
484     int result = 0;
485     struct dirent *de;
486     int dfd;
487 
488     dfd = dirfd(d);
489 
490     if (dfd < 0) return -1;
491 
492     while ((de = readdir(d))) {
493         const char *name = de->d_name;
494 
495             /* check using the exclusion predicate, if provided */
496         if (exclusion_predicate && exclusion_predicate(name, (de->d_type == DT_DIR))) {
497             continue;
498         }
499 
500         if (de->d_type == DT_DIR) {
501             int subfd;
502             DIR *subdir;
503 
504                 /* always skip "." and ".." */
505             if (name[0] == '.') {
506                 if (name[1] == 0) continue;
507                 if ((name[1] == '.') && (name[2] == 0)) continue;
508             }
509 
510             subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC);
511             if (subfd < 0) {
512                 ALOGE("Couldn't openat %s: %s\n", name, strerror(errno));
513                 result = -1;
514                 continue;
515             }
516             subdir = fdopendir(subfd);
517             if (subdir == nullptr) {
518                 ALOGE("Couldn't fdopendir %s: %s\n", name, strerror(errno));
519                 close(subfd);
520                 result = -1;
521                 continue;
522             }
523             if (_delete_dir_contents(subdir, exclusion_predicate)) {
524                 result = -1;
525             }
526             closedir(subdir);
527             if (unlinkat(dfd, name, AT_REMOVEDIR) < 0) {
528                 ALOGE("Couldn't unlinkat %s: %s\n", name, strerror(errno));
529                 result = -1;
530             }
531         } else {
532             if (unlinkat(dfd, name, 0) < 0) {
533                 ALOGE("Couldn't unlinkat %s: %s\n", name, strerror(errno));
534                 result = -1;
535             }
536         }
537     }
538 
539     return result;
540 }
541 
create_dir_if_needed(const std::string & pathname,mode_t perms)542 int create_dir_if_needed(const std::string& pathname, mode_t perms) {
543     struct stat st;
544 
545     int rc;
546     if ((rc = stat(pathname.c_str(), &st)) != 0) {
547         if (errno == ENOENT) {
548             return mkdir(pathname.c_str(), perms);
549         } else {
550             return rc;
551         }
552     } else if (!S_ISDIR(st.st_mode)) {
553         LOG(DEBUG) << pathname << " is not a folder";
554         return -1;
555     }
556 
557     mode_t actual_perms = st.st_mode & ALLPERMS;
558     if (actual_perms != perms) {
559         LOG(WARNING) << pathname << " permissions " << actual_perms << " expected " << perms;
560         return -1;
561     }
562 
563     return 0;
564 }
565 
delete_dir_contents(const std::string & pathname,bool ignore_if_missing)566 int delete_dir_contents(const std::string& pathname, bool ignore_if_missing) {
567     return delete_dir_contents(pathname.c_str(), 0, nullptr, ignore_if_missing);
568 }
569 
delete_dir_contents_and_dir(const std::string & pathname,bool ignore_if_missing)570 int delete_dir_contents_and_dir(const std::string& pathname, bool ignore_if_missing) {
571     return delete_dir_contents(pathname.c_str(), 1, nullptr, ignore_if_missing);
572 }
573 
delete_dir_contents(const char * pathname,int also_delete_dir,int (* exclusion_predicate)(const char *,const int),bool ignore_if_missing)574 int delete_dir_contents(const char *pathname,
575                         int also_delete_dir,
576                         int (*exclusion_predicate)(const char*, const int),
577                         bool ignore_if_missing)
578 {
579     int res = 0;
580     DIR *d;
581 
582     d = opendir(pathname);
583     if (d == nullptr) {
584         if (ignore_if_missing && (errno == ENOENT)) {
585             return 0;
586         }
587         ALOGE("Couldn't opendir %s: %s\n", pathname, strerror(errno));
588         return -errno;
589     }
590     res = _delete_dir_contents(d, exclusion_predicate);
591     closedir(d);
592     if (also_delete_dir) {
593         if (rmdir(pathname)) {
594             ALOGE("Couldn't rmdir %s: %s\n", pathname, strerror(errno));
595             res = -1;
596         }
597     }
598     return res;
599 }
600 
delete_dir_contents_fd(int dfd,const char * name)601 int delete_dir_contents_fd(int dfd, const char *name)
602 {
603     int fd, res;
604     DIR *d;
605 
606     fd = openat(dfd, name, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC);
607     if (fd < 0) {
608         ALOGE("Couldn't openat %s: %s\n", name, strerror(errno));
609         return -1;
610     }
611     d = fdopendir(fd);
612     if (d == nullptr) {
613         ALOGE("Couldn't fdopendir %s: %s\n", name, strerror(errno));
614         close(fd);
615         return -1;
616     }
617     res = _delete_dir_contents(d, nullptr);
618     closedir(d);
619     return res;
620 }
621 
_copy_owner_permissions(int srcfd,int dstfd)622 static int _copy_owner_permissions(int srcfd, int dstfd)
623 {
624     struct stat st;
625     if (fstat(srcfd, &st) != 0) {
626         return -1;
627     }
628     if (fchmod(dstfd, st.st_mode) != 0) {
629         return -1;
630     }
631     return 0;
632 }
633 
_copy_dir_files(int sdfd,int ddfd,uid_t owner,gid_t group)634 static int _copy_dir_files(int sdfd, int ddfd, uid_t owner, gid_t group)
635 {
636     int result = 0;
637     if (_copy_owner_permissions(sdfd, ddfd) != 0) {
638         ALOGE("_copy_dir_files failed to copy dir permissions\n");
639     }
640     if (fchown(ddfd, owner, group) != 0) {
641         ALOGE("_copy_dir_files failed to change dir owner\n");
642     }
643 
644     DIR *ds = fdopendir(sdfd);
645     if (ds == nullptr) {
646         ALOGE("Couldn't fdopendir: %s\n", strerror(errno));
647         return -1;
648     }
649     struct dirent *de;
650     while ((de = readdir(ds))) {
651         if (de->d_type != DT_REG) {
652             continue;
653         }
654 
655         const char *name = de->d_name;
656         int fsfd = openat(sdfd, name, O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
657         int fdfd = openat(ddfd, name, O_WRONLY | O_NOFOLLOW | O_CLOEXEC | O_CREAT, 0600);
658         if (fsfd == -1 || fdfd == -1) {
659             ALOGW("Couldn't copy %s: %s\n", name, strerror(errno));
660         } else {
661             if (_copy_owner_permissions(fsfd, fdfd) != 0) {
662                 ALOGE("Failed to change file permissions\n");
663             }
664             if (fchown(fdfd, owner, group) != 0) {
665                 ALOGE("Failed to change file owner\n");
666             }
667 
668             char buf[8192];
669             ssize_t size;
670             while ((size = read(fsfd, buf, sizeof(buf))) > 0) {
671                 write(fdfd, buf, size);
672             }
673             if (size < 0) {
674                 ALOGW("Couldn't copy %s: %s\n", name, strerror(errno));
675                 result = -1;
676             }
677         }
678         close(fdfd);
679         close(fsfd);
680     }
681 
682     return result;
683 }
684 
copy_dir_files(const char * srcname,const char * dstname,uid_t owner,uid_t group)685 int copy_dir_files(const char *srcname,
686                    const char *dstname,
687                    uid_t owner,
688                    uid_t group)
689 {
690     int res = 0;
691     DIR *ds = nullptr;
692     DIR *dd = nullptr;
693 
694     ds = opendir(srcname);
695     if (ds == nullptr) {
696         ALOGE("Couldn't opendir %s: %s\n", srcname, strerror(errno));
697         return -errno;
698     }
699 
700     mkdir(dstname, 0600);
701     dd = opendir(dstname);
702     if (dd == nullptr) {
703         ALOGE("Couldn't opendir %s: %s\n", dstname, strerror(errno));
704         closedir(ds);
705         return -errno;
706     }
707 
708     int sdfd = dirfd(ds);
709     int ddfd = dirfd(dd);
710     if (sdfd != -1 && ddfd != -1) {
711         res = _copy_dir_files(sdfd, ddfd, owner, group);
712     } else {
713         res = -errno;
714     }
715     closedir(dd);
716     closedir(ds);
717     return res;
718 }
719 
data_disk_free(const std::string & data_path)720 int64_t data_disk_free(const std::string& data_path) {
721     struct statvfs sfs;
722     if (statvfs(data_path.c_str(), &sfs) == 0) {
723         return static_cast<int64_t>(sfs.f_bavail) * sfs.f_frsize;
724     } else {
725         PLOG(ERROR) << "Couldn't statvfs " << data_path;
726         return -1;
727     }
728 }
729 
get_path_inode(const std::string & path,ino_t * inode)730 int get_path_inode(const std::string& path, ino_t *inode) {
731     struct stat buf;
732     memset(&buf, 0, sizeof(buf));
733     if (stat(path.c_str(), &buf) != 0) {
734         PLOG(WARNING) << "Failed to stat " << path;
735         return -1;
736     } else {
737         *inode = buf.st_ino;
738         return 0;
739     }
740 }
741 
742 /**
743  * Write the inode of a specific child file into the given xattr on the
744  * parent directory. This allows you to find the child later, even if its
745  * name is encrypted.
746  */
write_path_inode(const std::string & parent,const char * name,const char * inode_xattr)747 int write_path_inode(const std::string& parent, const char* name, const char* inode_xattr) {
748     ino_t inode = 0;
749     uint64_t inode_raw = 0;
750     auto path = StringPrintf("%s/%s", parent.c_str(), name);
751 
752     if (get_path_inode(path, &inode) != 0) {
753         // Path probably doesn't exist yet; ignore
754         return 0;
755     }
756 
757     // Check to see if already set correctly
758     if (getxattr(parent.c_str(), inode_xattr, &inode_raw, sizeof(inode_raw)) == sizeof(inode_raw)) {
759         if (inode_raw == inode) {
760             // Already set correctly; skip writing
761             return 0;
762         } else {
763             PLOG(WARNING) << "Mismatched inode value; found " << inode
764                     << " on disk but marked value was " << inode_raw << "; overwriting";
765         }
766     }
767 
768     inode_raw = inode;
769     if (setxattr(parent.c_str(), inode_xattr, &inode_raw, sizeof(inode_raw), 0) != 0 && errno != EOPNOTSUPP) {
770         PLOG(ERROR) << "Failed to write xattr " << inode_xattr << " at " << parent;
771         return -1;
772     } else {
773         return 0;
774     }
775 }
776 
777 /**
778  * Read the inode of a specific child file from the given xattr on the
779  * parent directory. Returns a currently valid path for that child, which
780  * might have an encrypted name.
781  */
read_path_inode(const std::string & parent,const char * name,const char * inode_xattr)782 std::string read_path_inode(const std::string& parent, const char* name, const char* inode_xattr) {
783     ino_t inode = 0;
784     uint64_t inode_raw = 0;
785     auto fallback = StringPrintf("%s/%s", parent.c_str(), name);
786 
787     // Lookup the inode value written earlier
788     if (getxattr(parent.c_str(), inode_xattr, &inode_raw, sizeof(inode_raw)) == sizeof(inode_raw)) {
789         inode = inode_raw;
790     }
791 
792     // For testing purposes, rely on the inode when defined; this could be
793     // optimized to use access() in the future.
794     if (inode != 0) {
795         DIR* dir = opendir(parent.c_str());
796         if (dir == nullptr) {
797             PLOG(ERROR) << "Failed to opendir " << parent;
798             return fallback;
799         }
800 
801         struct dirent* ent;
802         while ((ent = readdir(dir))) {
803             if (ent->d_ino == inode) {
804                 auto resolved = StringPrintf("%s/%s", parent.c_str(), ent->d_name);
805 #if DEBUG_XATTRS
806                 if (resolved != fallback) {
807                     LOG(DEBUG) << "Resolved path " << resolved << " for inode " << inode
808                             << " instead of " << fallback;
809                 }
810 #endif
811                 closedir(dir);
812                 return resolved;
813             }
814         }
815         LOG(WARNING) << "Failed to resolve inode " << inode << "; using " << fallback;
816         closedir(dir);
817         return fallback;
818     } else {
819         return fallback;
820     }
821 }
822 
remove_path_xattr(const std::string & path,const char * inode_xattr)823 void remove_path_xattr(const std::string& path, const char* inode_xattr) {
824     if (removexattr(path.c_str(), inode_xattr) && errno != ENODATA) {
825         PLOG(ERROR) << "Failed to remove xattr " << inode_xattr << " at " << path;
826     }
827 }
828 
829 /**
830  * Validate that the path is valid in the context of the provided directory.
831  * The path is allowed to have at most one subdirectory and no indirections
832  * to top level directories (i.e. have "..").
833  */
validate_path(const std::string & dir,const std::string & path,int maxSubdirs)834 static int validate_path(const std::string& dir, const std::string& path, int maxSubdirs) {
835     // Argument sanity checking
836     if (dir.find('/') != 0 || dir.rfind('/') != dir.size() - 1
837             || dir.find("..") != std::string::npos) {
838         LOG(ERROR) << "Invalid directory " << dir;
839         return -1;
840     }
841     if (path.find("..") != std::string::npos) {
842         LOG(ERROR) << "Invalid path " << path;
843         return -1;
844     }
845 
846     if (path.compare(0, dir.size(), dir) != 0) {
847         // Common case, path isn't under directory
848         return -1;
849     }
850 
851     // Count number of subdirectories
852     auto pos = path.find('/', dir.size());
853     int count = 0;
854     while (pos != std::string::npos) {
855         auto next = path.find('/', pos + 1);
856         if (next > pos + 1) {
857             count++;
858         }
859         pos = next;
860     }
861 
862     if (count > maxSubdirs) {
863         LOG(ERROR) << "Invalid path depth " << path << " when tested against " << dir;
864         return -1;
865     }
866 
867     return 0;
868 }
869 
870 /**
871  * Checks whether a path points to a system app (.apk file). Returns 0
872  * if it is a system app or -1 if it is not.
873  */
validate_system_app_path(const char * path)874 int validate_system_app_path(const char* path) {
875     std::string path_ = path;
876     for (const auto& dir : android_system_dirs) {
877         if (validate_path(dir, path, 1) == 0) {
878             return 0;
879         }
880     }
881     return -1;
882 }
883 
validate_secondary_dex_path(const std::string & pkgname,const std::string & dex_path,const char * volume_uuid,int uid,int storage_flag)884 bool validate_secondary_dex_path(const std::string& pkgname, const std::string& dex_path,
885         const char* volume_uuid, int uid, int storage_flag) {
886     CHECK(storage_flag == FLAG_STORAGE_CE || storage_flag == FLAG_STORAGE_DE);
887 
888     // Empty paths are not allowed.
889     if (dex_path.empty()) { return false; }
890     // First character should always be '/'. No relative paths.
891     if (dex_path[0] != '/') { return false; }
892     // The last character should not be '/'.
893     if (dex_path[dex_path.size() - 1] == '/') { return false; }
894     // There should be no '.' after the directory marker.
895     if (dex_path.find("/.") != std::string::npos) { return false; }
896     // The path should be at most PKG_PATH_MAX long.
897     if (dex_path.size() > PKG_PATH_MAX) { return false; }
898 
899     // The dex_path should be under the app data directory.
900     std::string app_private_dir = storage_flag == FLAG_STORAGE_CE
901             ? create_data_user_ce_package_path(
902                     volume_uuid, multiuser_get_user_id(uid), pkgname.c_str())
903             : create_data_user_de_package_path(
904                     volume_uuid, multiuser_get_user_id(uid), pkgname.c_str());
905 
906     if (strncmp(dex_path.c_str(), app_private_dir.c_str(), app_private_dir.size()) != 0) {
907         // The check above might fail if the dex file is accessed via the /data/user/0 symlink.
908         // If that's the case, attempt to validate against the user data link.
909         std::string app_private_dir_symlink = create_data_user_ce_package_path_as_user_link(
910                 volume_uuid, multiuser_get_user_id(uid), pkgname.c_str());
911         if (strncmp(dex_path.c_str(), app_private_dir_symlink.c_str(),
912                 app_private_dir_symlink.size()) != 0) {
913             return false;
914         }
915     }
916 
917     // If we got here we have a valid path.
918     return true;
919 }
920 
921 /**
922  * Check whether path points to a valid path for an APK file. The path must
923  * begin with a whitelisted prefix path and must be no deeper than |maxSubdirs| within
924  * that path. Returns -1 when an invalid path is encountered and 0 when a valid path
925  * is encountered.
926  */
validate_apk_path_internal(const std::string & path,int maxSubdirs)927 static int validate_apk_path_internal(const std::string& path, int maxSubdirs) {
928     if (validate_path(android_app_dir, path, maxSubdirs) == 0) {
929         return 0;
930     } else if (validate_path(android_staging_dir, path, maxSubdirs) == 0) {
931         return 0;
932     } else if (validate_path(android_app_private_dir, path, maxSubdirs) == 0) {
933         return 0;
934     } else if (validate_path(android_app_ephemeral_dir, path, maxSubdirs) == 0) {
935         return 0;
936     } else if (validate_path(android_asec_dir, path, maxSubdirs) == 0) {
937         return 0;
938     } else if (android::base::StartsWith(path, android_mnt_expand_dir)) {
939         // Rewrite the path as if it were on internal storage, and test that
940         size_t end = path.find('/', android_mnt_expand_dir.size() + 1);
941         if (end != std::string::npos) {
942             auto modified = path;
943             modified.replace(0, end + 1, android_data_dir);
944             return validate_apk_path_internal(modified, maxSubdirs);
945         }
946     }
947     return -1;
948 }
949 
validate_apk_path(const char * path)950 int validate_apk_path(const char* path) {
951     return validate_apk_path_internal(path, 2 /* maxSubdirs */);
952 }
953 
validate_apk_path_subdirs(const char * path)954 int validate_apk_path_subdirs(const char* path) {
955     return validate_apk_path_internal(path, 4 /* maxSubdirs */);
956 }
957 
ensure_config_user_dirs(userid_t userid)958 int ensure_config_user_dirs(userid_t userid) {
959     // writable by system, readable by any app within the same user
960     const int uid = multiuser_get_uid(userid, AID_SYSTEM);
961     const int gid = multiuser_get_uid(userid, AID_EVERYBODY);
962 
963     // Ensure /data/misc/user/<userid> exists
964     auto path = create_data_misc_legacy_path(userid);
965     return fs_prepare_dir(path.c_str(), 0750, uid, gid);
966 }
967 
wait_child(pid_t pid)968 int wait_child(pid_t pid)
969 {
970     int status;
971     pid_t got_pid;
972 
973     while (1) {
974         got_pid = waitpid(pid, &status, 0);
975         if (got_pid == -1 && errno == EINTR) {
976             printf("waitpid interrupted, retrying\n");
977         } else {
978             break;
979         }
980     }
981     if (got_pid != pid) {
982         ALOGW("waitpid failed: wanted %d, got %d: %s\n",
983             (int) pid, (int) got_pid, strerror(errno));
984         return 1;
985     }
986 
987     if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
988         return 0;
989     } else {
990         return status;      /* always nonzero */
991     }
992 }
993 
994 /**
995  * Prepare an app cache directory, which offers to fix-up the GID and
996  * directory mode flags during a platform upgrade.
997  * The app cache directory path will be 'parent'/'name'.
998  */
prepare_app_cache_dir(const std::string & parent,const char * name,mode_t target_mode,uid_t uid,gid_t gid)999 int prepare_app_cache_dir(const std::string& parent, const char* name, mode_t target_mode,
1000         uid_t uid, gid_t gid) {
1001     auto path = StringPrintf("%s/%s", parent.c_str(), name);
1002     struct stat st;
1003     if (stat(path.c_str(), &st) != 0) {
1004         if (errno == ENOENT) {
1005             // This is fine, just create it
1006             if (fs_prepare_dir_strict(path.c_str(), target_mode, uid, gid) != 0) {
1007                 PLOG(ERROR) << "Failed to prepare " << path;
1008                 return -1;
1009             } else {
1010                 return 0;
1011             }
1012         } else {
1013             PLOG(ERROR) << "Failed to stat " << path;
1014             return -1;
1015         }
1016     }
1017 
1018     mode_t actual_mode = st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO | S_ISGID);
1019     if (st.st_uid != uid) {
1020         // Mismatched UID is real trouble; we can't recover
1021         LOG(ERROR) << "Mismatched UID at " << path << ": found " << st.st_uid
1022                 << " but expected " << uid;
1023         return -1;
1024     } else if (st.st_gid == gid && actual_mode == target_mode) {
1025         // Everything looks good!
1026         return 0;
1027     } else {
1028         // Mismatched GID/mode is recoverable; fall through to update
1029         LOG(DEBUG) << "Mismatched cache GID/mode at " << path << ": found " << st.st_gid
1030                 << "/" << actual_mode << " but expected " << gid << "/" << target_mode;
1031     }
1032 
1033     // Directory is owned correctly, but GID or mode mismatch means it's
1034     // probably a platform upgrade so we need to fix them
1035     FTS *fts;
1036     FTSENT *p;
1037     char *argv[] = { (char*) path.c_str(), nullptr };
1038     if (!(fts = fts_open(argv, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, nullptr))) {
1039         PLOG(ERROR) << "Failed to fts_open " << path;
1040         return -1;
1041     }
1042     while ((p = fts_read(fts)) != nullptr) {
1043         switch (p->fts_info) {
1044         case FTS_DP:
1045             if (chmod(p->fts_path, target_mode) != 0) {
1046                 PLOG(WARNING) << "Failed to chmod " << p->fts_path;
1047             }
1048             [[fallthrough]]; // to also set GID
1049         case FTS_F:
1050             if (chown(p->fts_path, -1, gid) != 0) {
1051                 PLOG(WARNING) << "Failed to chown " << p->fts_path;
1052             }
1053             break;
1054         case FTS_SL:
1055         case FTS_SLNONE:
1056             if (lchown(p->fts_path, -1, gid) != 0) {
1057                 PLOG(WARNING) << "Failed to chown " << p->fts_path;
1058             }
1059             break;
1060         }
1061     }
1062     fts_close(fts);
1063     return 0;
1064 }
1065 
1066 static const char* kProcFilesystems = "/proc/filesystems";
supports_sdcardfs()1067 bool supports_sdcardfs() {
1068     std::string supported;
1069     if (!android::base::ReadFileToString(kProcFilesystems, &supported)) {
1070         PLOG(ERROR) << "Failed to read supported filesystems";
1071         return false;
1072     }
1073     return supported.find("sdcardfs\n") != std::string::npos;
1074 }
1075 
get_occupied_app_space_external(const std::string & uuid,int32_t userId,int32_t appId)1076 int64_t get_occupied_app_space_external(const std::string& uuid, int32_t userId, int32_t appId) {
1077     static const bool supportsSdcardFs = supports_sdcardfs();
1078 
1079     if (supportsSdcardFs) {
1080         int extGid = multiuser_get_ext_gid(userId, appId);
1081 
1082         if (extGid == -1) {
1083             return -1;
1084         }
1085 
1086         return GetOccupiedSpaceForGid(uuid, extGid);
1087     } else {
1088         uid_t uid = multiuser_get_uid(userId, appId);
1089         long projectId = uid - AID_APP_START + PROJECT_ID_EXT_DATA_START;
1090         return GetOccupiedSpaceForProjectId(uuid, projectId);
1091     }
1092 }
get_occupied_app_cache_space_external(const std::string & uuid,int32_t userId,int32_t appId)1093 int64_t get_occupied_app_cache_space_external(const std::string& uuid, int32_t userId, int32_t appId) {
1094     static const bool supportsSdcardFs = supports_sdcardfs();
1095 
1096     if (supportsSdcardFs) {
1097         int extCacheGid = multiuser_get_ext_cache_gid(userId, appId);
1098 
1099         if (extCacheGid == -1) {
1100             return -1;
1101         }
1102 
1103         return GetOccupiedSpaceForGid(uuid, extCacheGid);
1104     } else {
1105         uid_t uid = multiuser_get_uid(userId, appId);
1106         long projectId = uid - AID_APP_START + PROJECT_ID_EXT_CACHE_START;
1107         return GetOccupiedSpaceForProjectId(uuid, projectId);
1108     }
1109 }
1110 
1111 // Collect all non empty profiles from the given directory and puts then into profile_paths.
1112 // The profiles are identified based on PROFILE_EXT extension.
1113 // If a subdirectory or profile file cannot be opened the method logs a warning and moves on.
1114 // It returns true if there were no errors at all, and false otherwise.
collect_profiles(DIR * d,const std::string & current_path,std::vector<std::string> * profiles_paths)1115 static bool collect_profiles(DIR* d,
1116                              const std::string& current_path,
1117                              std::vector<std::string>* profiles_paths) {
1118     int32_t dir_fd = dirfd(d);
1119     if (dir_fd < 0) {
1120         return false;
1121     }
1122 
1123     bool result = true;
1124     struct dirent* dir_entry;
1125     while ((dir_entry = readdir(d))) {
1126         std::string name = dir_entry->d_name;
1127         std::string local_path = current_path + "/" + name;
1128 
1129         if (dir_entry->d_type == DT_REG) {
1130             // Check if this is a non empty profile file.
1131             if (EndsWith(name, PROFILE_EXT)) {
1132                 struct stat st;
1133                 if (stat(local_path.c_str(), &st) != 0) {
1134                     PLOG(WARNING) << "Cannot stat local path " << local_path;
1135                     result = false;
1136                     continue;
1137                 } else if (st.st_size > 0) {
1138                     profiles_paths->push_back(local_path);
1139                 }
1140             }
1141         } else if (dir_entry->d_type == DT_DIR) {
1142             // always skip "." and ".."
1143             if (name == "." || name == "..") {
1144                 continue;
1145             }
1146 
1147             unique_fd subdir_fd(openat(dir_fd, name.c_str(),
1148                     O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC));
1149             if (subdir_fd < 0) {
1150                 PLOG(WARNING) << "Could not open dir path " << local_path;
1151                 result = false;
1152                 continue;
1153             }
1154 
1155             DIR* subdir = Fdopendir(std::move(subdir_fd));
1156             if (subdir == nullptr) {
1157                 PLOG(WARNING) << "Could not open dir path " << local_path;
1158                 result = false;
1159                 continue;
1160             }
1161             bool new_result = collect_profiles(subdir, local_path, profiles_paths);
1162             result = result && new_result;
1163             if (closedir(subdir) != 0) {
1164                 PLOG(WARNING) << "Could not close dir path " << local_path;
1165             }
1166         }
1167     }
1168 
1169     return result;
1170 }
1171 
collect_profiles(std::vector<std::string> * profiles_paths)1172 bool collect_profiles(std::vector<std::string>* profiles_paths) {
1173     DIR* d = opendir(android_profiles_dir.c_str());
1174     if (d == nullptr) {
1175         return false;
1176     } else {
1177         return collect_profiles(d, android_profiles_dir, profiles_paths);
1178     }
1179 }
1180 
drop_capabilities(uid_t uid)1181 void drop_capabilities(uid_t uid) {
1182     if (setgid(uid) != 0) {
1183         PLOG(ERROR) << "setgid(" << uid << ") failed in installd during dexopt";
1184         exit(DexoptReturnCodes::kSetGid);
1185     }
1186     if (setuid(uid) != 0) {
1187         PLOG(ERROR) << "setuid(" << uid << ") failed in installd during dexopt";
1188         exit(DexoptReturnCodes::kSetUid);
1189     }
1190     // drop capabilities
1191     struct __user_cap_header_struct capheader;
1192     struct __user_cap_data_struct capdata[2];
1193     memset(&capheader, 0, sizeof(capheader));
1194     memset(&capdata, 0, sizeof(capdata));
1195     capheader.version = _LINUX_CAPABILITY_VERSION_3;
1196     if (capset(&capheader, &capdata[0]) < 0) {
1197         PLOG(ERROR) << "capset failed";
1198         exit(DexoptReturnCodes::kCapSet);
1199     }
1200 }
1201 
1202 }  // namespace installd
1203 }  // namespace android
1204