xref: /aosp_15_r20/frameworks/native/cmds/installd/tests/installd_service_test.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1 /*
2  * Copyright (C) 2017 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 <sstream>
18 #include <string>
19 
20 #include <fcntl.h>
21 #include <pwd.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <sys/stat.h>
25 #include <sys/statvfs.h>
26 #include <sys/xattr.h>
27 
28 #include <android-base/file.h>
29 #include <android-base/logging.h>
30 #include <android-base/properties.h>
31 #include <android-base/scopeguard.h>
32 #include <android-base/stringprintf.h>
33 #include <cutils/properties.h>
34 #include <gtest/gtest.h>
35 #include <filesystem>
36 #include <fstream>
37 
38 #include <android/content/pm/IPackageManagerNative.h>
39 #include <binder/IServiceManager.h>
40 #include "InstalldNativeService.h"
41 #include "binder/Status.h"
42 #include "binder_test_utils.h"
43 #include "dexopt.h"
44 #include "globals.h"
45 #include "unique_file.h"
46 #include "utils.h"
47 
48 using android::base::StringPrintf;
49 using android::base::unique_fd;
50 using android::os::ParcelFileDescriptor;
51 using std::filesystem::is_empty;
52 
53 namespace android {
get_package_name(uid_t uid)54 std::string get_package_name(uid_t uid) {
55     sp<IServiceManager> sm = defaultServiceManager();
56     sp<content::pm::IPackageManagerNative> package_mgr;
57     if (sm.get() == nullptr) {
58         LOG(INFO) << "Cannot find service manager";
59     } else {
60         sp<IBinder> binder = sm->getService(String16("package_native"));
61         if (binder.get() == nullptr) {
62             LOG(INFO) << "Cannot find package_native";
63         } else {
64             package_mgr = interface_cast<content::pm::IPackageManagerNative>(binder);
65         }
66     }
67     // find package name
68     std::string pkg;
69     if (package_mgr != nullptr) {
70         std::vector<std::string> names;
71         binder::Status status = package_mgr->getNamesForUids({(int)uid}, &names);
72         if (!status.isOk()) {
73             LOG(INFO) << "getNamesForUids failed: %s", status.exceptionMessage().c_str();
74         } else {
75             if (!names[0].empty()) {
76                 pkg = names[0].c_str();
77             }
78         }
79     }
80     return pkg;
81 }
82 namespace installd {
83 
84 static constexpr const char* kTestUuid = "TEST";
85 static const std::string kTestPath = "/data/local/tmp";
86 static constexpr const uid_t kNobodyUid = 9999;
87 static constexpr const uid_t kSystemUid = 1000;
88 static constexpr const int32_t kTestUserId = 0;
89 static constexpr const uid_t kTestAppId = 19999;
90 static constexpr const int FLAG_STORAGE_SDK = InstalldNativeService::FLAG_STORAGE_SDK;
91 static constexpr const int FLAG_CLEAR_CACHE_ONLY = InstalldNativeService::FLAG_CLEAR_CACHE_ONLY;
92 static constexpr const int FLAG_CLEAR_CODE_CACHE_ONLY =
93         InstalldNativeService::FLAG_CLEAR_CODE_CACHE_ONLY;
94 
95 const gid_t kTestAppUid = multiuser_get_uid(kTestUserId, kTestAppId);
96 const gid_t kTestCacheGid = multiuser_get_cache_gid(kTestUserId, kTestAppId);
97 const uid_t kTestSdkSandboxUid = multiuser_get_sdk_sandbox_uid(kTestUserId, kTestAppId);
98 
99 #define FLAG_FORCE InstalldNativeService::FLAG_FORCE
100 
get_property(const char * key,char * value,const char * default_value)101 int get_property(const char *key, char *value, const char *default_value) {
102     return property_get(key, value, default_value);
103 }
104 
calculate_oat_file_path(char path[PKG_PATH_MAX],const char * oat_dir,const char * apk_path,const char * instruction_set)105 bool calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path,
106         const char *instruction_set) {
107     return calculate_oat_file_path_default(path, oat_dir, apk_path, instruction_set);
108 }
109 
calculate_odex_file_path(char path[PKG_PATH_MAX],const char * apk_path,const char * instruction_set)110 bool calculate_odex_file_path(char path[PKG_PATH_MAX], const char *apk_path,
111         const char *instruction_set) {
112     return calculate_odex_file_path_default(path, apk_path, instruction_set);
113 }
114 
create_cache_path(char path[PKG_PATH_MAX],const char * src,const char * instruction_set)115 bool create_cache_path(char path[PKG_PATH_MAX], const char *src, const char *instruction_set) {
116     return create_cache_path_default(path, src, instruction_set);
117 }
118 
force_compile_without_image()119 bool force_compile_without_image() {
120     return false;
121 }
122 
get_full_path(const std::string & path)123 static std::string get_full_path(const std::string& path) {
124     return StringPrintf("%s/%s", kTestPath.c_str(), path.c_str());
125 }
126 
mkdir(const std::string & path,uid_t owner,gid_t group,mode_t mode)127 static void mkdir(const std::string& path, uid_t owner, gid_t group, mode_t mode) {
128     const std::string fullPath = get_full_path(path);
129     EXPECT_EQ(::mkdir(fullPath.c_str(), mode), 0);
130     EXPECT_EQ(::chown(fullPath.c_str(), owner, group), 0);
131     EXPECT_EQ(::chmod(fullPath.c_str(), mode), 0);
132 }
133 
create(const std::string & path,uid_t owner,gid_t group,mode_t mode)134 static int create(const std::string& path, uid_t owner, gid_t group, mode_t mode) {
135     int fd = ::open(get_full_path(path).c_str(), O_RDWR | O_CREAT, mode);
136     EXPECT_NE(fd, -1);
137     EXPECT_EQ(::fchown(fd, owner, group), 0);
138     EXPECT_EQ(::fchmod(fd, mode), 0);
139     return fd;
140 }
141 
create_with_content(const std::string & path,uid_t owner,gid_t group,mode_t mode,const std::string & content)142 static void create_with_content(const std::string& path, uid_t owner, gid_t group, mode_t mode,
143                                 const std::string& content) {
144     int fd = ::open(path.c_str(), O_RDWR | O_CREAT, mode);
145     EXPECT_NE(fd, -1);
146     EXPECT_TRUE(android::base::WriteStringToFd(content, fd));
147     EXPECT_EQ(::fchown(fd, owner, group), 0);
148     EXPECT_EQ(::fchmod(fd, mode), 0);
149     close(fd);
150 }
151 
touch(const std::string & path,uid_t owner,gid_t group,mode_t mode)152 static void touch(const std::string& path, uid_t owner, gid_t group, mode_t mode) {
153     EXPECT_EQ(::close(create(path.c_str(), owner, group, mode)), 0);
154 }
155 
stat_gid(const char * path)156 static int stat_gid(const char* path) {
157     struct stat buf;
158     EXPECT_EQ(::stat(get_full_path(path).c_str(), &buf), 0);
159     return buf.st_gid;
160 }
161 
stat_mode(const char * path)162 static int stat_mode(const char* path) {
163     struct stat buf;
164     EXPECT_EQ(::stat(get_full_path(path).c_str(), &buf), 0);
165     return buf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO | S_ISGID);
166 }
167 
exists(const std::string & path)168 static bool exists(const std::string& path) {
169     return ::access(get_full_path(path).c_str(), F_OK) == 0;
170 }
171 
172 template <class Pred>
find_file(const char * path,Pred && pred)173 static bool find_file(const char* path, Pred&& pred) {
174     bool result = false;
175     auto d = opendir(path);
176     if (d == nullptr) {
177         return result;
178     }
179     struct dirent* de;
180     while ((de = readdir(d))) {
181         const char* name = de->d_name;
182         if (pred(name, de->d_type == DT_DIR)) {
183             result = true;
184             break;
185         }
186     }
187     closedir(d);
188     return result;
189 }
190 
exists_renamed_deleted_dir(const std::string & rootDirectory)191 static bool exists_renamed_deleted_dir(const std::string& rootDirectory) {
192     return find_file((kTestPath + rootDirectory).c_str(), [](const std::string& name, bool is_dir) {
193         return is_dir && is_renamed_deleted_dir(name);
194     });
195 }
196 
unlink_path(const std::string & path)197 static void unlink_path(const std::string& path) {
198     if (unlink(path.c_str()) < 0) {
199         PLOG(DEBUG) << "Failed to unlink " + path;
200     }
201 }
202 
203 class ServiceTest : public testing::Test {
204 protected:
205     InstalldNativeService* service;
206     std::optional<std::string> testUuid;
207 
SetUp()208     virtual void SetUp() {
209         setenv("ANDROID_LOG_TAGS", "*:v", 1);
210         android::base::InitLogging(nullptr);
211 
212         service = new InstalldNativeService();
213         testUuid = kTestUuid;
214         system("rm -rf /data/local/tmp/user");
215         system("rm -rf /data/local/tmp/misc_ce");
216         system("rm -rf /data/local/tmp/misc_de");
217         system("mkdir -p /data/local/tmp/user/0");
218         system("mkdir -p /data/local/tmp/misc_ce/0/sdksandbox");
219         system("mkdir -p /data/local/tmp/misc_de/0/sdksandbox");
220         init_globals_from_data_and_root();
221     }
222 
TearDown()223     virtual void TearDown() {
224         delete service;
225         system("rm -rf /data/local/tmp/user");
226         system("rm -rf /data/local/tmp/misc_ce");
227         system("rm -rf /data/local/tmp/misc_de");
228     }
229 };
230 
TEST_F(ServiceTest,FixupAppData_Upgrade)231 TEST_F(ServiceTest, FixupAppData_Upgrade) {
232     LOG(INFO) << "FixupAppData_Upgrade";
233 
234     mkdir("user/0/com.example", 10000, 10000, 0700);
235     mkdir("user/0/com.example/normal", 10000, 10000, 0700);
236     mkdir("user/0/com.example/cache", 10000, 10000, 0700);
237     touch("user/0/com.example/cache/file", 10000, 10000, 0700);
238 
239     service->fixupAppData(testUuid, 0);
240 
241     EXPECT_EQ(10000, stat_gid("user/0/com.example/normal"));
242     EXPECT_EQ(20000, stat_gid("user/0/com.example/cache"));
243     EXPECT_EQ(20000, stat_gid("user/0/com.example/cache/file"));
244 
245     EXPECT_EQ(0700, stat_mode("user/0/com.example/normal"));
246     EXPECT_EQ(02771, stat_mode("user/0/com.example/cache"));
247     EXPECT_EQ(0700, stat_mode("user/0/com.example/cache/file"));
248 }
249 
TEST_F(ServiceTest,FixupAppData_Moved)250 TEST_F(ServiceTest, FixupAppData_Moved) {
251     LOG(INFO) << "FixupAppData_Moved";
252 
253     mkdir("user/0/com.example", 10000, 10000, 0700);
254     mkdir("user/0/com.example/foo", 10000, 10000, 0700);
255     touch("user/0/com.example/foo/file", 10000, 20000, 0700);
256     mkdir("user/0/com.example/bar", 10000, 20000, 0700);
257     touch("user/0/com.example/bar/file", 10000, 20000, 0700);
258 
259     service->fixupAppData(testUuid, 0);
260 
261     EXPECT_EQ(10000, stat_gid("user/0/com.example/foo"));
262     EXPECT_EQ(20000, stat_gid("user/0/com.example/foo/file"));
263     EXPECT_EQ(10000, stat_gid("user/0/com.example/bar"));
264     EXPECT_EQ(10000, stat_gid("user/0/com.example/bar/file"));
265 
266     service->fixupAppData(testUuid, FLAG_FORCE);
267 
268     EXPECT_EQ(10000, stat_gid("user/0/com.example/foo"));
269     EXPECT_EQ(10000, stat_gid("user/0/com.example/foo/file"));
270     EXPECT_EQ(10000, stat_gid("user/0/com.example/bar"));
271     EXPECT_EQ(10000, stat_gid("user/0/com.example/bar/file"));
272 }
273 
TEST_F(ServiceTest,DestroyUserData)274 TEST_F(ServiceTest, DestroyUserData) {
275     LOG(INFO) << "DestroyUserData";
276 
277     mkdir("user/0/com.example", 10000, 10000, 0700);
278     mkdir("user/0/com.example/foo", 10000, 10000, 0700);
279     touch("user/0/com.example/foo/file", 10000, 20000, 0700);
280     mkdir("user/0/com.example/bar", 10000, 20000, 0700);
281     touch("user/0/com.example/bar/file", 10000, 20000, 0700);
282 
283     EXPECT_TRUE(exists("user/0/com.example/foo"));
284     EXPECT_TRUE(exists("user/0/com.example/foo/file"));
285     EXPECT_TRUE(exists("user/0/com.example/bar"));
286     EXPECT_TRUE(exists("user/0/com.example/bar/file"));
287 
288     service->destroyUserData(testUuid, 0, FLAG_STORAGE_DE | FLAG_STORAGE_CE);
289 
290     EXPECT_FALSE(exists("user/0/com.example/foo"));
291     EXPECT_FALSE(exists("user/0/com.example/foo/file"));
292     EXPECT_FALSE(exists("user/0/com.example/bar"));
293     EXPECT_FALSE(exists("user/0/com.example/bar/file"));
294 
295     EXPECT_FALSE(exists_renamed_deleted_dir("/user/0"));
296 }
297 
TEST_F(ServiceTest,DestroyAppData)298 TEST_F(ServiceTest, DestroyAppData) {
299     LOG(INFO) << "DestroyAppData";
300 
301     mkdir("user/0/com.example", 10000, 10000, 0700);
302     mkdir("user/0/com.example/foo", 10000, 10000, 0700);
303     touch("user/0/com.example/foo/file", 10000, 20000, 0700);
304     mkdir("user/0/com.example/bar", 10000, 20000, 0700);
305     touch("user/0/com.example/bar/file", 10000, 20000, 0700);
306 
307     EXPECT_TRUE(exists("user/0/com.example/foo"));
308     EXPECT_TRUE(exists("user/0/com.example/foo/file"));
309     EXPECT_TRUE(exists("user/0/com.example/bar"));
310     EXPECT_TRUE(exists("user/0/com.example/bar/file"));
311 
312     service->destroyAppData(testUuid, "com.example", 0, FLAG_STORAGE_DE | FLAG_STORAGE_CE, 0);
313 
314     EXPECT_FALSE(exists("user/0/com.example/foo"));
315     EXPECT_FALSE(exists("user/0/com.example/foo/file"));
316     EXPECT_FALSE(exists("user/0/com.example/bar"));
317     EXPECT_FALSE(exists("user/0/com.example/bar/file"));
318 
319     EXPECT_FALSE(exists_renamed_deleted_dir("/user/0"));
320 }
321 
TEST_F(ServiceTest,CleanupInvalidPackageDirs)322 TEST_F(ServiceTest, CleanupInvalidPackageDirs) {
323     LOG(INFO) << "CleanupInvalidPackageDirs";
324 
325     std::string rootDirectoryPrefix[] = {"user/0", "misc_ce/0/sdksandbox", "misc_de/0/sdksandbox"};
326     for (auto& prefix : rootDirectoryPrefix) {
327         mkdir(prefix + "/5b14b6458a44==deleted==", 10000, 10000, 0700);
328         mkdir(prefix + "/5b14b6458a44==deleted==/foo", 10000, 10000, 0700);
329         touch(prefix + "/5b14b6458a44==deleted==/foo/file", 10000, 20000, 0700);
330         mkdir(prefix + "/5b14b6458a44==deleted==/bar", 10000, 20000, 0700);
331         touch(prefix + "/5b14b6458a44==deleted==/bar/file", 10000, 20000, 0700);
332 
333         auto fd = create(prefix + "/5b14b6458a44==deleted==/bar/opened_file", 10000, 20000, 0700);
334 
335         mkdir(prefix + "/b14b6458a44NOTdeleted", 10000, 10000, 0700);
336         mkdir(prefix + "/b14b6458a44NOTdeleted/foo", 10000, 10000, 0700);
337         touch(prefix + "/b14b6458a44NOTdeleted/foo/file", 10000, 20000, 0700);
338         mkdir(prefix + "/b14b6458a44NOTdeleted/bar", 10000, 20000, 0700);
339         touch(prefix + "/b14b6458a44NOTdeleted/bar/file", 10000, 20000, 0700);
340 
341         mkdir(prefix + "/com.example", 10000, 10000, 0700);
342         mkdir(prefix + "/com.example/foo", 10000, 10000, 0700);
343         touch(prefix + "/com.example/foo/file", 10000, 20000, 0700);
344         mkdir(prefix + "/com.example/bar", 10000, 20000, 0700);
345         touch(prefix + "/com.example/bar/file", 10000, 20000, 0700);
346 
347         mkdir(prefix + "/==deleted==", 10000, 10000, 0700);
348         mkdir(prefix + "/==deleted==/foo", 10000, 10000, 0700);
349         touch(prefix + "/==deleted==/foo/file", 10000, 20000, 0700);
350         mkdir(prefix + "/==deleted==/bar", 10000, 20000, 0700);
351         touch(prefix + "/==deleted==/bar/file", 10000, 20000, 0700);
352 
353         EXPECT_TRUE(exists(prefix + "/5b14b6458a44==deleted==/foo"));
354         EXPECT_TRUE(exists(prefix + "/5b14b6458a44==deleted==/foo/file"));
355         EXPECT_TRUE(exists(prefix + "/5b14b6458a44==deleted==/bar"));
356         EXPECT_TRUE(exists(prefix + "/5b14b6458a44==deleted==/bar/file"));
357         EXPECT_TRUE(exists(prefix + "/5b14b6458a44==deleted==/bar/opened_file"));
358 
359         EXPECT_TRUE(exists(prefix + "/b14b6458a44NOTdeleted/foo"));
360         EXPECT_TRUE(exists(prefix + "/b14b6458a44NOTdeleted/foo/file"));
361         EXPECT_TRUE(exists(prefix + "/b14b6458a44NOTdeleted/bar"));
362         EXPECT_TRUE(exists(prefix + "/b14b6458a44NOTdeleted/bar/file"));
363 
364         EXPECT_TRUE(exists(prefix + "/com.example/foo"));
365         EXPECT_TRUE(exists(prefix + "/com.example/foo/file"));
366         EXPECT_TRUE(exists(prefix + "/com.example/bar"));
367         EXPECT_TRUE(exists(prefix + "/com.example/bar/file"));
368 
369         EXPECT_TRUE(exists(prefix + "/==deleted==/foo"));
370         EXPECT_TRUE(exists(prefix + "/==deleted==/foo/file"));
371         EXPECT_TRUE(exists(prefix + "/==deleted==/bar"));
372         EXPECT_TRUE(exists(prefix + "/==deleted==/bar/file"));
373 
374         EXPECT_TRUE(exists_renamed_deleted_dir("/" + prefix));
375 
376         service->cleanupInvalidPackageDirs(testUuid, 0, FLAG_STORAGE_CE | FLAG_STORAGE_DE);
377 
378         EXPECT_EQ(::close(fd), 0);
379 
380         EXPECT_FALSE(exists(prefix + "/5b14b6458a44==deleted==/foo"));
381         EXPECT_FALSE(exists(prefix + "/5b14b6458a44==deleted==/foo/file"));
382         EXPECT_FALSE(exists(prefix + "/5b14b6458a44==deleted==/bar"));
383         EXPECT_FALSE(exists(prefix + "/5b14b6458a44==deleted==/bar/file"));
384         EXPECT_FALSE(exists(prefix + "/5b14b6458a44==deleted==/bar/opened_file"));
385 
386         EXPECT_TRUE(exists(prefix + "/b14b6458a44NOTdeleted/foo"));
387         EXPECT_TRUE(exists(prefix + "/b14b6458a44NOTdeleted/foo/file"));
388         EXPECT_TRUE(exists(prefix + "/b14b6458a44NOTdeleted/bar"));
389         EXPECT_TRUE(exists(prefix + "/b14b6458a44NOTdeleted/bar/file"));
390 
391         EXPECT_TRUE(exists(prefix + "/com.example/foo"));
392         EXPECT_TRUE(exists(prefix + "/com.example/foo/file"));
393         EXPECT_TRUE(exists(prefix + "/com.example/bar"));
394         EXPECT_TRUE(exists(prefix + "/com.example/bar/file"));
395 
396         EXPECT_FALSE(exists(prefix + "/==deleted==/foo"));
397         EXPECT_FALSE(exists(prefix + "/==deleted==/foo/file"));
398         EXPECT_FALSE(exists(prefix + "/==deleted==/bar"));
399         EXPECT_FALSE(exists(prefix + "/==deleted==/bar/file"));
400 
401         EXPECT_FALSE(exists_renamed_deleted_dir(prefix));
402     }
403 }
404 
TEST_F(ServiceTest,HashSecondaryDex)405 TEST_F(ServiceTest, HashSecondaryDex) {
406     LOG(INFO) << "HashSecondaryDex";
407 
408     mkdir("user/0/com.example", 10000, 10000, 0700);
409     mkdir("user/0/com.example/foo", 10000, 10000, 0700);
410     touch("user/0/com.example/foo/file", 10000, 20000, 0700);
411 
412     std::vector<uint8_t> result;
413     std::string dexPath = get_full_path("user/0/com.example/foo/file");
414     EXPECT_BINDER_SUCCESS(service->hashSecondaryDexFile(
415         dexPath, "com.example", 10000, testUuid, FLAG_STORAGE_CE, &result));
416 
417     EXPECT_EQ(result.size(), 32U);
418 
419     std::ostringstream output;
420     output << std::hex << std::setfill('0');
421     for (auto b : result) {
422         output << std::setw(2) << +b;
423     }
424 
425     // This is the SHA256 of an empty string (sha256sum /dev/null)
426     EXPECT_EQ(output.str(), "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
427 }
428 
TEST_F(ServiceTest,HashSecondaryDex_NoSuch)429 TEST_F(ServiceTest, HashSecondaryDex_NoSuch) {
430     LOG(INFO) << "HashSecondaryDex_NoSuch";
431 
432     std::vector<uint8_t> result;
433     std::string dexPath = get_full_path("user/0/com.example/foo/file");
434     EXPECT_BINDER_SUCCESS(service->hashSecondaryDexFile(
435         dexPath, "com.example", 10000, testUuid, FLAG_STORAGE_CE, &result));
436 
437     EXPECT_EQ(result.size(), 0U);
438 }
439 
TEST_F(ServiceTest,HashSecondaryDex_Unreadable)440 TEST_F(ServiceTest, HashSecondaryDex_Unreadable) {
441     LOG(INFO) << "HashSecondaryDex_Unreadable";
442 
443     mkdir("user/0/com.example", 10000, 10000, 0700);
444     mkdir("user/0/com.example/foo", 10000, 10000, 0700);
445     touch("user/0/com.example/foo/file", 10000, 20000, 0300);
446 
447     std::vector<uint8_t> result;
448     std::string dexPath = get_full_path("user/0/com.example/foo/file");
449     EXPECT_BINDER_SUCCESS(service->hashSecondaryDexFile(
450         dexPath, "com.example", 10000, testUuid, FLAG_STORAGE_CE, &result));
451 
452     EXPECT_EQ(result.size(), 0U);
453 }
454 
TEST_F(ServiceTest,HashSecondaryDex_WrongApp)455 TEST_F(ServiceTest, HashSecondaryDex_WrongApp) {
456     LOG(INFO) << "HashSecondaryDex_WrongApp";
457 
458     mkdir("user/0/com.example", 10000, 10000, 0700);
459     mkdir("user/0/com.example/foo", 10000, 10000, 0700);
460     touch("user/0/com.example/foo/file", 10000, 20000, 0700);
461 
462     std::vector<uint8_t> result;
463     std::string dexPath = get_full_path("user/0/com.example/foo/file");
464     EXPECT_BINDER_FAIL(service->hashSecondaryDexFile(
465         dexPath, "com.wrong", 10000, testUuid, FLAG_STORAGE_CE, &result));
466 }
467 
TEST_F(ServiceTest,CalculateOat)468 TEST_F(ServiceTest, CalculateOat) {
469     char buf[PKG_PATH_MAX];
470 
471     EXPECT_TRUE(calculate_oat_file_path(buf, "/path/to/oat", "/path/to/file.apk", "isa"));
472     EXPECT_EQ("/path/to/oat/isa/file.odex", std::string(buf));
473 
474     EXPECT_FALSE(calculate_oat_file_path(buf, "/path/to/oat", "/path/to/file", "isa"));
475     EXPECT_FALSE(calculate_oat_file_path(buf, "/path/to/oat", "file", "isa"));
476 }
477 
TEST_F(ServiceTest,CalculateOdex)478 TEST_F(ServiceTest, CalculateOdex) {
479     char buf[PKG_PATH_MAX];
480 
481     EXPECT_TRUE(calculate_odex_file_path(buf, "/path/to/file.apk", "isa"));
482     EXPECT_EQ("/path/to/oat/isa/file.odex", std::string(buf));
483 }
484 
TEST_F(ServiceTest,CalculateCache)485 TEST_F(ServiceTest, CalculateCache) {
486     char buf[PKG_PATH_MAX];
487 
488     EXPECT_TRUE(create_cache_path(buf, "/path/to/file.apk", "isa"));
489     EXPECT_EQ("/data/dalvik-cache/isa/path@[email protected]@classes.dex", std::string(buf));
490 }
TEST_F(ServiceTest,GetAppSizeManualForMedia)491 TEST_F(ServiceTest, GetAppSizeManualForMedia) {
492     struct stat s;
493 
494     std::string externalPicDir =
495             StringPrintf("%s/Pictures", create_data_media_path(nullptr, 0).c_str());
496     if (stat(externalPicDir.c_str(), &s) == 0) {
497         // fetch the appId from the uid of the external storage owning app
498         int32_t externalStorageAppId = multiuser_get_app_id(s.st_uid);
499         // Fetch Package Name for the external storage owning app uid
500         std::string pkg = get_package_name(s.st_uid);
501 
502         std::vector<int64_t> externalStorageSize, externalStorageSizeAfterAddingExternalFile;
503         std::vector<int64_t> ceDataInodes;
504 
505         std::vector<std::string> codePaths;
506         std::vector<std::string> packageNames;
507         // set up parameters
508         packageNames.push_back(pkg);
509         ceDataInodes.push_back(0);
510         // initialise the mounts
511         service->invalidateMounts();
512         // call the getAppSize to get the current size of the external storage owning app
513         service->getAppSize(std::nullopt, packageNames, 0, InstalldNativeService::FLAG_USE_QUOTA,
514                             externalStorageAppId, ceDataInodes, codePaths, &externalStorageSize);
515         // add a file with 20MB size to the external storage
516         std::string externalFileLocation =
517                 StringPrintf("%s/Pictures/%s", getenv("EXTERNAL_STORAGE"), "External.jpg");
518         std::string externalFileContentCommand =
519                 StringPrintf("dd if=/dev/zero of=%s bs=1M count=20", externalFileLocation.c_str());
520         system(externalFileContentCommand.c_str());
521         // call the getAppSize again to get the new size of the external storage owning app
522         service->getAppSize(std::nullopt, packageNames, 0, InstalldNativeService::FLAG_USE_QUOTA,
523                             externalStorageAppId, ceDataInodes, codePaths,
524                             &externalStorageSizeAfterAddingExternalFile);
525         // check that the size before adding the file and after should be the same, as the app size
526         // is not changed.
527         for (size_t i = 0; i < externalStorageSize.size(); i++) {
528             ASSERT_TRUE(externalStorageSize[i] == externalStorageSizeAfterAddingExternalFile[i]);
529         }
530         // remove the external file
531         std::string removeCommand = StringPrintf("rm -f %s", externalFileLocation.c_str());
532         system(removeCommand.c_str());
533     }
534 }
535 
TEST_F(ServiceTest,GetAppSizeWrongSizes)536 TEST_F(ServiceTest, GetAppSizeWrongSizes) {
537     int32_t externalStorageAppId = -1;
538     std::vector<int64_t> externalStorageSize;
539 
540     std::vector<std::string> codePaths;
541     std::vector<std::string> packageNames = {"package1", "package2"};
542     std::vector<int64_t> ceDataInodes = {0};
543 
544     EXPECT_BINDER_FAIL(service->getAppSize(std::nullopt, packageNames, 0,
545                                            InstalldNativeService::FLAG_USE_QUOTA,
546                                            externalStorageAppId, ceDataInodes, codePaths,
547                                            &externalStorageSize));
548 }
549 
550 class FsverityTest : public ServiceTest {
551 protected:
createFsveritySetupAuthToken(const std::string & path,int open_mode,sp<IFsveritySetupAuthToken> * _aidl_return)552     binder::Status createFsveritySetupAuthToken(const std::string& path, int open_mode,
553                                                 sp<IFsveritySetupAuthToken>* _aidl_return) {
554         unique_fd ufd(open(path.c_str(), open_mode));
555         EXPECT_GE(ufd.get(), 0) << "open failed: " << strerror(errno);
556         ParcelFileDescriptor rfd(std::move(ufd));
557         return service->createFsveritySetupAuthToken(std::move(rfd), kTestAppId, _aidl_return);
558     }
559 };
560 
TEST_F(FsverityTest,enableFsverity)561 TEST_F(FsverityTest, enableFsverity) {
562     const std::string path = kTestPath + "/foo";
563     create_with_content(path, kTestAppUid, kTestAppUid, 0600, "content");
564     UniqueFile raii(/*fd=*/-1, path, &unlink_path);
565 
566     // Expect to fs-verity setup to succeed
567     sp<IFsveritySetupAuthToken> authToken;
568     binder::Status status = createFsveritySetupAuthToken(path, O_RDWR, &authToken);
569     EXPECT_TRUE(status.isOk());
570     EXPECT_TRUE(authToken != nullptr);
571 
572     // Verity auth token works to enable fs-verity
573     int32_t errno_local;
574     status = service->enableFsverity(authToken, path, "fake.package.name", &errno_local);
575     EXPECT_TRUE(status.isOk());
576     EXPECT_EQ(errno_local, 0);
577 }
578 
TEST_F(FsverityTest,enableFsverity_nullAuthToken)579 TEST_F(FsverityTest, enableFsverity_nullAuthToken) {
580     const std::string path = kTestPath + "/foo";
581     create_with_content(path, kTestAppUid, kTestAppUid, 0600, "content");
582     UniqueFile raii(/*fd=*/-1, path, &unlink_path);
583 
584     // Verity null auth token fails
585     sp<IFsveritySetupAuthToken> authToken;
586     int32_t errno_local;
587     binder::Status status =
588             service->enableFsverity(authToken, path, "fake.package.name", &errno_local);
589     EXPECT_FALSE(status.isOk());
590 }
591 
TEST_F(FsverityTest,enableFsverity_differentFile)592 TEST_F(FsverityTest, enableFsverity_differentFile) {
593     const std::string path = kTestPath + "/foo";
594     create_with_content(path, kTestAppUid, kTestAppUid, 0600, "content");
595     UniqueFile raii(/*fd=*/-1, path, &unlink_path);
596 
597     // Expect to fs-verity setup to succeed
598     sp<IFsveritySetupAuthToken> authToken;
599     binder::Status status = createFsveritySetupAuthToken(path, O_RDWR, &authToken);
600     EXPECT_TRUE(status.isOk());
601     EXPECT_TRUE(authToken != nullptr);
602 
603     // Verity auth token does not work for a different file
604     const std::string anotherPath = kTestPath + "/bar";
605     ASSERT_TRUE(android::base::WriteStringToFile("content", anotherPath));
606     UniqueFile raii2(/*fd=*/-1, anotherPath, &unlink_path);
607     int32_t errno_local;
608     status = service->enableFsverity(authToken, anotherPath, "fake.package.name", &errno_local);
609     EXPECT_TRUE(status.isOk());
610     EXPECT_NE(errno_local, 0);
611 }
612 
TEST_F(FsverityTest,enableFsverity_errnoBeforeAuthenticated)613 TEST_F(FsverityTest, enableFsverity_errnoBeforeAuthenticated) {
614     const std::string path = kTestPath + "/foo";
615     create_with_content(path, kTestAppUid, kTestAppUid, 0600, "content");
616     UniqueFile raii(/*fd=*/-1, path, &unlink_path);
617 
618     // Expect to fs-verity setup to succeed
619     sp<IFsveritySetupAuthToken> authToken;
620     binder::Status status = createFsveritySetupAuthToken(path, O_RDWR, &authToken);
621     EXPECT_TRUE(status.isOk());
622     EXPECT_TRUE(authToken != nullptr);
623 
624     // Verity errno before the fd authentication is constant (EPERM)
625     int32_t errno_local;
626     status = service->enableFsverity(authToken, path + "-non-exist", "fake.package.name",
627                                      &errno_local);
628     EXPECT_TRUE(status.isOk());
629     EXPECT_EQ(errno_local, EPERM);
630 }
631 
TEST_F(FsverityTest,createFsveritySetupAuthToken_ReadonlyFdDoesNotAuthenticate)632 TEST_F(FsverityTest, createFsveritySetupAuthToken_ReadonlyFdDoesNotAuthenticate) {
633     const std::string path = kTestPath + "/foo";
634     create_with_content(path, kTestAppUid, kTestAppUid, 0600, "content");
635     UniqueFile raii(/*fd=*/-1, path, &unlink_path);
636 
637     // Expect the fs-verity setup to fail
638     sp<IFsveritySetupAuthToken> authToken;
639     binder::Status status = createFsveritySetupAuthToken(path, O_RDONLY, &authToken);
640     EXPECT_FALSE(status.isOk());
641 }
642 
TEST_F(FsverityTest,createFsveritySetupAuthToken_UnownedFile)643 TEST_F(FsverityTest, createFsveritySetupAuthToken_UnownedFile) {
644     const std::string path = kTestPath + "/foo";
645     // Simulate world-writable file owned by another app
646     create_with_content(path, kTestAppUid + 1, kTestAppUid + 1, 0666, "content");
647     UniqueFile raii(/*fd=*/-1, path, &unlink_path);
648 
649     // Expect the fs-verity setup to fail
650     sp<IFsveritySetupAuthToken> authToken;
651     binder::Status status = createFsveritySetupAuthToken(path, O_RDWR, &authToken);
652     EXPECT_FALSE(status.isOk());
653 }
654 
mkdirs(const std::string & path,mode_t mode)655 static bool mkdirs(const std::string& path, mode_t mode) {
656     struct stat sb;
657     if (stat(path.c_str(), &sb) != -1 && S_ISDIR(sb.st_mode)) {
658         return true;
659     }
660 
661     if (!mkdirs(android::base::Dirname(path), mode)) {
662         return false;
663     }
664 
665     if (::mkdir(path.c_str(), mode) != 0) {
666         PLOG(DEBUG) << "Failed to create folder " << path;
667         return false;
668     }
669     return true;
670 }
671 
672 class AppDataSnapshotTest : public testing::Test {
673 private:
674     std::string rollback_ce_base_dir;
675     std::string rollback_de_base_dir;
676 
677 protected:
678     InstalldNativeService* service;
679 
680     std::string fake_package_ce_path;
681     std::string fake_package_de_path;
682 
SetUp()683     virtual void SetUp() {
684         setenv("ANDROID_LOG_TAGS", "*:v", 1);
685         android::base::InitLogging(nullptr);
686 
687         service = new InstalldNativeService();
688         ASSERT_TRUE(mkdirs("/data/local/tmp/user/0", 0700));
689 
690         init_globals_from_data_and_root();
691 
692         rollback_ce_base_dir = create_data_misc_ce_rollback_base_path("TEST", 0);
693         rollback_de_base_dir = create_data_misc_de_rollback_base_path("TEST", 0);
694 
695         fake_package_ce_path = create_data_user_ce_package_path("TEST", 0, "com.foo");
696         fake_package_de_path = create_data_user_de_package_path("TEST", 0, "com.foo");
697 
698         ASSERT_TRUE(mkdirs(rollback_ce_base_dir, 0700));
699         ASSERT_TRUE(mkdirs(rollback_de_base_dir, 0700));
700         ASSERT_TRUE(mkdirs(fake_package_ce_path, 0700));
701         ASSERT_TRUE(mkdirs(fake_package_de_path, 0700));
702     }
703 
TearDown()704     virtual void TearDown() {
705         ASSERT_EQ(0, delete_dir_contents_and_dir(rollback_ce_base_dir, true));
706         ASSERT_EQ(0, delete_dir_contents_and_dir(rollback_de_base_dir, true));
707         ASSERT_EQ(0, delete_dir_contents(fake_package_ce_path, true));
708         ASSERT_EQ(0, delete_dir_contents(fake_package_de_path, true));
709 
710         delete service;
711         ASSERT_EQ(0, delete_dir_contents_and_dir("/data/local/tmp/user/0", true));
712     }
713 };
714 
TEST_F(AppDataSnapshotTest,CreateAppDataSnapshot)715 TEST_F(AppDataSnapshotTest, CreateAppDataSnapshot) {
716   auto rollback_ce_dir = create_data_misc_ce_rollback_path("TEST", 0, 37);
717   auto rollback_de_dir = create_data_misc_de_rollback_path("TEST", 0, 37);
718 
719   ASSERT_TRUE(android::base::WriteStringToFile(
720           "TEST_CONTENT_CE", fake_package_ce_path + "/file1",
721           0700, 10000, 20000, false /* follow_symlinks */));
722   ASSERT_TRUE(android::base::WriteStringToFile(
723           "TEST_CONTENT_DE", fake_package_de_path + "/file1",
724           0700, 10000, 20000, false /* follow_symlinks */));
725 
726   // Request a snapshot of the CE content but not the DE content.
727   int64_t ce_snapshot_inode;
728   ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_optional<std::string>("TEST"),
729           "com.foo", 0, 37, FLAG_STORAGE_CE, &ce_snapshot_inode));
730   struct stat buf;
731   memset(&buf, 0, sizeof(buf));
732   ASSERT_EQ(0, stat((rollback_ce_dir + "/com.foo").c_str(), &buf));
733   ASSERT_EQ(ce_snapshot_inode, (int64_t) buf.st_ino);
734 
735   std::string ce_content, de_content;
736   // At this point, we should have the CE content but not the DE content.
737   ASSERT_TRUE(android::base::ReadFileToString(
738       rollback_ce_dir + "/com.foo/file1", &ce_content, false /* follow_symlinks */));
739   ASSERT_FALSE(android::base::ReadFileToString(
740       rollback_de_dir + "/com.foo/file1", &de_content, false /* follow_symlinks */));
741   ASSERT_EQ("TEST_CONTENT_CE", ce_content);
742 
743   // Modify the CE content, so we can assert later that it's reflected
744   // in the snapshot.
745   ASSERT_TRUE(android::base::WriteStringToFile(
746           "TEST_CONTENT_CE_MODIFIED", fake_package_ce_path + "/file1",
747           0700, 10000, 20000, false /* follow_symlinks */));
748 
749   // Request a snapshot of the DE content but not the CE content.
750   ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_optional<std::string>("TEST"),
751           "com.foo", 0, 37, FLAG_STORAGE_DE, &ce_snapshot_inode));
752   // Only DE content snapshot was requested.
753   ASSERT_EQ(ce_snapshot_inode, 0);
754 
755   // At this point, both the CE as well as the DE content should be fully
756   // populated.
757   ASSERT_TRUE(android::base::ReadFileToString(
758       rollback_ce_dir + "/com.foo/file1", &ce_content, false /* follow_symlinks */));
759   ASSERT_TRUE(android::base::ReadFileToString(
760       rollback_de_dir + "/com.foo/file1", &de_content, false /* follow_symlinks */));
761   ASSERT_EQ("TEST_CONTENT_CE", ce_content);
762   ASSERT_EQ("TEST_CONTENT_DE", de_content);
763 
764   // Modify the DE content, so we can assert later that it's reflected
765   // in our final snapshot.
766   ASSERT_TRUE(android::base::WriteStringToFile(
767           "TEST_CONTENT_DE_MODIFIED", fake_package_de_path + "/file1",
768           0700, 10000, 20000, false /* follow_symlinks */));
769 
770   // Request a snapshot of both the CE as well as the DE content.
771   ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_optional<std::string>("TEST"),
772           "com.foo", 0, 37, FLAG_STORAGE_DE | FLAG_STORAGE_CE, nullptr));
773 
774   ASSERT_TRUE(android::base::ReadFileToString(
775       rollback_ce_dir + "/com.foo/file1", &ce_content, false /* follow_symlinks */));
776   ASSERT_TRUE(android::base::ReadFileToString(
777       rollback_de_dir + "/com.foo/file1", &de_content, false /* follow_symlinks */));
778   ASSERT_EQ("TEST_CONTENT_CE_MODIFIED", ce_content);
779   ASSERT_EQ("TEST_CONTENT_DE_MODIFIED", de_content);
780 }
781 
TEST_F(AppDataSnapshotTest,CreateAppDataSnapshot_TwoSnapshotsWithTheSameId)782 TEST_F(AppDataSnapshotTest, CreateAppDataSnapshot_TwoSnapshotsWithTheSameId) {
783   auto rollback_ce_dir = create_data_misc_ce_rollback_path("TEST", 0, 67);
784   auto rollback_de_dir = create_data_misc_de_rollback_path("TEST", 0, 67);
785 
786   auto another_fake_package_ce_path = create_data_user_ce_package_path("TEST", 0, "com.bar");
787   auto another_fake_package_de_path = create_data_user_de_package_path("TEST", 0, "com.bar");
788 
789   // Since this test sets up data for another package, some bookkeeping is required.
790   auto deleter = [&]() {
791       ASSERT_EQ(0, delete_dir_contents_and_dir(another_fake_package_ce_path, true));
792       ASSERT_EQ(0, delete_dir_contents_and_dir(another_fake_package_de_path, true));
793   };
794   auto scope_guard = android::base::make_scope_guard(deleter);
795 
796   ASSERT_TRUE(mkdirs(another_fake_package_ce_path, 0700));
797   ASSERT_TRUE(mkdirs(another_fake_package_de_path, 0700));
798 
799   ASSERT_TRUE(android::base::WriteStringToFile(
800           "TEST_CONTENT_CE", fake_package_ce_path + "/file1",
801           0700, 10000, 20000, false /* follow_symlinks */));
802   ASSERT_TRUE(android::base::WriteStringToFile(
803           "TEST_CONTENT_DE", fake_package_de_path + "/file1",
804           0700, 10000, 20000, false /* follow_symlinks */));
805   ASSERT_TRUE(android::base::WriteStringToFile(
806           "ANOTHER_TEST_CONTENT_CE", another_fake_package_ce_path + "/file1",
807           0700, 10000, 20000, false /* follow_symlinks */));
808   ASSERT_TRUE(android::base::WriteStringToFile(
809           "ANOTHER_TEST_CONTENT_DE", another_fake_package_de_path + "/file1",
810           0700, 10000, 20000, false /* follow_symlinks */));
811 
812   // Request snapshot for the package com.foo.
813   ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_optional<std::string>("TEST"),
814           "com.foo", 0, 67, FLAG_STORAGE_DE | FLAG_STORAGE_CE, nullptr));
815   // Now request snapshot with the same id for the package com.bar
816   ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_optional<std::string>("TEST"),
817           "com.bar", 0, 67, FLAG_STORAGE_DE | FLAG_STORAGE_CE, nullptr));
818 
819   // Check that both snapshots have correct data in them.
820   std::string com_foo_ce_content, com_foo_de_content;
821   std::string com_bar_ce_content, com_bar_de_content;
822   ASSERT_TRUE(android::base::ReadFileToString(
823       rollback_ce_dir + "/com.foo/file1", &com_foo_ce_content, false /* follow_symlinks */));
824   ASSERT_TRUE(android::base::ReadFileToString(
825       rollback_de_dir + "/com.foo/file1", &com_foo_de_content, false /* follow_symlinks */));
826   ASSERT_TRUE(android::base::ReadFileToString(
827       rollback_ce_dir + "/com.bar/file1", &com_bar_ce_content, false /* follow_symlinks */));
828   ASSERT_TRUE(android::base::ReadFileToString(
829       rollback_de_dir + "/com.bar/file1", &com_bar_de_content, false /* follow_symlinks */));
830   ASSERT_EQ("TEST_CONTENT_CE", com_foo_ce_content);
831   ASSERT_EQ("TEST_CONTENT_DE", com_foo_de_content);
832   ASSERT_EQ("ANOTHER_TEST_CONTENT_CE", com_bar_ce_content);
833   ASSERT_EQ("ANOTHER_TEST_CONTENT_DE", com_bar_de_content);
834 }
835 
TEST_F(AppDataSnapshotTest,CreateAppDataSnapshot_AppDataAbsent)836 TEST_F(AppDataSnapshotTest, CreateAppDataSnapshot_AppDataAbsent) {
837   auto rollback_ce_dir = create_data_misc_ce_rollback_path("TEST", 0, 73);
838   auto rollback_de_dir = create_data_misc_de_rollback_path("TEST", 0, 73);
839 
840   // Similuating app data absence.
841   ASSERT_EQ(0, delete_dir_contents_and_dir(fake_package_ce_path, true));
842   ASSERT_EQ(0, delete_dir_contents_and_dir(fake_package_de_path, true));
843 
844   int64_t ce_snapshot_inode;
845   ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_optional<std::string>("TEST"),
846           "com.foo", 0, 73, FLAG_STORAGE_CE, &ce_snapshot_inode));
847   ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_optional<std::string>("TEST"),
848           "com.foo", 0, 73, FLAG_STORAGE_DE, nullptr));
849   // No CE content snapshot was performed.
850   ASSERT_EQ(ce_snapshot_inode, 0);
851 
852   // The snapshot calls must succeed but there should be no snapshot
853   // created.
854   struct stat sb;
855   ASSERT_EQ(-1, stat((rollback_ce_dir + "/com.foo").c_str(), &sb));
856   ASSERT_EQ(-1, stat((rollback_de_dir + "/com.foo").c_str(), &sb));
857 }
858 
TEST_F(AppDataSnapshotTest,CreateAppDataSnapshot_ClearsExistingSnapshot)859 TEST_F(AppDataSnapshotTest, CreateAppDataSnapshot_ClearsExistingSnapshot) {
860   auto rollback_ce_dir = create_data_misc_ce_rollback_package_path("TEST", 0, 13, "com.foo");
861   auto rollback_de_dir = create_data_misc_de_rollback_package_path("TEST", 0, 13, "com.foo");
862 
863   ASSERT_TRUE(mkdirs(rollback_ce_dir, 0700));
864   ASSERT_TRUE(mkdirs(rollback_de_dir, 0700));
865 
866   // Simulate presence of an existing snapshot
867   ASSERT_TRUE(android::base::WriteStringToFile(
868           "TEST_CONTENT_CE", rollback_ce_dir + "/file1",
869           0700, 10000, 20000, false /* follow_symlinks */));
870   ASSERT_TRUE(android::base::WriteStringToFile(
871           "TEST_CONTENT_DE", rollback_de_dir + "/file1",
872           0700, 10000, 20000, false /* follow_symlinks */));
873 
874   // Create app data.
875   ASSERT_TRUE(android::base::WriteStringToFile(
876           "TEST_CONTENT_2_CE", fake_package_ce_path + "/file2",
877           0700, 10000, 20000, false /* follow_symlinks */));
878   ASSERT_TRUE(android::base::WriteStringToFile(
879           "TEST_CONTENT_2_DE", fake_package_de_path + "/file2",
880           0700, 10000, 20000, false /* follow_symlinks */));
881 
882   ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_optional<std::string>("TEST"),
883           "com.foo", 0, 13, FLAG_STORAGE_DE | FLAG_STORAGE_CE, nullptr));
884 
885   // Previous snapshot (with data for file1) must be cleared.
886   struct stat sb;
887   ASSERT_EQ(-1, stat((rollback_ce_dir + "/file1").c_str(), &sb));
888   ASSERT_EQ(-1, stat((rollback_de_dir + "/file1").c_str(), &sb));
889   // New snapshot (with data for file2) must be present.
890   ASSERT_NE(-1, stat((rollback_ce_dir + "/file2").c_str(), &sb));
891   ASSERT_NE(-1, stat((rollback_de_dir + "/file2").c_str(), &sb));
892 }
893 
TEST_F(AppDataSnapshotTest,SnapshotAppData_WrongVolumeUuid)894 TEST_F(AppDataSnapshotTest, SnapshotAppData_WrongVolumeUuid) {
895   // Setup rollback folders to make sure that fails due to wrong volumeUuid being
896   // passed, not because of some other reason.
897   auto rollback_ce_dir = create_data_misc_ce_rollback_path("TEST", 0, 17);
898   auto rollback_de_dir = create_data_misc_de_rollback_path("TEST", 0, 17);
899 
900   ASSERT_TRUE(mkdirs(rollback_ce_dir, 0700));
901   ASSERT_TRUE(mkdirs(rollback_de_dir, 0700));
902 
903   EXPECT_BINDER_FAIL(service->snapshotAppData(std::make_optional<std::string>("FOO"),
904           "com.foo", 0, 17, FLAG_STORAGE_DE, nullptr));
905 }
906 
TEST_F(AppDataSnapshotTest,CreateAppDataSnapshot_ClearsCache)907 TEST_F(AppDataSnapshotTest, CreateAppDataSnapshot_ClearsCache) {
908   auto fake_package_ce_cache_path = fake_package_ce_path + "/cache";
909   auto fake_package_ce_code_cache_path = fake_package_ce_path + "/code_cache";
910   auto fake_package_de_cache_path = fake_package_de_path + "/cache";
911   auto fake_package_de_code_cache_path = fake_package_de_path + "/code_cache";
912 
913   ASSERT_TRUE(mkdirs(fake_package_ce_cache_path, 0700));
914   ASSERT_TRUE(mkdirs(fake_package_ce_code_cache_path, 0700));
915   ASSERT_TRUE(mkdirs(fake_package_de_cache_path, 0700));
916   ASSERT_TRUE(mkdirs(fake_package_de_code_cache_path, 0700));
917 
918   ASSERT_TRUE(android::base::WriteStringToFile(
919           "TEST_CONTENT_CE", fake_package_ce_cache_path + "/file1",
920           0700, 10000, 20000, false /* follow_symlinks */));
921   ASSERT_TRUE(android::base::WriteStringToFile(
922           "TEST_CONTENT_CE", fake_package_ce_code_cache_path + "/file1",
923           0700, 10000, 20000, false /* follow_symlinks */));
924   ASSERT_TRUE(android::base::WriteStringToFile(
925           "TEST_CONTENT_DE", fake_package_de_cache_path + "/file1",
926           0700, 10000, 20000, false /* follow_symlinks */));
927   ASSERT_TRUE(android::base::WriteStringToFile(
928           "TEST_CONTENT_DE", fake_package_de_code_cache_path + "/file1",
929           0700, 10000, 20000, false /* follow_symlinks */));
930   ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_optional<std::string>("TEST"),
931           "com.foo", 0, 23, FLAG_STORAGE_CE | FLAG_STORAGE_DE, nullptr));
932   // The snapshot call must clear cache.
933   struct stat sb;
934   ASSERT_EQ(-1, stat((fake_package_ce_cache_path + "/file1").c_str(), &sb));
935   ASSERT_EQ(-1, stat((fake_package_ce_code_cache_path + "/file1").c_str(), &sb));
936   ASSERT_EQ(-1, stat((fake_package_de_cache_path + "/file1").c_str(), &sb));
937   ASSERT_EQ(-1, stat((fake_package_de_code_cache_path + "/file1").c_str(), &sb));
938 }
939 
TEST_F(AppDataSnapshotTest,RestoreAppDataSnapshot)940 TEST_F(AppDataSnapshotTest, RestoreAppDataSnapshot) {
941   auto rollback_ce_dir = create_data_misc_ce_rollback_path("TEST", 0, 239);
942   auto rollback_de_dir = create_data_misc_de_rollback_path("TEST", 0, 239);
943 
944   ASSERT_TRUE(mkdirs(rollback_ce_dir, 0700));
945   ASSERT_TRUE(mkdirs(rollback_de_dir, 0700));
946 
947   // Write contents to the rollback location. We'll write the same files to the
948   // app data location and make sure the restore has overwritten them.
949   ASSERT_TRUE(mkdirs(rollback_ce_dir + "/com.foo/", 0700));
950   ASSERT_TRUE(mkdirs(rollback_de_dir + "/com.foo/", 0700));
951   ASSERT_TRUE(android::base::WriteStringToFile(
952           "CE_RESTORE_CONTENT", rollback_ce_dir + "/com.foo/file1",
953           0700, 10000, 20000, false /* follow_symlinks */));
954   ASSERT_TRUE(android::base::WriteStringToFile(
955           "DE_RESTORE_CONTENT", rollback_de_dir + "/com.foo/file1",
956           0700, 10000, 20000, false /* follow_symlinks */));
957   ASSERT_TRUE(android::base::WriteStringToFile(
958           "TEST_CONTENT_CE", fake_package_ce_path + "/file1",
959           0700, 10000, 20000, false /* follow_symlinks */));
960   ASSERT_TRUE(android::base::WriteStringToFile(
961           "TEST_CONTENT_DE", fake_package_de_path + "/file1",
962           0700, 10000, 20000, false /* follow_symlinks */));
963 
964   ASSERT_BINDER_SUCCESS(service->restoreAppDataSnapshot(std::make_optional<std::string>("TEST"),
965           "com.foo", 10000, "", 0, 239, FLAG_STORAGE_DE | FLAG_STORAGE_CE));
966 
967   std::string ce_content, de_content;
968   ASSERT_TRUE(android::base::ReadFileToString(
969       fake_package_ce_path + "/file1", &ce_content, false /* follow_symlinks */));
970   ASSERT_TRUE(android::base::ReadFileToString(
971       fake_package_de_path + "/file1", &de_content, false /* follow_symlinks */));
972   ASSERT_EQ("CE_RESTORE_CONTENT", ce_content);
973   ASSERT_EQ("DE_RESTORE_CONTENT", de_content);
974 }
975 
TEST_F(AppDataSnapshotTest,CreateSnapshotThenDestroyIt)976 TEST_F(AppDataSnapshotTest, CreateSnapshotThenDestroyIt) {
977   auto rollback_ce_dir = create_data_misc_ce_rollback_path("TEST", 0, 57);
978   auto rollback_de_dir = create_data_misc_de_rollback_path("TEST", 0, 57);
979 
980   // Prepare data for snapshot.
981   ASSERT_TRUE(android::base::WriteStringToFile(
982           "TEST_CONTENT_CE", fake_package_ce_path + "/file1",
983           0700, 10000, 20000, false /* follow_symlinks */));
984   ASSERT_TRUE(android::base::WriteStringToFile(
985           "TEST_CONTENT_DE", fake_package_de_path + "/file1",
986           0700, 10000, 20000, false /* follow_symlinks */));
987 
988   int64_t ce_snapshot_inode;
989   // Request a snapshot of both the CE as well as the DE content.
990   ASSERT_TRUE(service->snapshotAppData(std::make_optional<std::string>("TEST"),
991           "com.foo", 0, 57, FLAG_STORAGE_DE | FLAG_STORAGE_CE, &ce_snapshot_inode).isOk());
992   // Because CE data snapshot was requested, ce_snapshot_inode can't be null.
993   ASSERT_NE(0, ce_snapshot_inode);
994   // Check snapshot is there.
995   struct stat sb;
996   ASSERT_EQ(0, stat((rollback_ce_dir + "/com.foo").c_str(), &sb));
997   ASSERT_EQ(0, stat((rollback_de_dir + "/com.foo").c_str(), &sb));
998 
999 
1000   ASSERT_TRUE(service->destroyAppDataSnapshot(std::make_optional<std::string>("TEST"),
1001           "com.foo", 0, ce_snapshot_inode, 57, FLAG_STORAGE_DE | FLAG_STORAGE_CE).isOk());
1002   // Check snapshot is deleted.
1003   ASSERT_EQ(-1, stat((rollback_ce_dir + "/com.foo").c_str(), &sb));
1004   ASSERT_EQ(-1, stat((rollback_de_dir + "/com.foo").c_str(), &sb));
1005 }
1006 
TEST_F(AppDataSnapshotTest,DestroyAppDataSnapshot_CeSnapshotInodeIsZero)1007 TEST_F(AppDataSnapshotTest, DestroyAppDataSnapshot_CeSnapshotInodeIsZero) {
1008   auto rollback_ce_dir = create_data_misc_ce_rollback_path("TEST", 0, 1543);
1009   auto rollback_de_dir = create_data_misc_de_rollback_path("TEST", 0, 1543);
1010 
1011   // Create a snapshot
1012   ASSERT_TRUE(mkdirs(rollback_ce_dir + "/com.foo/", 0700));
1013   ASSERT_TRUE(mkdirs(rollback_de_dir + "/com.foo/", 0700));
1014   ASSERT_TRUE(android::base::WriteStringToFile(
1015           "CE_RESTORE_CONTENT", rollback_ce_dir + "/com.foo/file1",
1016           0700, 10000, 20000, false /* follow_symlinks */));
1017   ASSERT_TRUE(android::base::WriteStringToFile(
1018           "DE_RESTORE_CONTENT", rollback_de_dir + "/com.foo/file1",
1019           0700, 10000, 20000, false /* follow_symlinks */));
1020 
1021   ASSERT_TRUE(service->destroyAppDataSnapshot(std::make_optional<std::string>("TEST"),
1022           "com.foo", 0, 0, 1543, FLAG_STORAGE_DE | FLAG_STORAGE_CE).isOk());
1023 
1024   // Check snapshot is deleted.
1025   struct stat sb;
1026   ASSERT_EQ(-1, stat((rollback_ce_dir + "/com.foo").c_str(), &sb));
1027   ASSERT_EQ(-1, stat((rollback_de_dir + "/com.foo").c_str(), &sb));
1028 
1029   // Check that deleting already deleted snapshot is no-op.
1030   ASSERT_TRUE(service->destroyAppDataSnapshot(std::make_optional<std::string>("TEST"),
1031           "com.foo", 0, 0, 1543, FLAG_STORAGE_DE | FLAG_STORAGE_CE).isOk());
1032 }
1033 
TEST_F(AppDataSnapshotTest,DestroyAppDataSnapshot_WrongVolumeUuid)1034 TEST_F(AppDataSnapshotTest, DestroyAppDataSnapshot_WrongVolumeUuid) {
1035   // Setup rollback data to make sure that test fails due to wrong volumeUuid
1036   // being passed, not because of some other reason.
1037   auto rollback_ce_dir = create_data_misc_ce_rollback_path("TEST", 0, 43);
1038   auto rollback_de_dir = create_data_misc_de_rollback_path("TEST", 0, 43);
1039 
1040   ASSERT_TRUE(mkdirs(rollback_ce_dir, 0700));
1041   ASSERT_TRUE(mkdirs(rollback_de_dir, 0700));
1042 
1043   ASSERT_FALSE(service->destroyAppDataSnapshot(std::make_optional<std::string>("BAR"),
1044           "com.foo", 0, 0, 43, FLAG_STORAGE_DE).isOk());
1045 }
1046 
TEST_F(AppDataSnapshotTest,DestroyCeSnapshotsNotSpecified)1047 TEST_F(AppDataSnapshotTest, DestroyCeSnapshotsNotSpecified) {
1048   auto rollback_ce_dir_in_1 = create_data_misc_ce_rollback_path("TEST", 0, 1543);
1049   auto rollback_ce_dir_in_2 = create_data_misc_ce_rollback_path("TEST", 0, 77);
1050   auto rollback_ce_dir_out_1 = create_data_misc_ce_rollback_path("TEST", 0, 1500);
1051   auto rollback_ce_dir_out_2 = create_data_misc_ce_rollback_path("TEST", 0, 2);
1052 
1053   // Create snapshots
1054   ASSERT_TRUE(mkdirs(rollback_ce_dir_in_1 + "/com.foo/", 0700));
1055   ASSERT_TRUE(android::base::WriteStringToFile(
1056           "CE_RESTORE_CONTENT", rollback_ce_dir_in_1 + "/com.foo/file1",
1057           0700, 10000, 20000, false /* follow_symlinks */));
1058 
1059   ASSERT_TRUE(mkdirs(rollback_ce_dir_in_2 + "/com.foo/", 0700));
1060   ASSERT_TRUE(android::base::WriteStringToFile(
1061           "CE_RESTORE_CONTENT", rollback_ce_dir_in_2 + "/com.foo/file1",
1062           0700, 10000, 20000, false /* follow_symlinks */));
1063 
1064   ASSERT_TRUE(mkdirs(rollback_ce_dir_out_1 + "/com.foo/", 0700));
1065   ASSERT_TRUE(android::base::WriteStringToFile(
1066           "CE_RESTORE_CONTENT", rollback_ce_dir_out_1 + "/com.foo/file1",
1067           0700, 10000, 20000, false /* follow_symlinks */));
1068 
1069   ASSERT_TRUE(mkdirs(rollback_ce_dir_out_2 + "/com.foo/", 0700));
1070   ASSERT_TRUE(android::base::WriteStringToFile(
1071           "CE_RESTORE_CONTENT", rollback_ce_dir_out_2 + "/com.foo/file1",
1072           0700, 10000, 20000, false /* follow_symlinks */));
1073 
1074   ASSERT_TRUE(service->destroyCeSnapshotsNotSpecified(
1075           std::make_optional<std::string>("TEST"), 0, { 1543, 77 }).isOk());
1076 
1077   // Check only snapshots not specified are deleted.
1078   struct stat sb;
1079   ASSERT_EQ(0, stat((rollback_ce_dir_in_1 + "/com.foo").c_str(), &sb));
1080   ASSERT_EQ(0, stat((rollback_ce_dir_in_2 + "/com.foo").c_str(), &sb));
1081   ASSERT_EQ(-1, stat((rollback_ce_dir_out_1 + "/com.foo").c_str(), &sb));
1082   ASSERT_EQ(ENOENT, errno);
1083   ASSERT_EQ(-1, stat((rollback_ce_dir_out_2 + "/com.foo").c_str(), &sb));
1084   ASSERT_EQ(ENOENT, errno);
1085 }
1086 
TEST_F(AppDataSnapshotTest,RestoreAppDataSnapshot_WrongVolumeUuid)1087 TEST_F(AppDataSnapshotTest, RestoreAppDataSnapshot_WrongVolumeUuid) {
1088   // Setup rollback data to make sure that fails due to wrong volumeUuid being
1089   // passed, not because of some other reason.
1090   auto rollback_ce_dir = create_data_misc_ce_rollback_path("TEST", 0, 41);
1091   auto rollback_de_dir = create_data_misc_de_rollback_path("TEST", 0, 41);
1092 
1093   ASSERT_TRUE(mkdirs(rollback_ce_dir, 0700));
1094   ASSERT_TRUE(mkdirs(rollback_de_dir, 0700));
1095 
1096   EXPECT_BINDER_FAIL(service->restoreAppDataSnapshot(std::make_optional<std::string>("BAR"),
1097           "com.foo", 10000, "", 0, 41, FLAG_STORAGE_DE));
1098 }
1099 
1100 class SdkSandboxDataTest : public testing::Test {
1101 public:
CheckFileAccess(const std::string & path,uid_t uid,gid_t gid,mode_t mode)1102     void CheckFileAccess(const std::string& path, uid_t uid, gid_t gid, mode_t mode) {
1103         const auto fullPath = "/data/local/tmp/" + path;
1104         ASSERT_TRUE(exists(fullPath.c_str())) << "For path: " << fullPath;
1105         struct stat st;
1106         ASSERT_EQ(0, stat(fullPath.c_str(), &st));
1107         ASSERT_EQ(uid, st.st_uid) << "For path: " << fullPath;
1108         ASSERT_EQ(gid, st.st_gid) << "For path: " << fullPath;
1109         ASSERT_EQ(mode, st.st_mode) << "For path: " << fullPath;
1110     }
1111 
exists(const char * path)1112     bool exists(const char* path) { return ::access(path, F_OK) == 0; }
1113 
1114     // Creates a default CreateAppDataArgs object
createAppDataArgs(const std::string & packageName)1115     android::os::CreateAppDataArgs createAppDataArgs(const std::string& packageName) {
1116         android::os::CreateAppDataArgs args;
1117         args.uuid = kTestUuid;
1118         args.packageName = packageName;
1119         args.userId = kTestUserId;
1120         args.appId = kTestAppId;
1121         args.seInfo = "default";
1122         args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE | FLAG_STORAGE_SDK;
1123         return args;
1124     }
1125 
reconcileSdkDataArgs(const std::string & packageName,const std::vector<std::string> & subDirNames)1126     android::os::ReconcileSdkDataArgs reconcileSdkDataArgs(
1127             const std::string& packageName, const std::vector<std::string>& subDirNames) {
1128         android::os::ReconcileSdkDataArgs args;
1129         args.uuid = kTestUuid;
1130         args.packageName = packageName;
1131         for (const auto& subDirName : subDirNames) {
1132             args.subDirNames.push_back(subDirName);
1133         }
1134         args.userId = kTestUserId;
1135         args.appId = kTestAppId;
1136         args.previousAppId = -1;
1137         args.seInfo = "default";
1138         args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE;
1139         return args;
1140     }
1141 
1142 protected:
1143     InstalldNativeService* service;
1144 
SetUp()1145     virtual void SetUp() {
1146         setenv("ANDROID_LOG_TAGS", "*:v", 1);
1147         android::base::InitLogging(nullptr);
1148 
1149         service = new InstalldNativeService();
1150         clearAppData();
1151         ASSERT_TRUE(mkdirs("/data/local/tmp/user/0", 0700));
1152         ASSERT_TRUE(mkdirs("/data/local/tmp/user_de/0", 0700));
1153         ASSERT_TRUE(mkdirs("/data/local/tmp/misc_ce/0/sdksandbox", 0700));
1154         ASSERT_TRUE(mkdirs("/data/local/tmp/misc_de/0/sdksandbox", 0700));
1155 
1156         init_globals_from_data_and_root();
1157     }
1158 
TearDown()1159     virtual void TearDown() {
1160         delete service;
1161         clearAppData();
1162     }
1163 
1164 private:
clearAppData()1165     void clearAppData() {
1166         ASSERT_EQ(0, delete_dir_contents_and_dir("/data/local/tmp/user", true));
1167         ASSERT_EQ(0, delete_dir_contents_and_dir("/data/local/tmp/user_de", true));
1168         ASSERT_EQ(0, delete_dir_contents_and_dir("/data/local/tmp/misc_ce", true));
1169         ASSERT_EQ(0, delete_dir_contents_and_dir("/data/local/tmp/misc_de", true));
1170     }
1171 };
1172 
TEST_F(SdkSandboxDataTest,CreateAppData_CreatesSdkPackageData)1173 TEST_F(SdkSandboxDataTest, CreateAppData_CreatesSdkPackageData) {
1174     android::os::CreateAppDataResult result;
1175     android::os::CreateAppDataArgs args = createAppDataArgs("com.foo");
1176 
1177     // Create the app user data.
1178     ASSERT_BINDER_SUCCESS(service->createAppData(args, &result));
1179 
1180     const std::string fooCePath = "misc_ce/0/sdksandbox/com.foo";
1181     CheckFileAccess(fooCePath, kSystemUid, kSystemUid, S_IFDIR | 0751);
1182 
1183     const std::string fooDePath = "misc_de/0/sdksandbox/com.foo";
1184     CheckFileAccess(fooDePath, kSystemUid, kSystemUid, S_IFDIR | 0751);
1185 }
1186 
TEST_F(SdkSandboxDataTest,CreateAppData_CreatesSdkPackageData_WithoutSdkFlag)1187 TEST_F(SdkSandboxDataTest, CreateAppData_CreatesSdkPackageData_WithoutSdkFlag) {
1188     android::os::CreateAppDataResult result;
1189     android::os::CreateAppDataArgs args = createAppDataArgs("com.foo");
1190     args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE;
1191 
1192     // Create the app user data.
1193     ASSERT_BINDER_SUCCESS(service->createAppData(args, &result));
1194 
1195     ASSERT_FALSE(exists("/data/local/tmp/misc_ce/0/sdksandbox/com.foo"));
1196     ASSERT_FALSE(exists("/data/local/tmp/misc_de/0/sdksandbox/com.foo"));
1197 }
1198 
TEST_F(SdkSandboxDataTest,CreateAppData_CreatesSdkPackageData_WithoutSdkFlagDeletesExisting)1199 TEST_F(SdkSandboxDataTest, CreateAppData_CreatesSdkPackageData_WithoutSdkFlagDeletesExisting) {
1200     android::os::CreateAppDataResult result;
1201     android::os::CreateAppDataArgs args = createAppDataArgs("com.foo");
1202     // Create the app user data.
1203     ASSERT_BINDER_SUCCESS(service->createAppData(args, &result));
1204     ASSERT_TRUE(exists("/data/local/tmp/misc_ce/0/sdksandbox/com.foo"));
1205     ASSERT_TRUE(exists("/data/local/tmp/misc_de/0/sdksandbox/com.foo"));
1206 
1207     args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE;
1208     ASSERT_BINDER_SUCCESS(service->createAppData(args, &result));
1209     ASSERT_FALSE(exists("/data/local/tmp/misc_ce/0/sdksandbox/com.foo"));
1210     ASSERT_FALSE(exists("/data/local/tmp/misc_de/0/sdksandbox/com.foo"));
1211 }
1212 
TEST_F(SdkSandboxDataTest,CreateAppData_CreatesSdkPackageData_WithoutDeFlag)1213 TEST_F(SdkSandboxDataTest, CreateAppData_CreatesSdkPackageData_WithoutDeFlag) {
1214     android::os::CreateAppDataResult result;
1215     android::os::CreateAppDataArgs args = createAppDataArgs("com.foo");
1216     args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_SDK;
1217 
1218     // Create the app user data.
1219     ASSERT_BINDER_SUCCESS(service->createAppData(args, &result));
1220 
1221     // Only CE paths should exist
1222     CheckFileAccess("misc_ce/0/sdksandbox/com.foo", kSystemUid, kSystemUid, S_IFDIR | 0751);
1223 
1224     // DE paths should not exist
1225     ASSERT_FALSE(exists("/data/local/tmp/misc_de/0/sdksandbox/com.foo"));
1226 }
1227 
TEST_F(SdkSandboxDataTest,CreateAppData_CreatesSdkPackageData_WithoutCeFlag)1228 TEST_F(SdkSandboxDataTest, CreateAppData_CreatesSdkPackageData_WithoutCeFlag) {
1229     android::os::CreateAppDataResult result;
1230     android::os::CreateAppDataArgs args = createAppDataArgs("com.foo");
1231     args.flags = FLAG_STORAGE_DE | FLAG_STORAGE_SDK;
1232 
1233     // Create the app user data.
1234     ASSERT_BINDER_SUCCESS(service->createAppData(args, &result));
1235 
1236     // CE paths should not exist
1237     ASSERT_FALSE(exists("/data/local/tmp/misc_ce/0/sdksandbox/com.foo"));
1238 
1239     // Only DE paths should exist
1240     CheckFileAccess("misc_de/0/sdksandbox/com.foo", kSystemUid, kSystemUid, S_IFDIR | 0751);
1241 }
1242 
TEST_F(SdkSandboxDataTest,ReconcileSdkData)1243 TEST_F(SdkSandboxDataTest, ReconcileSdkData) {
1244     android::os::ReconcileSdkDataArgs args =
1245             reconcileSdkDataArgs("com.foo", {"bar@random1", "baz@random2"});
1246 
1247     // Create the sdk data.
1248     ASSERT_BINDER_SUCCESS(service->reconcileSdkData(args));
1249 
1250     const std::string barCePath = "misc_ce/0/sdksandbox/com.foo/bar@random1";
1251     CheckFileAccess(barCePath, kTestSdkSandboxUid, kNobodyUid, S_IFDIR | S_ISGID | 0700);
1252     CheckFileAccess(barCePath + "/cache", kTestSdkSandboxUid, kTestCacheGid,
1253                     S_IFDIR | S_ISGID | 0771);
1254     CheckFileAccess(barCePath + "/code_cache", kTestSdkSandboxUid, kTestCacheGid,
1255                     S_IFDIR | S_ISGID | 0771);
1256 
1257     const std::string bazCePath = "misc_ce/0/sdksandbox/com.foo/baz@random2";
1258     CheckFileAccess(bazCePath, kTestSdkSandboxUid, kNobodyUid, S_IFDIR | S_ISGID | 0700);
1259     CheckFileAccess(bazCePath + "/cache", kTestSdkSandboxUid, kTestCacheGid,
1260                     S_IFDIR | S_ISGID | 0771);
1261     CheckFileAccess(bazCePath + "/code_cache", kTestSdkSandboxUid, kTestCacheGid,
1262                     S_IFDIR | S_ISGID | 0771);
1263 
1264     const std::string barDePath = "misc_de/0/sdksandbox/com.foo/bar@random1";
1265     CheckFileAccess(barDePath, kTestSdkSandboxUid, kNobodyUid, S_IFDIR | S_ISGID | 0700);
1266     CheckFileAccess(barDePath + "/cache", kTestSdkSandboxUid, kTestCacheGid,
1267                     S_IFDIR | S_ISGID | 0771);
1268     CheckFileAccess(barDePath + "/code_cache", kTestSdkSandboxUid, kTestCacheGid,
1269                     S_IFDIR | S_ISGID | 0771);
1270 
1271     const std::string bazDePath = "misc_de/0/sdksandbox/com.foo/baz@random2";
1272     CheckFileAccess(bazDePath, kTestSdkSandboxUid, kNobodyUid, S_IFDIR | S_ISGID | 0700);
1273     CheckFileAccess(bazDePath + "/cache", kTestSdkSandboxUid, kTestCacheGid,
1274                     S_IFDIR | S_ISGID | 0771);
1275     CheckFileAccess(bazDePath + "/code_cache", kTestSdkSandboxUid, kTestCacheGid,
1276                     S_IFDIR | S_ISGID | 0771);
1277 }
1278 
TEST_F(SdkSandboxDataTest,ReconcileSdkData_ExtraCodeDirectoriesAreDeleted)1279 TEST_F(SdkSandboxDataTest, ReconcileSdkData_ExtraCodeDirectoriesAreDeleted) {
1280     android::os::ReconcileSdkDataArgs args =
1281             reconcileSdkDataArgs("com.foo", {"bar@random1", "baz@random2"});
1282 
1283     // Create the sdksandbox data.
1284     ASSERT_BINDER_SUCCESS(service->reconcileSdkData(args));
1285 
1286     // Retry with different package name
1287     args.subDirNames[0] = "bar.diff@random1";
1288 
1289     // Create the sdksandbox data again
1290     ASSERT_BINDER_SUCCESS(service->reconcileSdkData(args));
1291 
1292     // New directoris should exist
1293     CheckFileAccess("misc_ce/0/sdksandbox/com.foo/bar.diff@random1", kTestSdkSandboxUid, kNobodyUid,
1294                     S_IFDIR | S_ISGID | 0700);
1295     CheckFileAccess("misc_ce/0/sdksandbox/com.foo/baz@random2", kTestSdkSandboxUid, kNobodyUid,
1296                     S_IFDIR | S_ISGID | 0700);
1297     // Directory for old unreferred sdksandbox package name should be removed
1298     ASSERT_FALSE(exists("/data/local/tmp/misc_ce/0/sdksandbox/com.foo/bar@random1"));
1299 }
1300 
1301 class DestroyAppDataTest : public SdkSandboxDataTest {};
1302 
TEST_F(DestroyAppDataTest,DestroySdkSandboxDataDirectories_WithCeAndDeFlag)1303 TEST_F(DestroyAppDataTest, DestroySdkSandboxDataDirectories_WithCeAndDeFlag) {
1304     android::os::CreateAppDataResult result;
1305     android::os::CreateAppDataArgs args = createAppDataArgs("com.foo");
1306     args.packageName = "com.foo";
1307     // Create the app user data.
1308     ASSERT_BINDER_SUCCESS(service->createAppData(args, &result));
1309     // Destroy the app user data.
1310     ASSERT_BINDER_SUCCESS(service->destroyAppData(args.uuid, args.packageName, args.userId,
1311                                                   args.flags, result.ceDataInode));
1312     ASSERT_FALSE(exists("/data/local/tmp/misc_ce/0/sdksandbox/com.foo"));
1313     ASSERT_FALSE(exists("/data/local/tmp/misc_de/0/sdksandbox/com.foo"));
1314 }
1315 
TEST_F(DestroyAppDataTest,DestroySdkSandboxDataDirectories_WithoutDeFlag)1316 TEST_F(DestroyAppDataTest, DestroySdkSandboxDataDirectories_WithoutDeFlag) {
1317     android::os::CreateAppDataResult result;
1318     android::os::CreateAppDataArgs args = createAppDataArgs("com.foo");
1319     args.packageName = "com.foo";
1320     // Create the app user data.
1321     ASSERT_BINDER_SUCCESS(service->createAppData(args, &result));
1322     // Destroy the app user data.
1323     ASSERT_BINDER_SUCCESS(service->destroyAppData(args.uuid, args.packageName, args.userId,
1324                                                   FLAG_STORAGE_CE, result.ceDataInode));
1325     ASSERT_TRUE(exists("/data/local/tmp/misc_de/0/sdksandbox/com.foo"));
1326     ASSERT_FALSE(exists("/data/local/tmp/misc_ce/0/sdksandbox/com.foo"));
1327 }
1328 
TEST_F(DestroyAppDataTest,DestroySdkSandboxDataDirectories_WithoutCeFlag)1329 TEST_F(DestroyAppDataTest, DestroySdkSandboxDataDirectories_WithoutCeFlag) {
1330     android::os::CreateAppDataResult result;
1331     android::os::CreateAppDataArgs args = createAppDataArgs("com.foo");
1332     args.packageName = "com.foo";
1333     // Create the app user data.
1334     ASSERT_BINDER_SUCCESS(service->createAppData(args, &result));
1335     // Destroy the app user data.
1336     ASSERT_BINDER_SUCCESS(service->destroyAppData(args.uuid, args.packageName, args.userId,
1337                                                   FLAG_STORAGE_DE, result.ceDataInode));
1338     ASSERT_TRUE(exists("/data/local/tmp/misc_ce/0/sdksandbox/com.foo"));
1339     ASSERT_FALSE(exists("/data/local/tmp/misc_de/0/sdksandbox/com.foo"));
1340 }
1341 
1342 class ClearAppDataTest : public SdkSandboxDataTest {
1343 public:
createTestSdkData(const std::string & packageName,std::vector<std::string> sdkNames)1344     void createTestSdkData(const std::string& packageName, std::vector<std::string> sdkNames) {
1345         const auto& cePackagePath = "/data/local/tmp/misc_ce/0/sdksandbox/" + packageName;
1346         const auto& dePackagePath = "/data/local/tmp/misc_de/0/sdksandbox/" + packageName;
1347         ASSERT_TRUE(mkdirs(cePackagePath, 0700));
1348         ASSERT_TRUE(mkdirs(dePackagePath, 0700));
1349         const std::vector<std::string> packagePaths = {cePackagePath, dePackagePath};
1350         for (const auto& packagePath : packagePaths) {
1351             for (auto sdkName : sdkNames) {
1352                 ASSERT_TRUE(mkdirs(packagePath + "/" + sdkName + "/cache", 0700));
1353                 ASSERT_TRUE(mkdirs(packagePath + "/" + sdkName + "/code_cache", 0700));
1354                 std::ofstream{packagePath + "/" + sdkName + "/cache/cachedTestData.txt"};
1355                 std::ofstream{packagePath + "/" + sdkName + "/code_cache/cachedTestData.txt"};
1356             }
1357         }
1358     }
1359 };
1360 
TEST_F(ClearAppDataTest,ClearSdkSandboxDataDirectories_WithCeAndClearCacheFlag)1361 TEST_F(ClearAppDataTest, ClearSdkSandboxDataDirectories_WithCeAndClearCacheFlag) {
1362     createTestSdkData("com.foo", {"shared", "sdk1", "sdk2"});
1363     // Clear the app user data.
1364     ASSERT_BINDER_SUCCESS(service->clearAppData(kTestUuid, "com.foo", 0,
1365                                                 FLAG_STORAGE_CE | FLAG_CLEAR_CACHE_ONLY, -1));
1366 
1367     const std::string packagePath = kTestPath + "/misc_ce/0/sdksandbox/com.foo";
1368     ASSERT_TRUE(is_empty(packagePath + "/shared/cache"));
1369     ASSERT_TRUE(is_empty(packagePath + "/sdk1/cache"));
1370     ASSERT_TRUE(is_empty(packagePath + "/sdk2/cache"));
1371 }
1372 
TEST_F(ClearAppDataTest,ClearSdkSandboxDataDirectories_WithCeAndClearCodeCacheFlag)1373 TEST_F(ClearAppDataTest, ClearSdkSandboxDataDirectories_WithCeAndClearCodeCacheFlag) {
1374     createTestSdkData("com.foo", {"shared", "sdk1", "sdk2"});
1375     // Clear the app user data.
1376     ASSERT_BINDER_SUCCESS(service->clearAppData(kTestUuid, "com.foo", 0,
1377                                                 FLAG_STORAGE_CE | FLAG_CLEAR_CODE_CACHE_ONLY, -1));
1378 
1379     const std::string packagePath = kTestPath + "/misc_ce/0/sdksandbox/com.foo";
1380     ASSERT_TRUE(is_empty(packagePath + "/shared/code_cache"));
1381     ASSERT_TRUE(is_empty(packagePath + "/sdk1/code_cache"));
1382     ASSERT_TRUE(is_empty(packagePath + "/sdk2/code_cache"));
1383 }
1384 
TEST_F(ClearAppDataTest,ClearSdkSandboxDataDirectories_WithDeAndClearCacheFlag)1385 TEST_F(ClearAppDataTest, ClearSdkSandboxDataDirectories_WithDeAndClearCacheFlag) {
1386     createTestSdkData("com.foo", {"shared", "sdk1", "sdk2"});
1387     // Clear the app user data
1388     ASSERT_BINDER_SUCCESS(
1389             service->clearAppData(kTestUuid, "com.foo", 0,
1390                                   FLAG_STORAGE_DE | (InstalldNativeService::FLAG_CLEAR_CACHE_ONLY),
1391                                   -1));
1392 
1393     const std::string packagePath = kTestPath + "/misc_de/0/sdksandbox/com.foo";
1394     ASSERT_TRUE(is_empty(packagePath + "/shared/cache"));
1395     ASSERT_TRUE(is_empty(packagePath + "/sdk1/cache"));
1396     ASSERT_TRUE(is_empty(packagePath + "/sdk2/cache"));
1397 }
1398 
TEST_F(ClearAppDataTest,ClearSdkSandboxDataDirectories_WithDeAndClearCodeCacheFlag)1399 TEST_F(ClearAppDataTest, ClearSdkSandboxDataDirectories_WithDeAndClearCodeCacheFlag) {
1400     createTestSdkData("com.foo", {"shared", "sdk1", "sdk2"});
1401     // Clear the app user data.
1402     ASSERT_BINDER_SUCCESS(service->clearAppData(kTestUuid, "com.foo", 0,
1403                                                 FLAG_STORAGE_DE | FLAG_CLEAR_CODE_CACHE_ONLY, -1));
1404 
1405     const std::string packagePath = kTestPath + "/misc_de/0/sdksandbox/com.foo";
1406     ASSERT_TRUE(is_empty(packagePath + "/shared/code_cache"));
1407     ASSERT_TRUE(is_empty(packagePath + "/sdk1/code_cache"));
1408     ASSERT_TRUE(is_empty(packagePath + "/sdk2/code_cache"));
1409 }
1410 
TEST_F(ClearAppDataTest,ClearSdkSandboxDataDirectories_WithCeAndWithoutAnyCacheFlag)1411 TEST_F(ClearAppDataTest, ClearSdkSandboxDataDirectories_WithCeAndWithoutAnyCacheFlag) {
1412     createTestSdkData("com.foo", {"shared", "sdk1", "sdk2"});
1413     // Clear the app user data.
1414     ASSERT_BINDER_SUCCESS(service->clearAppData(kTestUuid, "com.foo", 0, FLAG_STORAGE_CE, -1));
1415 
1416     const std::string packagePath = kTestPath + "/misc_ce/0/sdksandbox/com.foo";
1417     ASSERT_TRUE(is_empty(packagePath + "/shared"));
1418     ASSERT_TRUE(is_empty(packagePath + "/sdk1"));
1419     ASSERT_TRUE(is_empty(packagePath + "/sdk2"));
1420 }
1421 
TEST_F(ClearAppDataTest,ClearSdkSandboxDataDirectories_WithDeAndWithoutAnyCacheFlag)1422 TEST_F(ClearAppDataTest, ClearSdkSandboxDataDirectories_WithDeAndWithoutAnyCacheFlag) {
1423     createTestSdkData("com.foo", {"shared", "sdk1", "sdk2"});
1424     // Clear the app user data.
1425     ASSERT_BINDER_SUCCESS(service->clearAppData(kTestUuid, "com.foo", 0, FLAG_STORAGE_DE, -1));
1426 
1427     const std::string packagePath = kTestPath + "/misc_de/0/sdksandbox/com.foo";
1428     ASSERT_TRUE(is_empty(packagePath + "/shared"));
1429     ASSERT_TRUE(is_empty(packagePath + "/sdk1"));
1430     ASSERT_TRUE(is_empty(packagePath + "/sdk2"));
1431 }
1432 
1433 class DestroyUserDataTest : public SdkSandboxDataTest {};
1434 
TEST_F(DestroyUserDataTest,DestroySdkData_WithCeFlag)1435 TEST_F(DestroyUserDataTest, DestroySdkData_WithCeFlag) {
1436     android::os::CreateAppDataResult result;
1437     android::os::CreateAppDataArgs args = createAppDataArgs("com.foo");
1438     args.packageName = "com.foo";
1439     // Create the app user data.
1440     ASSERT_BINDER_SUCCESS(service->createAppData(args, &result));
1441     // Destroy user data
1442     ASSERT_BINDER_SUCCESS(service->destroyUserData(args.uuid, args.userId, FLAG_STORAGE_CE));
1443     ASSERT_FALSE(exists("/data/local/tmp/misc_ce/0/sdksandbox"));
1444     ASSERT_TRUE(exists("/data/local/tmp/misc_de/0/sdksandbox"));
1445 }
1446 
TEST_F(DestroyUserDataTest,DestroySdkData_WithDeFlag)1447 TEST_F(DestroyUserDataTest, DestroySdkData_WithDeFlag) {
1448     android::os::CreateAppDataResult result;
1449     android::os::CreateAppDataArgs args = createAppDataArgs("com.foo");
1450     args.packageName = "com.foo";
1451     // Create the app user data.
1452     ASSERT_BINDER_SUCCESS(service->createAppData(args, &result));
1453     // Destroy user data
1454     ASSERT_BINDER_SUCCESS(service->destroyUserData(args.uuid, args.userId, FLAG_STORAGE_DE));
1455     ASSERT_TRUE(exists("/data/local/tmp/misc_ce/0/sdksandbox"));
1456     ASSERT_FALSE(exists("/data/local/tmp/misc_de/0/sdksandbox"));
1457 }
1458 
1459 }  // namespace installd
1460 }  // namespace android
1461