installd_service_test.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658
  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. #include <sstream>
  17. #include <string>
  18. #include <fcntl.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <sys/statvfs.h>
  22. #include <sys/stat.h>
  23. #include <sys/xattr.h>
  24. #include <android-base/file.h>
  25. #include <android-base/logging.h>
  26. #include <android-base/properties.h>
  27. #include <android-base/scopeguard.h>
  28. #include <android-base/stringprintf.h>
  29. #include <cutils/properties.h>
  30. #include <gtest/gtest.h>
  31. #include "binder_test_utils.h"
  32. #include "InstalldNativeService.h"
  33. #include "dexopt.h"
  34. #include "globals.h"
  35. #include "utils.h"
  36. using android::base::StringPrintf;
  37. namespace android {
  38. namespace installd {
  39. constexpr const char* kTestUuid = "TEST";
  40. #define FLAG_FORCE InstalldNativeService::FLAG_FORCE
  41. int get_property(const char *key, char *value, const char *default_value) {
  42. return property_get(key, value, default_value);
  43. }
  44. bool calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path,
  45. const char *instruction_set) {
  46. return calculate_oat_file_path_default(path, oat_dir, apk_path, instruction_set);
  47. }
  48. bool calculate_odex_file_path(char path[PKG_PATH_MAX], const char *apk_path,
  49. const char *instruction_set) {
  50. return calculate_odex_file_path_default(path, apk_path, instruction_set);
  51. }
  52. bool create_cache_path(char path[PKG_PATH_MAX], const char *src, const char *instruction_set) {
  53. return create_cache_path_default(path, src, instruction_set);
  54. }
  55. static std::string get_full_path(const char* path) {
  56. return StringPrintf("/data/local/tmp/user/0/%s", path);
  57. }
  58. static void mkdir(const char* path, uid_t owner, gid_t group, mode_t mode) {
  59. const std::string fullPath = get_full_path(path);
  60. EXPECT_EQ(::mkdir(fullPath.c_str(), mode), 0);
  61. EXPECT_EQ(::chown(fullPath.c_str(), owner, group), 0);
  62. EXPECT_EQ(::chmod(fullPath.c_str(), mode), 0);
  63. }
  64. static void touch(const char* path, uid_t owner, gid_t group, mode_t mode) {
  65. int fd = ::open(get_full_path(path).c_str(), O_RDWR | O_CREAT, mode);
  66. EXPECT_NE(fd, -1);
  67. EXPECT_EQ(::fchown(fd, owner, group), 0);
  68. EXPECT_EQ(::fchmod(fd, mode), 0);
  69. EXPECT_EQ(::close(fd), 0);
  70. }
  71. static int stat_gid(const char* path) {
  72. struct stat buf;
  73. EXPECT_EQ(::stat(get_full_path(path).c_str(), &buf), 0);
  74. return buf.st_gid;
  75. }
  76. static int stat_mode(const char* path) {
  77. struct stat buf;
  78. EXPECT_EQ(::stat(get_full_path(path).c_str(), &buf), 0);
  79. return buf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO | S_ISGID);
  80. }
  81. class ServiceTest : public testing::Test {
  82. protected:
  83. InstalldNativeService* service;
  84. std::unique_ptr<std::string> testUuid;
  85. virtual void SetUp() {
  86. setenv("ANDROID_LOG_TAGS", "*:v", 1);
  87. android::base::InitLogging(nullptr);
  88. service = new InstalldNativeService();
  89. testUuid = std::make_unique<std::string>();
  90. *testUuid = std::string(kTestUuid);
  91. system("mkdir -p /data/local/tmp/user/0");
  92. init_globals_from_data_and_root();
  93. }
  94. virtual void TearDown() {
  95. delete service;
  96. system("rm -rf /data/local/tmp/user");
  97. }
  98. };
  99. TEST_F(ServiceTest, FixupAppData_Upgrade) {
  100. LOG(INFO) << "FixupAppData_Upgrade";
  101. mkdir("com.example", 10000, 10000, 0700);
  102. mkdir("com.example/normal", 10000, 10000, 0700);
  103. mkdir("com.example/cache", 10000, 10000, 0700);
  104. touch("com.example/cache/file", 10000, 10000, 0700);
  105. service->fixupAppData(testUuid, 0);
  106. EXPECT_EQ(10000, stat_gid("com.example/normal"));
  107. EXPECT_EQ(20000, stat_gid("com.example/cache"));
  108. EXPECT_EQ(20000, stat_gid("com.example/cache/file"));
  109. EXPECT_EQ(0700, stat_mode("com.example/normal"));
  110. EXPECT_EQ(02771, stat_mode("com.example/cache"));
  111. EXPECT_EQ(0700, stat_mode("com.example/cache/file"));
  112. }
  113. TEST_F(ServiceTest, FixupAppData_Moved) {
  114. LOG(INFO) << "FixupAppData_Moved";
  115. mkdir("com.example", 10000, 10000, 0700);
  116. mkdir("com.example/foo", 10000, 10000, 0700);
  117. touch("com.example/foo/file", 10000, 20000, 0700);
  118. mkdir("com.example/bar", 10000, 20000, 0700);
  119. touch("com.example/bar/file", 10000, 20000, 0700);
  120. service->fixupAppData(testUuid, 0);
  121. EXPECT_EQ(10000, stat_gid("com.example/foo"));
  122. EXPECT_EQ(20000, stat_gid("com.example/foo/file"));
  123. EXPECT_EQ(10000, stat_gid("com.example/bar"));
  124. EXPECT_EQ(10000, stat_gid("com.example/bar/file"));
  125. service->fixupAppData(testUuid, FLAG_FORCE);
  126. EXPECT_EQ(10000, stat_gid("com.example/foo"));
  127. EXPECT_EQ(10000, stat_gid("com.example/foo/file"));
  128. EXPECT_EQ(10000, stat_gid("com.example/bar"));
  129. EXPECT_EQ(10000, stat_gid("com.example/bar/file"));
  130. }
  131. TEST_F(ServiceTest, HashSecondaryDex) {
  132. LOG(INFO) << "HashSecondaryDex";
  133. mkdir("com.example", 10000, 10000, 0700);
  134. mkdir("com.example/foo", 10000, 10000, 0700);
  135. touch("com.example/foo/file", 10000, 20000, 0700);
  136. std::vector<uint8_t> result;
  137. std::string dexPath = get_full_path("com.example/foo/file");
  138. EXPECT_BINDER_SUCCESS(service->hashSecondaryDexFile(
  139. dexPath, "com.example", 10000, testUuid, FLAG_STORAGE_CE, &result));
  140. EXPECT_EQ(result.size(), 32U);
  141. std::ostringstream output;
  142. output << std::hex << std::setfill('0');
  143. for (auto b : result) {
  144. output << std::setw(2) << +b;
  145. }
  146. // This is the SHA256 of an empty string (sha256sum /dev/null)
  147. EXPECT_EQ(output.str(), "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
  148. }
  149. TEST_F(ServiceTest, HashSecondaryDex_NoSuch) {
  150. LOG(INFO) << "HashSecondaryDex_NoSuch";
  151. std::vector<uint8_t> result;
  152. std::string dexPath = get_full_path("com.example/foo/file");
  153. EXPECT_BINDER_SUCCESS(service->hashSecondaryDexFile(
  154. dexPath, "com.example", 10000, testUuid, FLAG_STORAGE_CE, &result));
  155. EXPECT_EQ(result.size(), 0U);
  156. }
  157. TEST_F(ServiceTest, HashSecondaryDex_Unreadable) {
  158. LOG(INFO) << "HashSecondaryDex_Unreadable";
  159. mkdir("com.example", 10000, 10000, 0700);
  160. mkdir("com.example/foo", 10000, 10000, 0700);
  161. touch("com.example/foo/file", 10000, 20000, 0300);
  162. std::vector<uint8_t> result;
  163. std::string dexPath = get_full_path("com.example/foo/file");
  164. EXPECT_BINDER_SUCCESS(service->hashSecondaryDexFile(
  165. dexPath, "com.example", 10000, testUuid, FLAG_STORAGE_CE, &result));
  166. EXPECT_EQ(result.size(), 0U);
  167. }
  168. TEST_F(ServiceTest, HashSecondaryDex_WrongApp) {
  169. LOG(INFO) << "HashSecondaryDex_WrongApp";
  170. mkdir("com.example", 10000, 10000, 0700);
  171. mkdir("com.example/foo", 10000, 10000, 0700);
  172. touch("com.example/foo/file", 10000, 20000, 0700);
  173. std::vector<uint8_t> result;
  174. std::string dexPath = get_full_path("com.example/foo/file");
  175. EXPECT_BINDER_FAIL(service->hashSecondaryDexFile(
  176. dexPath, "com.wrong", 10000, testUuid, FLAG_STORAGE_CE, &result));
  177. }
  178. TEST_F(ServiceTest, CalculateOat) {
  179. char buf[PKG_PATH_MAX];
  180. EXPECT_TRUE(calculate_oat_file_path(buf, "/path/to/oat", "/path/to/file.apk", "isa"));
  181. EXPECT_EQ("/path/to/oat/isa/file.odex", std::string(buf));
  182. EXPECT_FALSE(calculate_oat_file_path(buf, "/path/to/oat", "/path/to/file", "isa"));
  183. EXPECT_FALSE(calculate_oat_file_path(buf, "/path/to/oat", "file", "isa"));
  184. }
  185. TEST_F(ServiceTest, CalculateOdex) {
  186. char buf[PKG_PATH_MAX];
  187. EXPECT_TRUE(calculate_odex_file_path(buf, "/path/to/file.apk", "isa"));
  188. EXPECT_EQ("/path/to/oat/isa/file.odex", std::string(buf));
  189. }
  190. TEST_F(ServiceTest, CalculateCache) {
  191. char buf[PKG_PATH_MAX];
  192. EXPECT_TRUE(create_cache_path(buf, "/path/to/file.apk", "isa"));
  193. EXPECT_EQ("/data/dalvik-cache/isa/path@[email protected]@classes.dex", std::string(buf));
  194. }
  195. static bool mkdirs(const std::string& path, mode_t mode) {
  196. struct stat sb;
  197. if (stat(path.c_str(), &sb) != -1 && S_ISDIR(sb.st_mode)) {
  198. return true;
  199. }
  200. if (!mkdirs(android::base::Dirname(path), mode)) {
  201. return false;
  202. }
  203. if (::mkdir(path.c_str(), mode) != 0) {
  204. PLOG(DEBUG) << "Failed to create folder " << path;
  205. return false;
  206. }
  207. return true;
  208. }
  209. class AppDataSnapshotTest : public testing::Test {
  210. private:
  211. std::string rollback_ce_base_dir;
  212. std::string rollback_de_base_dir;
  213. protected:
  214. InstalldNativeService* service;
  215. std::string fake_package_ce_path;
  216. std::string fake_package_de_path;
  217. virtual void SetUp() {
  218. setenv("ANDROID_LOG_TAGS", "*:v", 1);
  219. android::base::InitLogging(nullptr);
  220. service = new InstalldNativeService();
  221. ASSERT_TRUE(mkdirs("/data/local/tmp/user/0", 0700));
  222. init_globals_from_data_and_root();
  223. rollback_ce_base_dir = create_data_misc_ce_rollback_base_path("TEST", 0);
  224. rollback_de_base_dir = create_data_misc_de_rollback_base_path("TEST", 0);
  225. fake_package_ce_path = create_data_user_ce_package_path("TEST", 0, "com.foo");
  226. fake_package_de_path = create_data_user_de_package_path("TEST", 0, "com.foo");
  227. ASSERT_TRUE(mkdirs(rollback_ce_base_dir, 0700));
  228. ASSERT_TRUE(mkdirs(rollback_de_base_dir, 0700));
  229. ASSERT_TRUE(mkdirs(fake_package_ce_path, 0700));
  230. ASSERT_TRUE(mkdirs(fake_package_de_path, 0700));
  231. }
  232. virtual void TearDown() {
  233. ASSERT_EQ(0, delete_dir_contents_and_dir(rollback_ce_base_dir, true));
  234. ASSERT_EQ(0, delete_dir_contents_and_dir(rollback_de_base_dir, true));
  235. ASSERT_EQ(0, delete_dir_contents(fake_package_ce_path, true));
  236. ASSERT_EQ(0, delete_dir_contents(fake_package_de_path, true));
  237. delete service;
  238. ASSERT_EQ(0, delete_dir_contents_and_dir("/data/local/tmp/user/0", true));
  239. }
  240. };
  241. TEST_F(AppDataSnapshotTest, CreateAppDataSnapshot) {
  242. auto rollback_ce_dir = create_data_misc_ce_rollback_path("TEST", 0, 37);
  243. auto rollback_de_dir = create_data_misc_de_rollback_path("TEST", 0, 37);
  244. ASSERT_TRUE(android::base::WriteStringToFile(
  245. "TEST_CONTENT_CE", fake_package_ce_path + "/file1",
  246. 0700, 10000, 20000, false /* follow_symlinks */));
  247. ASSERT_TRUE(android::base::WriteStringToFile(
  248. "TEST_CONTENT_DE", fake_package_de_path + "/file1",
  249. 0700, 10000, 20000, false /* follow_symlinks */));
  250. // Request a snapshot of the CE content but not the DE content.
  251. int64_t ce_snapshot_inode;
  252. ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_unique<std::string>("TEST"),
  253. "com.foo", 0, 37, FLAG_STORAGE_CE, &ce_snapshot_inode));
  254. struct stat buf;
  255. memset(&buf, 0, sizeof(buf));
  256. ASSERT_EQ(0, stat((rollback_ce_dir + "/com.foo").c_str(), &buf));
  257. ASSERT_EQ(ce_snapshot_inode, (int64_t) buf.st_ino);
  258. std::string ce_content, de_content;
  259. // At this point, we should have the CE content but not the DE content.
  260. ASSERT_TRUE(android::base::ReadFileToString(
  261. rollback_ce_dir + "/com.foo/file1", &ce_content, false /* follow_symlinks */));
  262. ASSERT_FALSE(android::base::ReadFileToString(
  263. rollback_de_dir + "/com.foo/file1", &de_content, false /* follow_symlinks */));
  264. ASSERT_EQ("TEST_CONTENT_CE", ce_content);
  265. // Modify the CE content, so we can assert later that it's reflected
  266. // in the snapshot.
  267. ASSERT_TRUE(android::base::WriteStringToFile(
  268. "TEST_CONTENT_CE_MODIFIED", fake_package_ce_path + "/file1",
  269. 0700, 10000, 20000, false /* follow_symlinks */));
  270. // Request a snapshot of the DE content but not the CE content.
  271. ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_unique<std::string>("TEST"),
  272. "com.foo", 0, 37, FLAG_STORAGE_DE, &ce_snapshot_inode));
  273. // Only DE content snapshot was requested.
  274. ASSERT_EQ(ce_snapshot_inode, 0);
  275. // At this point, both the CE as well as the DE content should be fully
  276. // populated.
  277. ASSERT_TRUE(android::base::ReadFileToString(
  278. rollback_ce_dir + "/com.foo/file1", &ce_content, false /* follow_symlinks */));
  279. ASSERT_TRUE(android::base::ReadFileToString(
  280. rollback_de_dir + "/com.foo/file1", &de_content, false /* follow_symlinks */));
  281. ASSERT_EQ("TEST_CONTENT_CE", ce_content);
  282. ASSERT_EQ("TEST_CONTENT_DE", de_content);
  283. // Modify the DE content, so we can assert later that it's reflected
  284. // in our final snapshot.
  285. ASSERT_TRUE(android::base::WriteStringToFile(
  286. "TEST_CONTENT_DE_MODIFIED", fake_package_de_path + "/file1",
  287. 0700, 10000, 20000, false /* follow_symlinks */));
  288. // Request a snapshot of both the CE as well as the DE content.
  289. ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_unique<std::string>("TEST"),
  290. "com.foo", 0, 37, FLAG_STORAGE_DE | FLAG_STORAGE_CE, nullptr));
  291. ASSERT_TRUE(android::base::ReadFileToString(
  292. rollback_ce_dir + "/com.foo/file1", &ce_content, false /* follow_symlinks */));
  293. ASSERT_TRUE(android::base::ReadFileToString(
  294. rollback_de_dir + "/com.foo/file1", &de_content, false /* follow_symlinks */));
  295. ASSERT_EQ("TEST_CONTENT_CE_MODIFIED", ce_content);
  296. ASSERT_EQ("TEST_CONTENT_DE_MODIFIED", de_content);
  297. }
  298. TEST_F(AppDataSnapshotTest, CreateAppDataSnapshot_TwoSnapshotsWithTheSameId) {
  299. auto rollback_ce_dir = create_data_misc_ce_rollback_path("TEST", 0, 67);
  300. auto rollback_de_dir = create_data_misc_de_rollback_path("TEST", 0, 67);
  301. auto another_fake_package_ce_path = create_data_user_ce_package_path("TEST", 0, "com.bar");
  302. auto another_fake_package_de_path = create_data_user_de_package_path("TEST", 0, "com.bar");
  303. // Since this test sets up data for another package, some bookkeeping is required.
  304. auto deleter = [&]() {
  305. ASSERT_EQ(0, delete_dir_contents_and_dir(another_fake_package_ce_path, true));
  306. ASSERT_EQ(0, delete_dir_contents_and_dir(another_fake_package_de_path, true));
  307. };
  308. auto scope_guard = android::base::make_scope_guard(deleter);
  309. ASSERT_TRUE(mkdirs(another_fake_package_ce_path, 0700));
  310. ASSERT_TRUE(mkdirs(another_fake_package_de_path, 0700));
  311. ASSERT_TRUE(android::base::WriteStringToFile(
  312. "TEST_CONTENT_CE", fake_package_ce_path + "/file1",
  313. 0700, 10000, 20000, false /* follow_symlinks */));
  314. ASSERT_TRUE(android::base::WriteStringToFile(
  315. "TEST_CONTENT_DE", fake_package_de_path + "/file1",
  316. 0700, 10000, 20000, false /* follow_symlinks */));
  317. ASSERT_TRUE(android::base::WriteStringToFile(
  318. "ANOTHER_TEST_CONTENT_CE", another_fake_package_ce_path + "/file1",
  319. 0700, 10000, 20000, false /* follow_symlinks */));
  320. ASSERT_TRUE(android::base::WriteStringToFile(
  321. "ANOTHER_TEST_CONTENT_DE", another_fake_package_de_path + "/file1",
  322. 0700, 10000, 20000, false /* follow_symlinks */));
  323. // Request snapshot for the package com.foo.
  324. ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_unique<std::string>("TEST"),
  325. "com.foo", 0, 67, FLAG_STORAGE_DE | FLAG_STORAGE_CE, nullptr));
  326. // Now request snapshot with the same id for the package com.bar
  327. ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_unique<std::string>("TEST"),
  328. "com.bar", 0, 67, FLAG_STORAGE_DE | FLAG_STORAGE_CE, nullptr));
  329. // Check that both snapshots have correct data in them.
  330. std::string com_foo_ce_content, com_foo_de_content;
  331. std::string com_bar_ce_content, com_bar_de_content;
  332. ASSERT_TRUE(android::base::ReadFileToString(
  333. rollback_ce_dir + "/com.foo/file1", &com_foo_ce_content, false /* follow_symlinks */));
  334. ASSERT_TRUE(android::base::ReadFileToString(
  335. rollback_de_dir + "/com.foo/file1", &com_foo_de_content, false /* follow_symlinks */));
  336. ASSERT_TRUE(android::base::ReadFileToString(
  337. rollback_ce_dir + "/com.bar/file1", &com_bar_ce_content, false /* follow_symlinks */));
  338. ASSERT_TRUE(android::base::ReadFileToString(
  339. rollback_de_dir + "/com.bar/file1", &com_bar_de_content, false /* follow_symlinks */));
  340. ASSERT_EQ("TEST_CONTENT_CE", com_foo_ce_content);
  341. ASSERT_EQ("TEST_CONTENT_DE", com_foo_de_content);
  342. ASSERT_EQ("ANOTHER_TEST_CONTENT_CE", com_bar_ce_content);
  343. ASSERT_EQ("ANOTHER_TEST_CONTENT_DE", com_bar_de_content);
  344. }
  345. TEST_F(AppDataSnapshotTest, CreateAppDataSnapshot_AppDataAbsent) {
  346. auto rollback_ce_dir = create_data_misc_ce_rollback_path("TEST", 0, 73);
  347. auto rollback_de_dir = create_data_misc_de_rollback_path("TEST", 0, 73);
  348. // Similuating app data absence.
  349. ASSERT_EQ(0, delete_dir_contents_and_dir(fake_package_ce_path, true));
  350. ASSERT_EQ(0, delete_dir_contents_and_dir(fake_package_de_path, true));
  351. int64_t ce_snapshot_inode;
  352. ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_unique<std::string>("TEST"),
  353. "com.foo", 0, 73, FLAG_STORAGE_CE, &ce_snapshot_inode));
  354. ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_unique<std::string>("TEST"),
  355. "com.foo", 0, 73, FLAG_STORAGE_DE, nullptr));
  356. // No CE content snapshot was performed.
  357. ASSERT_EQ(ce_snapshot_inode, 0);
  358. // The snapshot calls must succeed but there should be no snapshot
  359. // created.
  360. struct stat sb;
  361. ASSERT_EQ(-1, stat((rollback_ce_dir + "/com.foo").c_str(), &sb));
  362. ASSERT_EQ(-1, stat((rollback_de_dir + "/com.foo").c_str(), &sb));
  363. }
  364. TEST_F(AppDataSnapshotTest, CreateAppDataSnapshot_ClearsExistingSnapshot) {
  365. auto rollback_ce_dir = create_data_misc_ce_rollback_package_path("TEST", 0, 13, "com.foo");
  366. auto rollback_de_dir = create_data_misc_de_rollback_package_path("TEST", 0, 13, "com.foo");
  367. ASSERT_TRUE(mkdirs(rollback_ce_dir, 0700));
  368. ASSERT_TRUE(mkdirs(rollback_de_dir, 0700));
  369. // Simulate presence of an existing snapshot
  370. ASSERT_TRUE(android::base::WriteStringToFile(
  371. "TEST_CONTENT_CE", rollback_ce_dir + "/file1",
  372. 0700, 10000, 20000, false /* follow_symlinks */));
  373. ASSERT_TRUE(android::base::WriteStringToFile(
  374. "TEST_CONTENT_DE", rollback_de_dir + "/file1",
  375. 0700, 10000, 20000, false /* follow_symlinks */));
  376. // Create app data.
  377. ASSERT_TRUE(android::base::WriteStringToFile(
  378. "TEST_CONTENT_2_CE", fake_package_ce_path + "/file2",
  379. 0700, 10000, 20000, false /* follow_symlinks */));
  380. ASSERT_TRUE(android::base::WriteStringToFile(
  381. "TEST_CONTENT_2_DE", fake_package_de_path + "/file2",
  382. 0700, 10000, 20000, false /* follow_symlinks */));
  383. ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_unique<std::string>("TEST"),
  384. "com.foo", 0, 13, FLAG_STORAGE_DE | FLAG_STORAGE_CE, nullptr));
  385. // Previous snapshot (with data for file1) must be cleared.
  386. struct stat sb;
  387. ASSERT_EQ(-1, stat((rollback_ce_dir + "/file1").c_str(), &sb));
  388. ASSERT_EQ(-1, stat((rollback_de_dir + "/file1").c_str(), &sb));
  389. // New snapshot (with data for file2) must be present.
  390. ASSERT_NE(-1, stat((rollback_ce_dir + "/file2").c_str(), &sb));
  391. ASSERT_NE(-1, stat((rollback_de_dir + "/file2").c_str(), &sb));
  392. }
  393. TEST_F(AppDataSnapshotTest, SnapshotAppData_WrongVolumeUuid) {
  394. // Setup rollback folders to make sure that fails due to wrong volumeUuid being
  395. // passed, not because of some other reason.
  396. auto rollback_ce_dir = create_data_misc_ce_rollback_path("TEST", 0, 17);
  397. auto rollback_de_dir = create_data_misc_de_rollback_path("TEST", 0, 17);
  398. ASSERT_TRUE(mkdirs(rollback_ce_dir, 0700));
  399. ASSERT_TRUE(mkdirs(rollback_de_dir, 0700));
  400. EXPECT_BINDER_FAIL(service->snapshotAppData(std::make_unique<std::string>("FOO"),
  401. "com.foo", 0, 17, FLAG_STORAGE_DE, nullptr));
  402. }
  403. TEST_F(AppDataSnapshotTest, CreateAppDataSnapshot_ClearsCache) {
  404. auto fake_package_ce_cache_path = fake_package_ce_path + "/cache";
  405. auto fake_package_ce_code_cache_path = fake_package_ce_path + "/code_cache";
  406. auto fake_package_de_cache_path = fake_package_de_path + "/cache";
  407. auto fake_package_de_code_cache_path = fake_package_de_path + "/code_cache";
  408. ASSERT_TRUE(mkdirs(fake_package_ce_cache_path, 0700));
  409. ASSERT_TRUE(mkdirs(fake_package_ce_code_cache_path, 0700));
  410. ASSERT_TRUE(mkdirs(fake_package_de_cache_path, 0700));
  411. ASSERT_TRUE(mkdirs(fake_package_de_code_cache_path, 0700));
  412. ASSERT_TRUE(android::base::WriteStringToFile(
  413. "TEST_CONTENT_CE", fake_package_ce_cache_path + "/file1",
  414. 0700, 10000, 20000, false /* follow_symlinks */));
  415. ASSERT_TRUE(android::base::WriteStringToFile(
  416. "TEST_CONTENT_CE", fake_package_ce_code_cache_path + "/file1",
  417. 0700, 10000, 20000, false /* follow_symlinks */));
  418. ASSERT_TRUE(android::base::WriteStringToFile(
  419. "TEST_CONTENT_DE", fake_package_de_cache_path + "/file1",
  420. 0700, 10000, 20000, false /* follow_symlinks */));
  421. ASSERT_TRUE(android::base::WriteStringToFile(
  422. "TEST_CONTENT_DE", fake_package_de_code_cache_path + "/file1",
  423. 0700, 10000, 20000, false /* follow_symlinks */));
  424. ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_unique<std::string>("TEST"),
  425. "com.foo", 0, 23, FLAG_STORAGE_CE | FLAG_STORAGE_DE, nullptr));
  426. // The snapshot call must clear cache.
  427. struct stat sb;
  428. ASSERT_EQ(-1, stat((fake_package_ce_cache_path + "/file1").c_str(), &sb));
  429. ASSERT_EQ(-1, stat((fake_package_ce_code_cache_path + "/file1").c_str(), &sb));
  430. ASSERT_EQ(-1, stat((fake_package_de_cache_path + "/file1").c_str(), &sb));
  431. ASSERT_EQ(-1, stat((fake_package_de_code_cache_path + "/file1").c_str(), &sb));
  432. }
  433. TEST_F(AppDataSnapshotTest, RestoreAppDataSnapshot) {
  434. auto rollback_ce_dir = create_data_misc_ce_rollback_path("TEST", 0, 239);
  435. auto rollback_de_dir = create_data_misc_de_rollback_path("TEST", 0, 239);
  436. ASSERT_TRUE(mkdirs(rollback_ce_dir, 0700));
  437. ASSERT_TRUE(mkdirs(rollback_de_dir, 0700));
  438. // Write contents to the rollback location. We'll write the same files to the
  439. // app data location and make sure the restore has overwritten them.
  440. ASSERT_TRUE(mkdirs(rollback_ce_dir + "/com.foo/", 0700));
  441. ASSERT_TRUE(mkdirs(rollback_de_dir + "/com.foo/", 0700));
  442. ASSERT_TRUE(android::base::WriteStringToFile(
  443. "CE_RESTORE_CONTENT", rollback_ce_dir + "/com.foo/file1",
  444. 0700, 10000, 20000, false /* follow_symlinks */));
  445. ASSERT_TRUE(android::base::WriteStringToFile(
  446. "DE_RESTORE_CONTENT", rollback_de_dir + "/com.foo/file1",
  447. 0700, 10000, 20000, false /* follow_symlinks */));
  448. ASSERT_TRUE(android::base::WriteStringToFile(
  449. "TEST_CONTENT_CE", fake_package_ce_path + "/file1",
  450. 0700, 10000, 20000, false /* follow_symlinks */));
  451. ASSERT_TRUE(android::base::WriteStringToFile(
  452. "TEST_CONTENT_DE", fake_package_de_path + "/file1",
  453. 0700, 10000, 20000, false /* follow_symlinks */));
  454. ASSERT_BINDER_SUCCESS(service->restoreAppDataSnapshot(std::make_unique<std::string>("TEST"),
  455. "com.foo", 10000, "", 0, 239, FLAG_STORAGE_DE | FLAG_STORAGE_CE));
  456. std::string ce_content, de_content;
  457. ASSERT_TRUE(android::base::ReadFileToString(
  458. fake_package_ce_path + "/file1", &ce_content, false /* follow_symlinks */));
  459. ASSERT_TRUE(android::base::ReadFileToString(
  460. fake_package_de_path + "/file1", &de_content, false /* follow_symlinks */));
  461. ASSERT_EQ("CE_RESTORE_CONTENT", ce_content);
  462. ASSERT_EQ("DE_RESTORE_CONTENT", de_content);
  463. }
  464. TEST_F(AppDataSnapshotTest, CreateSnapshotThenDestroyIt) {
  465. auto rollback_ce_dir = create_data_misc_ce_rollback_path("TEST", 0, 57);
  466. auto rollback_de_dir = create_data_misc_de_rollback_path("TEST", 0, 57);
  467. // Prepare data for snapshot.
  468. ASSERT_TRUE(android::base::WriteStringToFile(
  469. "TEST_CONTENT_CE", fake_package_ce_path + "/file1",
  470. 0700, 10000, 20000, false /* follow_symlinks */));
  471. ASSERT_TRUE(android::base::WriteStringToFile(
  472. "TEST_CONTENT_DE", fake_package_de_path + "/file1",
  473. 0700, 10000, 20000, false /* follow_symlinks */));
  474. int64_t ce_snapshot_inode;
  475. // Request a snapshot of both the CE as well as the DE content.
  476. ASSERT_TRUE(service->snapshotAppData(std::make_unique<std::string>("TEST"),
  477. "com.foo", 0, 57, FLAG_STORAGE_DE | FLAG_STORAGE_CE, &ce_snapshot_inode).isOk());
  478. // Because CE data snapshot was requested, ce_snapshot_inode can't be null.
  479. ASSERT_NE(0, ce_snapshot_inode);
  480. // Check snapshot is there.
  481. struct stat sb;
  482. ASSERT_EQ(0, stat((rollback_ce_dir + "/com.foo").c_str(), &sb));
  483. ASSERT_EQ(0, stat((rollback_de_dir + "/com.foo").c_str(), &sb));
  484. ASSERT_TRUE(service->destroyAppDataSnapshot(std::make_unique<std::string>("TEST"),
  485. "com.foo", 0, ce_snapshot_inode, 57, FLAG_STORAGE_DE | FLAG_STORAGE_CE).isOk());
  486. // Check snapshot is deleted.
  487. ASSERT_EQ(-1, stat((rollback_ce_dir + "/com.foo").c_str(), &sb));
  488. ASSERT_EQ(-1, stat((rollback_de_dir + "/com.foo").c_str(), &sb));
  489. }
  490. TEST_F(AppDataSnapshotTest, DestroyAppDataSnapshot_CeSnapshotInodeIsZero) {
  491. auto rollback_ce_dir = create_data_misc_ce_rollback_path("TEST", 0, 1543);
  492. auto rollback_de_dir = create_data_misc_de_rollback_path("TEST", 0, 1543);
  493. // Create a snapshot
  494. ASSERT_TRUE(mkdirs(rollback_ce_dir + "/com.foo/", 0700));
  495. ASSERT_TRUE(mkdirs(rollback_de_dir + "/com.foo/", 0700));
  496. ASSERT_TRUE(android::base::WriteStringToFile(
  497. "CE_RESTORE_CONTENT", rollback_ce_dir + "/com.foo/file1",
  498. 0700, 10000, 20000, false /* follow_symlinks */));
  499. ASSERT_TRUE(android::base::WriteStringToFile(
  500. "DE_RESTORE_CONTENT", rollback_de_dir + "/com.foo/file1",
  501. 0700, 10000, 20000, false /* follow_symlinks */));
  502. ASSERT_TRUE(service->destroyAppDataSnapshot(std::make_unique<std::string>("TEST"),
  503. "com.foo", 0, 0, 1543, FLAG_STORAGE_DE | FLAG_STORAGE_CE).isOk());
  504. // Check snapshot is deleted.
  505. struct stat sb;
  506. ASSERT_EQ(-1, stat((rollback_ce_dir + "/com.foo").c_str(), &sb));
  507. ASSERT_EQ(-1, stat((rollback_de_dir + "/com.foo").c_str(), &sb));
  508. // Check that deleting already deleted snapshot is no-op.
  509. ASSERT_TRUE(service->destroyAppDataSnapshot(std::make_unique<std::string>("TEST"),
  510. "com.foo", 0, 0, 1543, FLAG_STORAGE_DE | FLAG_STORAGE_CE).isOk());
  511. }
  512. TEST_F(AppDataSnapshotTest, DestroyAppDataSnapshot_WrongVolumeUuid) {
  513. // Setup rollback data to make sure that test fails due to wrong volumeUuid
  514. // being passed, not because of some other reason.
  515. auto rollback_ce_dir = create_data_misc_ce_rollback_path("TEST", 0, 43);
  516. auto rollback_de_dir = create_data_misc_de_rollback_path("TEST", 0, 43);
  517. ASSERT_TRUE(mkdirs(rollback_ce_dir, 0700));
  518. ASSERT_TRUE(mkdirs(rollback_de_dir, 0700));
  519. ASSERT_FALSE(service->destroyAppDataSnapshot(std::make_unique<std::string>("BAR"),
  520. "com.foo", 0, 0, 43, FLAG_STORAGE_DE).isOk());
  521. }
  522. TEST_F(AppDataSnapshotTest, RestoreAppDataSnapshot_WrongVolumeUuid) {
  523. // Setup rollback data to make sure that fails due to wrong volumeUuid being
  524. // passed, not because of some other reason.
  525. auto rollback_ce_dir = create_data_misc_ce_rollback_path("TEST", 0, 41);
  526. auto rollback_de_dir = create_data_misc_de_rollback_path("TEST", 0, 41);
  527. ASSERT_TRUE(mkdirs(rollback_ce_dir, 0700));
  528. ASSERT_TRUE(mkdirs(rollback_de_dir, 0700));
  529. EXPECT_BINDER_FAIL(service->restoreAppDataSnapshot(std::make_unique<std::string>("BAR"),
  530. "com.foo", 10000, "", 0, 41, FLAG_STORAGE_DE));
  531. }
  532. } // namespace installd
  533. } // namespace android