installd_dexopt_test.cpp 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257
  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 <cstdlib>
  17. #include <fcntl.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <sys/types.h>
  21. #include <sys/stat.h>
  22. #include <android-base/file.h>
  23. #include <android-base/logging.h>
  24. #include <android-base/properties.h>
  25. #include <android-base/scopeguard.h>
  26. #include <android-base/stringprintf.h>
  27. #include <android-base/unique_fd.h>
  28. #include <binder/Status.h>
  29. #include <cutils/properties.h>
  30. #include <gtest/gtest.h>
  31. #include <selinux/android.h>
  32. #include <selinux/avc.h>
  33. #include "binder_test_utils.h"
  34. #include "dexopt.h"
  35. #include "InstalldNativeService.h"
  36. #include "globals.h"
  37. #include "tests/test_utils.h"
  38. #include "utils.h"
  39. using android::base::ReadFully;
  40. using android::base::unique_fd;
  41. namespace android {
  42. namespace installd {
  43. // TODO(calin): try to dedup this code.
  44. #if defined(__arm__)
  45. static const std::string kRuntimeIsa = "arm";
  46. #elif defined(__aarch64__)
  47. static const std::string kRuntimeIsa = "arm64";
  48. #elif defined(__mips__) && !defined(__LP64__)
  49. static const std::string kRuntimeIsa = "mips";
  50. #elif defined(__mips__) && defined(__LP64__)
  51. static const std::string kRuntimeIsa = "mips64";
  52. #elif defined(__i386__)
  53. static const std::string kRuntimeIsa = "x86";
  54. #elif defined(__x86_64__)
  55. static const std::string kRuntimeIsa = "x86_64";
  56. #else
  57. static const std::string kRuntimeIsa = "none";
  58. #endif
  59. int get_property(const char *key, char *value, const char *default_value) {
  60. return property_get(key, value, default_value);
  61. }
  62. bool calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path,
  63. const char *instruction_set) {
  64. return calculate_oat_file_path_default(path, oat_dir, apk_path, instruction_set);
  65. }
  66. bool calculate_odex_file_path(char path[PKG_PATH_MAX], const char *apk_path,
  67. const char *instruction_set) {
  68. return calculate_odex_file_path_default(path, apk_path, instruction_set);
  69. }
  70. bool create_cache_path(char path[PKG_PATH_MAX], const char *src, const char *instruction_set) {
  71. return create_cache_path_default(path, src, instruction_set);
  72. }
  73. static void run_cmd(const std::string& cmd) {
  74. system(cmd.c_str());
  75. }
  76. template <typename Visitor>
  77. static void run_cmd_and_process_output(const std::string& cmd, const Visitor& visitor) {
  78. FILE* file = popen(cmd.c_str(), "r");
  79. CHECK(file != nullptr) << "Failed to ptrace " << cmd;
  80. char* line = nullptr;
  81. while (true) {
  82. size_t n = 0u;
  83. ssize_t value = getline(&line, &n, file);
  84. if (value == -1) {
  85. break;
  86. }
  87. visitor(line);
  88. }
  89. free(line);
  90. fclose(file);
  91. }
  92. static int mkdir(const std::string& path, uid_t owner, gid_t group, mode_t mode) {
  93. int ret = ::mkdir(path.c_str(), mode);
  94. if (ret != 0) {
  95. return ret;
  96. }
  97. ret = ::chown(path.c_str(), owner, group);
  98. if (ret != 0) {
  99. return ret;
  100. }
  101. return ::chmod(path.c_str(), mode);
  102. }
  103. static int log_callback(int type, const char *fmt, ...) { // NOLINT
  104. va_list ap;
  105. int priority;
  106. switch (type) {
  107. case SELINUX_WARNING:
  108. priority = ANDROID_LOG_WARN;
  109. break;
  110. case SELINUX_INFO:
  111. priority = ANDROID_LOG_INFO;
  112. break;
  113. default:
  114. priority = ANDROID_LOG_ERROR;
  115. break;
  116. }
  117. va_start(ap, fmt);
  118. LOG_PRI_VA(priority, "SELinux", fmt, ap);
  119. va_end(ap);
  120. return 0;
  121. }
  122. static bool init_selinux() {
  123. int selinux_enabled = (is_selinux_enabled() > 0);
  124. union selinux_callback cb;
  125. cb.func_log = log_callback;
  126. selinux_set_callback(SELINUX_CB_LOG, cb);
  127. if (selinux_enabled && selinux_status_open(true) < 0) {
  128. LOG(ERROR) << "Could not open selinux status; exiting";
  129. return false;
  130. }
  131. return true;
  132. }
  133. // Base64 encoding of a simple dex files with 2 methods.
  134. static const char kDexFile[] =
  135. "UEsDBBQAAAAIAOiOYUs9y6BLCgEAABQCAAALABwAY2xhc3Nlcy5kZXhVVAkAA/Ns+lkOHv1ZdXgL"
  136. "AAEEI+UCAASIEwAAS0mt4DIwNmX4qpn7j/2wA7v7N+ZvoQpCJRlVx5SWa4YaiDAxMBQwMDBUhJkI"
  137. "MUBBDyMDAzsDRJwFxAdioBDDHAYEYAbiFUAM1M5wAIhFGCGKDIDYAogdgNgDiH2BOAiI0xghekDm"
  138. "sQIxGxQzM6ACRijNhCbOhCZfyohdPYyuh8szgtVkMkLsLhAAqeCDi+ejibPZZOZlltgxsDnqZSWW"
  139. "JTKwOUFoZh9HayDhZM0g5AMS0M9JzEvX90/KSk0usWZgDAMaws5nAyXBzmpoYGlgAjsAyJoBMp0b"
  140. "zQ8gGhbOTEhhzYwU3qxIYc2GFN6MClC/AhUyKUDMAYU9M1Qc5F8GKBscVgIQM0FxCwBQSwECHgMU"
  141. "AAAACADojmFLPcugSwoBAAAUAgAACwAYAAAAAAAAAAAAoIEAAAAAY2xhc3Nlcy5kZXhVVAUAA/Ns"
  142. "+ll1eAsAAQQj5QIABIgTAABQSwUGAAAAAAEAAQBRAAAATwEAAAAA";
  143. class DexoptTestEnvTest : public testing::Test {
  144. };
  145. TEST_F(DexoptTestEnvTest, CheckSelinux) {
  146. ASSERT_EQ(1, is_selinux_enabled());
  147. // Crude cutout for virtual devices.
  148. #if !defined(__i386__) && !defined(__x86_64__)
  149. constexpr bool kIsX86 = false;
  150. #else
  151. constexpr bool kIsX86 = true;
  152. #endif
  153. ASSERT_TRUE(1 == security_getenforce() || kIsX86 || true /* b/119032200 */);
  154. }
  155. class DexoptTest : public testing::Test {
  156. protected:
  157. static constexpr bool kDebug = false;
  158. static constexpr uid_t kSystemUid = 1000;
  159. static constexpr uid_t kSystemGid = 1000;
  160. static constexpr int32_t kOSdkVersion = 25;
  161. static constexpr int32_t kAppDataFlags = FLAG_STORAGE_CE | FLAG_STORAGE_DE;
  162. static constexpr int32_t kTestUserId = 0;
  163. static constexpr uid_t kTestAppId = 19999;
  164. const gid_t kTestAppUid = multiuser_get_uid(kTestUserId, kTestAppId);
  165. const uid_t kTestAppGid = multiuser_get_shared_gid(kTestUserId, kTestAppId);
  166. InstalldNativeService* service_;
  167. std::unique_ptr<std::string> volume_uuid_;
  168. std::string package_name_;
  169. std::string apk_path_;
  170. std::string app_apk_dir_;
  171. std::string app_private_dir_ce_;
  172. std::string app_private_dir_de_;
  173. std::string se_info_;
  174. std::string app_oat_dir_;
  175. int64_t ce_data_inode_;
  176. std::string secondary_dex_ce_;
  177. std::string secondary_dex_ce_link_;
  178. std::string secondary_dex_de_;
  179. virtual void SetUp() {
  180. setenv("ANDROID_LOG_TAGS", "*:v", 1);
  181. android::base::InitLogging(nullptr);
  182. // Initialize the globals holding the file system main paths (/data/, /system/ etc..).
  183. // This is needed in order to compute the application and profile paths.
  184. ASSERT_TRUE(init_globals_from_data_and_root());
  185. // Initialize selinux log callbacks.
  186. // This ensures that selinux is up and running and re-directs the selinux messages
  187. // to logcat (in order to make it easier to investigate test results).
  188. ASSERT_TRUE(init_selinux());
  189. service_ = new InstalldNativeService();
  190. volume_uuid_ = nullptr;
  191. package_name_ = "com.installd.test.dexopt";
  192. se_info_ = "default";
  193. app_apk_dir_ = android_app_dir + package_name_;
  194. ASSERT_TRUE(create_mock_app());
  195. }
  196. virtual void TearDown() {
  197. if (!kDebug) {
  198. service_->destroyAppData(
  199. volume_uuid_, package_name_, kTestUserId, kAppDataFlags, ce_data_inode_);
  200. run_cmd("rm -rf " + app_apk_dir_);
  201. run_cmd("rm -rf " + app_private_dir_ce_);
  202. run_cmd("rm -rf " + app_private_dir_de_);
  203. }
  204. delete service_;
  205. }
  206. ::testing::AssertionResult create_mock_app() {
  207. // Create the oat dir.
  208. app_oat_dir_ = app_apk_dir_ + "/oat";
  209. // For debug mode, the directory might already exist. Avoid erroring out.
  210. if (mkdir(app_apk_dir_, kSystemUid, kSystemGid, 0755) != 0 && !kDebug) {
  211. return ::testing::AssertionFailure() << "Could not create app dir " << app_apk_dir_
  212. << " : " << strerror(errno);
  213. }
  214. binder::Status status = service_->createOatDir(app_oat_dir_, kRuntimeIsa);
  215. if (!status.isOk()) {
  216. return ::testing::AssertionFailure() << "Could not create oat dir: "
  217. << status.toString8().c_str();
  218. }
  219. // Copy the primary apk.
  220. apk_path_ = app_apk_dir_ + "/base.jar";
  221. std::string error_msg;
  222. if (!WriteBase64ToFile(kDexFile, apk_path_, kSystemUid, kSystemGid, 0644, &error_msg)) {
  223. return ::testing::AssertionFailure() << "Could not write base64 file to " << apk_path_
  224. << " : " << error_msg;
  225. }
  226. // Create the app user data.
  227. status = service_->createAppData(
  228. volume_uuid_,
  229. package_name_,
  230. kTestUserId,
  231. kAppDataFlags,
  232. kTestAppUid,
  233. se_info_,
  234. kOSdkVersion,
  235. &ce_data_inode_);
  236. if (!status.isOk()) {
  237. return ::testing::AssertionFailure() << "Could not create app data: "
  238. << status.toString8().c_str();
  239. }
  240. // Create a secondary dex file on CE storage
  241. const char* volume_uuid_cstr = volume_uuid_ == nullptr ? nullptr : volume_uuid_->c_str();
  242. app_private_dir_ce_ = create_data_user_ce_package_path(
  243. volume_uuid_cstr, kTestUserId, package_name_.c_str());
  244. secondary_dex_ce_ = app_private_dir_ce_ + "/secondary_ce.jar";
  245. if (!WriteBase64ToFile(kDexFile,
  246. secondary_dex_ce_,
  247. kTestAppUid,
  248. kTestAppGid,
  249. 0600,
  250. &error_msg)) {
  251. return ::testing::AssertionFailure() << "Could not write base64 file to "
  252. << secondary_dex_ce_ << " : " << error_msg;
  253. }
  254. std::string app_private_dir_ce_link = create_data_user_ce_package_path_as_user_link(
  255. volume_uuid_cstr, kTestUserId, package_name_.c_str());
  256. secondary_dex_ce_link_ = app_private_dir_ce_link + "/secondary_ce.jar";
  257. // Create a secondary dex file on DE storage.
  258. app_private_dir_de_ = create_data_user_de_package_path(
  259. volume_uuid_cstr, kTestUserId, package_name_.c_str());
  260. secondary_dex_de_ = app_private_dir_de_ + "/secondary_de.jar";
  261. if (!WriteBase64ToFile(kDexFile,
  262. secondary_dex_de_,
  263. kTestAppUid,
  264. kTestAppGid,
  265. 0600,
  266. &error_msg)) {
  267. return ::testing::AssertionFailure() << "Could not write base64 file to "
  268. << secondary_dex_de_ << " : " << error_msg;
  269. }
  270. // Fix app data uid.
  271. status = service_->fixupAppData(volume_uuid_, kTestUserId);
  272. if (!status.isOk()) {
  273. return ::testing::AssertionFailure() << "Could not fixup app data: "
  274. << status.toString8().c_str();
  275. }
  276. return ::testing::AssertionSuccess();
  277. }
  278. std::string GetSecondaryDexArtifact(const std::string& path, const std::string& type) {
  279. std::string::size_type end = path.rfind('.');
  280. std::string::size_type start = path.rfind('/', end);
  281. return path.substr(0, start) + "/oat/" + kRuntimeIsa + "/" +
  282. path.substr(start + 1, end - start) + type;
  283. }
  284. void CompileSecondaryDex(const std::string& path, int32_t dex_storage_flag,
  285. bool should_binder_call_succeed, bool should_dex_be_compiled = true,
  286. /*out */ binder::Status* binder_result = nullptr, int32_t uid = -1,
  287. const char* class_loader_context = nullptr) {
  288. if (uid == -1) {
  289. uid = kTestAppUid;
  290. }
  291. if (class_loader_context == nullptr) {
  292. class_loader_context = "&";
  293. }
  294. std::unique_ptr<std::string> package_name_ptr(new std::string(package_name_));
  295. int32_t dexopt_needed = 0; // does not matter;
  296. std::unique_ptr<std::string> out_path = nullptr; // does not matter
  297. int32_t dex_flags = DEXOPT_SECONDARY_DEX | dex_storage_flag;
  298. std::string compiler_filter = "speed-profile";
  299. std::unique_ptr<std::string> class_loader_context_ptr(
  300. new std::string(class_loader_context));
  301. std::unique_ptr<std::string> se_info_ptr(new std::string(se_info_));
  302. bool downgrade = false;
  303. int32_t target_sdk_version = 0; // default
  304. std::unique_ptr<std::string> profile_name_ptr = nullptr;
  305. std::unique_ptr<std::string> dm_path_ptr = nullptr;
  306. std::unique_ptr<std::string> compilation_reason_ptr = nullptr;
  307. binder::Status result = service_->dexopt(path,
  308. uid,
  309. package_name_ptr,
  310. kRuntimeIsa,
  311. dexopt_needed,
  312. out_path,
  313. dex_flags,
  314. compiler_filter,
  315. volume_uuid_,
  316. class_loader_context_ptr,
  317. se_info_ptr,
  318. downgrade,
  319. target_sdk_version,
  320. profile_name_ptr,
  321. dm_path_ptr,
  322. compilation_reason_ptr);
  323. ASSERT_EQ(should_binder_call_succeed, result.isOk()) << result.toString8().c_str();
  324. int expected_access = should_dex_be_compiled ? 0 : -1;
  325. std::string odex = GetSecondaryDexArtifact(path, "odex");
  326. std::string vdex = GetSecondaryDexArtifact(path, "vdex");
  327. std::string art = GetSecondaryDexArtifact(path, "art");
  328. ASSERT_EQ(expected_access, access(odex.c_str(), R_OK));
  329. ASSERT_EQ(expected_access, access(vdex.c_str(), R_OK));
  330. ASSERT_EQ(-1, access(art.c_str(), R_OK)); // empty profiles do not generate an image.
  331. if (binder_result != nullptr) {
  332. *binder_result = result;
  333. }
  334. }
  335. void reconcile_secondary_dex(const std::string& path, int32_t storage_flag,
  336. bool should_binder_call_succeed, bool should_dex_exist, bool should_dex_be_deleted,
  337. int32_t uid = -1, std::string* package_override = nullptr) {
  338. if (uid == -1) {
  339. uid = kTestAppUid;
  340. }
  341. std::vector<std::string> isas;
  342. isas.push_back(kRuntimeIsa);
  343. bool out_secondary_dex_exists = false;
  344. binder::Status result = service_->reconcileSecondaryDexFile(
  345. path,
  346. package_override == nullptr ? package_name_ : *package_override,
  347. uid,
  348. isas,
  349. volume_uuid_,
  350. storage_flag,
  351. &out_secondary_dex_exists);
  352. ASSERT_EQ(should_binder_call_succeed, result.isOk()) << result.toString8().c_str();
  353. ASSERT_EQ(should_dex_exist, out_secondary_dex_exists);
  354. int expected_access = should_dex_be_deleted ? -1 : 0;
  355. std::string odex = GetSecondaryDexArtifact(path, "odex");
  356. std::string vdex = GetSecondaryDexArtifact(path, "vdex");
  357. std::string art = GetSecondaryDexArtifact(path, "art");
  358. ASSERT_EQ(expected_access, access(odex.c_str(), F_OK));
  359. ASSERT_EQ(expected_access, access(vdex.c_str(), F_OK));
  360. ASSERT_EQ(-1, access(art.c_str(), R_OK)); // empty profiles do not generate an image.
  361. }
  362. void CheckFileAccess(const std::string& file, uid_t uid, gid_t gid, mode_t mode) {
  363. struct stat st;
  364. ASSERT_EQ(0, stat(file.c_str(), &st));
  365. ASSERT_EQ(uid, st.st_uid);
  366. ASSERT_EQ(gid, st.st_gid);
  367. ASSERT_EQ(mode, st.st_mode);
  368. }
  369. void CompilePrimaryDexOk(std::string compiler_filter,
  370. int32_t dex_flags,
  371. const char* oat_dir,
  372. int32_t uid,
  373. int32_t dexopt_needed,
  374. binder::Status* binder_result = nullptr,
  375. const char* dm_path = nullptr,
  376. bool downgrade = false) {
  377. CompilePrimaryDex(compiler_filter,
  378. dex_flags,
  379. oat_dir,
  380. uid,
  381. dexopt_needed,
  382. dm_path,
  383. downgrade,
  384. true,
  385. binder_result);
  386. }
  387. void CompilePrimaryDexFail(std::string compiler_filter,
  388. int32_t dex_flags,
  389. const char* oat_dir,
  390. int32_t uid,
  391. int32_t dexopt_needed,
  392. binder::Status* binder_result = nullptr,
  393. const char* dm_path = nullptr,
  394. bool downgrade = false) {
  395. CompilePrimaryDex(compiler_filter,
  396. dex_flags,
  397. oat_dir,
  398. uid,
  399. dexopt_needed,
  400. dm_path,
  401. downgrade,
  402. false,
  403. binder_result);
  404. }
  405. void CompilePrimaryDex(std::string compiler_filter,
  406. int32_t dex_flags,
  407. const char* oat_dir,
  408. int32_t uid,
  409. int32_t dexopt_needed,
  410. const char* dm_path,
  411. bool downgrade,
  412. bool should_binder_call_succeed,
  413. /*out */ binder::Status* binder_result) {
  414. std::unique_ptr<std::string> package_name_ptr(new std::string(package_name_));
  415. std::unique_ptr<std::string> out_path(
  416. oat_dir == nullptr ? nullptr : new std::string(oat_dir));
  417. std::unique_ptr<std::string> class_loader_context_ptr(new std::string("&"));
  418. std::unique_ptr<std::string> se_info_ptr(new std::string(se_info_));
  419. int32_t target_sdk_version = 0; // default
  420. std::unique_ptr<std::string> profile_name_ptr(new std::string("primary.prof"));
  421. std::unique_ptr<std::string> dm_path_ptr = nullptr;
  422. if (dm_path != nullptr) {
  423. dm_path_ptr.reset(new std::string(dm_path));
  424. }
  425. std::unique_ptr<std::string> compilation_reason_ptr(new std::string("test-reason"));
  426. bool prof_result;
  427. ASSERT_BINDER_SUCCESS(service_->prepareAppProfile(
  428. package_name_, kTestUserId, kTestAppId, *profile_name_ptr, apk_path_,
  429. /*dex_metadata*/ nullptr, &prof_result));
  430. ASSERT_TRUE(prof_result);
  431. binder::Status result = service_->dexopt(apk_path_,
  432. uid,
  433. package_name_ptr,
  434. kRuntimeIsa,
  435. dexopt_needed,
  436. out_path,
  437. dex_flags,
  438. compiler_filter,
  439. volume_uuid_,
  440. class_loader_context_ptr,
  441. se_info_ptr,
  442. downgrade,
  443. target_sdk_version,
  444. profile_name_ptr,
  445. dm_path_ptr,
  446. compilation_reason_ptr);
  447. ASSERT_EQ(should_binder_call_succeed, result.isOk()) << result.toString8().c_str();
  448. if (!should_binder_call_succeed) {
  449. if (binder_result != nullptr) {
  450. *binder_result = result;
  451. }
  452. return;
  453. }
  454. // Check the access to the compiler output.
  455. // - speed-profile artifacts are not world-wide readable.
  456. // - files are owned by the system uid.
  457. std::string odex = GetPrimaryDexArtifact(oat_dir, apk_path_, "odex");
  458. std::string vdex = GetPrimaryDexArtifact(oat_dir, apk_path_, "vdex");
  459. std::string art = GetPrimaryDexArtifact(oat_dir, apk_path_, "art");
  460. bool is_public = (dex_flags & DEXOPT_PUBLIC) != 0;
  461. mode_t mode = S_IFREG | (is_public ? 0644 : 0640);
  462. CheckFileAccess(odex, kSystemUid, uid, mode);
  463. CheckFileAccess(vdex, kSystemUid, uid, mode);
  464. if (compiler_filter == "speed-profile") {
  465. CheckFileAccess(art, kSystemUid, uid, mode);
  466. }
  467. if (binder_result != nullptr) {
  468. *binder_result = result;
  469. }
  470. }
  471. std::string GetPrimaryDexArtifact(const char* oat_dir,
  472. const std::string& dex_path,
  473. const std::string& type) {
  474. if (oat_dir == nullptr) {
  475. std::string path = dex_path;
  476. for (auto it = path.begin() + 1; it < path.end(); ++it) {
  477. if (*it == '/') {
  478. *it = '@';
  479. }
  480. }
  481. return android_data_dir + DALVIK_CACHE + '/' + kRuntimeIsa + "/" + path
  482. + "@classes.dex";
  483. } else {
  484. std::string::size_type name_end = dex_path.rfind('.');
  485. std::string::size_type name_start = dex_path.rfind('/');
  486. return std::string(oat_dir) + "/" + kRuntimeIsa + "/" +
  487. dex_path.substr(name_start + 1, name_end - name_start) + type;
  488. }
  489. }
  490. };
  491. TEST_F(DexoptTest, DexoptSecondaryCe) {
  492. LOG(INFO) << "DexoptSecondaryCe";
  493. CompileSecondaryDex(secondary_dex_ce_, DEXOPT_STORAGE_CE,
  494. /*binder_ok*/ true, /*compile_ok*/ true);
  495. }
  496. TEST_F(DexoptTest, DexoptSecondaryCeLink) {
  497. LOG(INFO) << "DexoptSecondaryCeLink";
  498. CompileSecondaryDex(secondary_dex_ce_link_, DEXOPT_STORAGE_CE,
  499. /*binder_ok*/ true, /*compile_ok*/ true);
  500. }
  501. TEST_F(DexoptTest, DexoptSecondaryCeWithContext) {
  502. LOG(INFO) << "DexoptSecondaryCeWithContext";
  503. std::string class_loader_context = "PCL[" + secondary_dex_ce_ + "]";
  504. CompileSecondaryDex(secondary_dex_ce_, DEXOPT_STORAGE_CE,
  505. /*binder_ok*/ true, /*compile_ok*/ true, nullptr, -1, class_loader_context.c_str());
  506. }
  507. TEST_F(DexoptTest, DexoptSecondaryDe) {
  508. LOG(INFO) << "DexoptSecondaryDe";
  509. CompileSecondaryDex(secondary_dex_de_, DEXOPT_STORAGE_DE,
  510. /*binder_ok*/ true, /*compile_ok*/ true);
  511. }
  512. TEST_F(DexoptTest, DexoptSecondaryDeWithContext) {
  513. LOG(INFO) << "DexoptSecondaryDeWithContext";
  514. std::string class_loader_context = "PCL[" + secondary_dex_de_ + "]";
  515. CompileSecondaryDex(secondary_dex_de_, DEXOPT_STORAGE_DE,
  516. /*binder_ok*/ true, /*compile_ok*/ true, nullptr, -1, class_loader_context.c_str());
  517. }
  518. TEST_F(DexoptTest, DexoptSecondaryDoesNotExist) {
  519. LOG(INFO) << "DexoptSecondaryDoesNotExist";
  520. // If the file validates but does not exist we do not treat it as an error.
  521. binder::Status status;
  522. CompileSecondaryDex(secondary_dex_ce_ + "not.there", DEXOPT_STORAGE_CE,
  523. /*binder_ok*/ true, /*compile_ok*/ false, &status);
  524. EXPECT_STREQ(status.toString8().c_str(), "No error");
  525. }
  526. TEST_F(DexoptTest, DexoptSecondaryStorageValidationError) {
  527. LOG(INFO) << "DexoptSecondaryStorageValidationError";
  528. binder::Status status;
  529. CompileSecondaryDex(secondary_dex_ce_, DEXOPT_STORAGE_DE,
  530. /*binder_ok*/ false, /*compile_ok*/ false, &status);
  531. EXPECT_STREQ(status.toString8().c_str(),
  532. "Status(-8, EX_SERVICE_SPECIFIC): '-1: Dexoptanalyzer path validation failed'");
  533. }
  534. TEST_F(DexoptTest, DexoptSecondaryAppOwnershipValidationError) {
  535. LOG(INFO) << "DexoptSecondaryAppOwnershipValidationError";
  536. binder::Status status;
  537. CompileSecondaryDex("/data/data/random.app/secondary.jar", DEXOPT_STORAGE_CE,
  538. /*binder_ok*/ false, /*compile_ok*/ false, &status);
  539. EXPECT_STREQ(status.toString8().c_str(),
  540. "Status(-8, EX_SERVICE_SPECIFIC): '-1: Dexoptanalyzer path validation failed'");
  541. }
  542. TEST_F(DexoptTest, DexoptSecondaryAcessViaDifferentUidError) {
  543. LOG(INFO) << "DexoptSecondaryAcessViaDifferentUidError";
  544. binder::Status status;
  545. CompileSecondaryDex(secondary_dex_ce_, DEXOPT_STORAGE_CE,
  546. /*binder_ok*/ false, /*compile_ok*/ false, &status, kSystemUid);
  547. EXPECT_STREQ(status.toString8().c_str(),
  548. "Status(-8, EX_SERVICE_SPECIFIC): '-1: Dexoptanalyzer open zip failed'");
  549. }
  550. TEST_F(DexoptTest, DexoptPrimaryPublic) {
  551. LOG(INFO) << "DexoptPrimaryPublic";
  552. CompilePrimaryDexOk("verify",
  553. DEXOPT_BOOTCOMPLETE | DEXOPT_PUBLIC,
  554. app_oat_dir_.c_str(),
  555. kTestAppGid,
  556. DEX2OAT_FROM_SCRATCH);
  557. }
  558. TEST_F(DexoptTest, DexoptPrimaryFailedInvalidFilter) {
  559. LOG(INFO) << "DexoptPrimaryFailedInvalidFilter";
  560. binder::Status status;
  561. CompilePrimaryDexFail("awesome-filter",
  562. DEXOPT_IDLE_BACKGROUND_JOB | DEXOPT_PUBLIC,
  563. app_oat_dir_.c_str(),
  564. kTestAppGid,
  565. DEX2OAT_FROM_SCRATCH,
  566. &status);
  567. EXPECT_STREQ(status.toString8().c_str(),
  568. "Status(-8, EX_SERVICE_SPECIFIC): \'256: Dex2oat invocation for "
  569. "/data/app/com.installd.test.dexopt/base.jar failed: unspecified dex2oat error'");
  570. }
  571. TEST_F(DexoptTest, DexoptPrimaryProfileNonPublic) {
  572. LOG(INFO) << "DexoptPrimaryProfileNonPublic";
  573. CompilePrimaryDexOk("speed-profile",
  574. DEXOPT_BOOTCOMPLETE | DEXOPT_PROFILE_GUIDED | DEXOPT_GENERATE_APP_IMAGE,
  575. app_oat_dir_.c_str(),
  576. kTestAppGid,
  577. DEX2OAT_FROM_SCRATCH);
  578. }
  579. TEST_F(DexoptTest, DexoptPrimaryProfilePublic) {
  580. LOG(INFO) << "DexoptPrimaryProfilePublic";
  581. CompilePrimaryDexOk("speed-profile",
  582. DEXOPT_BOOTCOMPLETE | DEXOPT_PROFILE_GUIDED | DEXOPT_PUBLIC |
  583. DEXOPT_GENERATE_APP_IMAGE,
  584. app_oat_dir_.c_str(),
  585. kTestAppGid,
  586. DEX2OAT_FROM_SCRATCH);
  587. }
  588. TEST_F(DexoptTest, DexoptPrimaryBackgroundOk) {
  589. LOG(INFO) << "DexoptPrimaryBackgroundOk";
  590. CompilePrimaryDexOk("speed-profile",
  591. DEXOPT_IDLE_BACKGROUND_JOB | DEXOPT_PROFILE_GUIDED |
  592. DEXOPT_GENERATE_APP_IMAGE,
  593. app_oat_dir_.c_str(),
  594. kTestAppGid,
  595. DEX2OAT_FROM_SCRATCH);
  596. }
  597. TEST_F(DexoptTest, ResolveStartupConstStrings) {
  598. LOG(INFO) << "DexoptDex2oatResolveStartupStrings";
  599. const std::string property = "persist.device_config.runtime.dex2oat_resolve_startup_strings";
  600. const std::string previous_value = android::base::GetProperty(property, "");
  601. auto restore_property = android::base::make_scope_guard([=]() {
  602. android::base::SetProperty(property, previous_value);
  603. });
  604. std::string odex = GetPrimaryDexArtifact(app_oat_dir_.c_str(), apk_path_, "odex");
  605. // Disable the property to start.
  606. bool found_disable = false;
  607. ASSERT_TRUE(android::base::SetProperty(property, "false")) << property;
  608. CompilePrimaryDexOk("speed-profile",
  609. DEXOPT_IDLE_BACKGROUND_JOB | DEXOPT_PROFILE_GUIDED |
  610. DEXOPT_GENERATE_APP_IMAGE,
  611. app_oat_dir_.c_str(),
  612. kTestAppGid,
  613. DEX2OAT_FROM_SCRATCH);
  614. run_cmd_and_process_output(
  615. "oatdump --header-only --oat-file=" + odex,
  616. [&](const std::string& line) {
  617. if (line.find("--resolve-startup-const-strings=false") != std::string::npos) {
  618. found_disable = true;
  619. }
  620. });
  621. EXPECT_TRUE(found_disable);
  622. // Enable the property and inspect that .art artifact is larger.
  623. bool found_enable = false;
  624. ASSERT_TRUE(android::base::SetProperty(property, "true")) << property;
  625. CompilePrimaryDexOk("speed-profile",
  626. DEXOPT_IDLE_BACKGROUND_JOB | DEXOPT_PROFILE_GUIDED |
  627. DEXOPT_GENERATE_APP_IMAGE,
  628. app_oat_dir_.c_str(),
  629. kTestAppGid,
  630. DEX2OAT_FROM_SCRATCH);
  631. run_cmd_and_process_output(
  632. "oatdump --header-only --oat-file=" + odex,
  633. [&](const std::string& line) {
  634. if (line.find("--resolve-startup-const-strings=true") != std::string::npos) {
  635. found_enable = true;
  636. }
  637. });
  638. EXPECT_TRUE(found_enable);
  639. }
  640. class PrimaryDexReCompilationTest : public DexoptTest {
  641. public:
  642. virtual void SetUp() {
  643. DexoptTest::SetUp();
  644. CompilePrimaryDexOk("verify",
  645. DEXOPT_BOOTCOMPLETE | DEXOPT_PUBLIC,
  646. app_oat_dir_.c_str(),
  647. kTestAppGid,
  648. DEX2OAT_FROM_SCRATCH);
  649. std::string odex = GetSecondaryDexArtifact(apk_path_, "odex");
  650. std::string vdex = GetSecondaryDexArtifact(apk_path_, "vdex");
  651. first_compilation_odex_fd_.reset(open(odex.c_str(), O_RDONLY));
  652. first_compilation_vdex_fd_.reset(open(vdex.c_str(), O_RDONLY));
  653. }
  654. virtual void TearDown() {
  655. first_compilation_odex_fd_.reset(-1);
  656. first_compilation_vdex_fd_.reset(-1);
  657. DexoptTest::TearDown();
  658. }
  659. protected:
  660. unique_fd first_compilation_odex_fd_;
  661. unique_fd first_compilation_vdex_fd_;
  662. };
  663. TEST_F(PrimaryDexReCompilationTest, DexoptPrimaryUpdateInPlaceVdex) {
  664. LOG(INFO) << "DexoptPrimaryUpdateInPlaceVdex";
  665. CompilePrimaryDexOk("verify",
  666. DEXOPT_IDLE_BACKGROUND_JOB | DEXOPT_PUBLIC,
  667. app_oat_dir_.c_str(),
  668. kTestAppGid,
  669. DEX2OAT_FOR_BOOT_IMAGE);
  670. }
  671. class ReconcileTest : public DexoptTest {
  672. virtual void SetUp() {
  673. DexoptTest::SetUp();
  674. CompileSecondaryDex(secondary_dex_ce_, DEXOPT_STORAGE_CE,
  675. /*binder_ok*/ true, /*compile_ok*/ true);
  676. CompileSecondaryDex(secondary_dex_de_, DEXOPT_STORAGE_DE,
  677. /*binder_ok*/ true, /*compile_ok*/ true);
  678. }
  679. };
  680. TEST_F(ReconcileTest, ReconcileSecondaryCeExists) {
  681. LOG(INFO) << "ReconcileSecondaryCeExists";
  682. reconcile_secondary_dex(secondary_dex_ce_, FLAG_STORAGE_CE,
  683. /*binder_ok*/ true, /*dex_ok */ true, /*odex_deleted*/ false);
  684. }
  685. TEST_F(ReconcileTest, ReconcileSecondaryCeLinkExists) {
  686. LOG(INFO) << "ReconcileSecondaryCeLinkExists";
  687. reconcile_secondary_dex(secondary_dex_ce_link_, FLAG_STORAGE_CE,
  688. /*binder_ok*/ true, /*dex_ok */ true, /*odex_deleted*/ false);
  689. }
  690. TEST_F(ReconcileTest, ReconcileSecondaryDeExists) {
  691. LOG(INFO) << "ReconcileSecondaryDeExists";
  692. reconcile_secondary_dex(secondary_dex_de_, FLAG_STORAGE_DE,
  693. /*binder_ok*/ true, /*dex_ok */ true, /*odex_deleted*/ false);
  694. }
  695. TEST_F(ReconcileTest, ReconcileSecondaryDeDoesNotExist) {
  696. LOG(INFO) << "ReconcileSecondaryDeDoesNotExist";
  697. run_cmd("rm -rf " + secondary_dex_de_);
  698. reconcile_secondary_dex(secondary_dex_de_, FLAG_STORAGE_DE,
  699. /*binder_ok*/ true, /*dex_ok */ false, /*odex_deleted*/ true);
  700. }
  701. TEST_F(ReconcileTest, ReconcileSecondaryStorageValidationError) {
  702. // Validation errors will not clean the odex/vdex/art files but will mark
  703. // the file as non existent so that the PM knows it should purge it from its
  704. // records.
  705. LOG(INFO) << "ReconcileSecondaryStorageValidationError";
  706. reconcile_secondary_dex(secondary_dex_ce_, FLAG_STORAGE_DE,
  707. /*binder_ok*/ true, /*dex_ok */ false, /*odex_deleted*/ false);
  708. }
  709. TEST_F(ReconcileTest, ReconcileSecondaryAppOwnershipValidationError) {
  710. LOG(INFO) << "ReconcileSecondaryAppOwnershipValidationError";
  711. // Attempt to reconcile the dex files of the test app from a different app.
  712. std::string another_app = "another.app";
  713. reconcile_secondary_dex(secondary_dex_ce_, FLAG_STORAGE_CE,
  714. /*binder_ok*/ true, /*dex_ok */ false, /*odex_deleted*/ false, kSystemUid, &another_app);
  715. }
  716. TEST_F(ReconcileTest, ReconcileSecondaryAcessViaDifferentUidError) {
  717. LOG(INFO) << "ReconcileSecondaryAcessViaDifferentUidError";
  718. reconcile_secondary_dex(secondary_dex_ce_, FLAG_STORAGE_CE,
  719. /*binder_ok*/ true, /*dex_ok */ false, /*odex_deleted*/ false, kSystemUid);
  720. }
  721. class ProfileTest : public DexoptTest {
  722. protected:
  723. std::string cur_profile_;
  724. std::string ref_profile_;
  725. std::string snap_profile_;
  726. static constexpr const char* kPrimaryProfile = "primary.prof";
  727. virtual void SetUp() {
  728. DexoptTest::SetUp();
  729. cur_profile_ = create_current_profile_path(
  730. kTestUserId, package_name_, kPrimaryProfile, /*is_secondary_dex*/ false);
  731. ref_profile_ = create_reference_profile_path(package_name_, kPrimaryProfile,
  732. /*is_secondary_dex*/ false);
  733. snap_profile_ = create_snapshot_profile_path(package_name_, kPrimaryProfile);
  734. }
  735. void SetupProfile(const std::string& path, uid_t uid, gid_t gid, mode_t mode,
  736. int32_t num_dex) {
  737. run_cmd("profman --generate-test-profile-seed=" + std::to_string(num_dex) +
  738. " --generate-test-profile-num-dex=" + std::to_string(num_dex) +
  739. " --generate-test-profile=" + path);
  740. ::chmod(path.c_str(), mode);
  741. ::chown(path.c_str(), uid, gid);
  742. }
  743. void SetupProfiles(bool setup_ref) {
  744. SetupProfile(cur_profile_, kTestAppUid, kTestAppGid, 0600, 1);
  745. if (setup_ref) {
  746. SetupProfile(ref_profile_, kTestAppUid, kTestAppGid, 0600, 2);
  747. }
  748. }
  749. void createProfileSnapshot(int32_t appid, const std::string& package_name,
  750. bool expected_result) {
  751. bool result;
  752. ASSERT_BINDER_SUCCESS(service_->createProfileSnapshot(
  753. appid, package_name, kPrimaryProfile, apk_path_, &result));
  754. ASSERT_EQ(expected_result, result);
  755. if (!expected_result) {
  756. // Do not check the files if we expect to fail.
  757. return;
  758. }
  759. // Check that the snapshot was created witht he expected acess flags.
  760. CheckFileAccess(snap_profile_, kSystemUid, kSystemGid, 0600 | S_IFREG);
  761. // The snapshot should be equivalent to the merge of profiles.
  762. std::string expected_profile_content = snap_profile_ + ".expected";
  763. run_cmd("rm -f " + expected_profile_content);
  764. run_cmd("touch " + expected_profile_content);
  765. run_cmd("profman --profile-file=" + cur_profile_ +
  766. " --profile-file=" + ref_profile_ +
  767. " --reference-profile-file=" + expected_profile_content +
  768. " --apk=" + apk_path_);
  769. ASSERT_TRUE(AreFilesEqual(expected_profile_content, snap_profile_));
  770. pid_t pid = fork();
  771. if (pid == 0) {
  772. /* child */
  773. TransitionToSystemServer();
  774. // System server should be able to open the the spanshot.
  775. unique_fd fd(open(snap_profile_.c_str(), O_RDONLY));
  776. ASSERT_TRUE(fd > -1) << "Failed to open profile as kSystemUid: " << strerror(errno);
  777. _exit(0);
  778. }
  779. /* parent */
  780. ASSERT_TRUE(WIFEXITED(wait_child(pid)));
  781. }
  782. void mergePackageProfiles(const std::string& package_name,
  783. const std::string& code_path,
  784. bool expected_result) {
  785. bool result;
  786. ASSERT_BINDER_SUCCESS(service_->mergeProfiles(
  787. kTestAppUid, package_name, code_path, &result));
  788. ASSERT_EQ(expected_result, result);
  789. if (!expected_result) {
  790. // Do not check the files if we expect to fail.
  791. return;
  792. }
  793. // Check that the snapshot was created witht he expected acess flags.
  794. CheckFileAccess(ref_profile_, kTestAppUid, kTestAppUid, 0600 | S_IFREG);
  795. // The snapshot should be equivalent to the merge of profiles.
  796. std::string ref_profile_content = ref_profile_ + ".expected";
  797. run_cmd("rm -f " + ref_profile_content);
  798. run_cmd("touch " + ref_profile_content);
  799. run_cmd("profman --profile-file=" + cur_profile_ +
  800. " --profile-file=" + ref_profile_ +
  801. " --reference-profile-file=" + ref_profile_content);
  802. ASSERT_TRUE(AreFilesEqual(ref_profile_content, ref_profile_));
  803. }
  804. // TODO(calin): add dex metadata tests once the ART change is merged.
  805. void preparePackageProfile(const std::string& package_name, const std::string& profile_name,
  806. bool expected_result) {
  807. bool result;
  808. ASSERT_BINDER_SUCCESS(service_->prepareAppProfile(
  809. package_name, kTestUserId, kTestAppId, profile_name, apk_path_,
  810. /*dex_metadata*/ nullptr, &result));
  811. ASSERT_EQ(expected_result, result);
  812. if (!expected_result) {
  813. // Do not check the files if we expect to fail.
  814. return;
  815. }
  816. std::string code_path_cur_prof = create_current_profile_path(
  817. kTestUserId, package_name, profile_name, /*is_secondary_dex*/ false);
  818. std::string code_path_ref_profile = create_reference_profile_path(package_name,
  819. profile_name, /*is_secondary_dex*/ false);
  820. // Check that we created the current profile.
  821. CheckFileAccess(code_path_cur_prof, kTestAppUid, kTestAppUid, 0600 | S_IFREG);
  822. // Without dex metadata we don't generate a reference profile.
  823. ASSERT_EQ(-1, access(code_path_ref_profile.c_str(), R_OK));
  824. }
  825. protected:
  826. void TransitionToSystemServer() {
  827. ASSERT_TRUE(DropCapabilities(kSystemUid, kSystemGid));
  828. int32_t res = selinux_android_setcon("u:r:system_server:s0");
  829. ASSERT_EQ(0, res) << "Failed to setcon " << strerror(errno);
  830. }
  831. bool AreFilesEqual(const std::string& file1, const std::string& file2) {
  832. std::vector<uint8_t> content1;
  833. std::vector<uint8_t> content2;
  834. if (!ReadAll(file1, &content1)) return false;
  835. if (!ReadAll(file2, &content2)) return false;
  836. return content1 == content2;
  837. }
  838. bool ReadAll(const std::string& file, std::vector<uint8_t>* content) {
  839. unique_fd fd(open(file.c_str(), O_RDONLY));
  840. if (fd < 0) {
  841. PLOG(ERROR) << "Failed to open " << file;
  842. return false;
  843. }
  844. struct stat st;
  845. if (fstat(fd, &st) != 0) {
  846. PLOG(ERROR) << "Failed to stat " << file;
  847. return false;
  848. }
  849. content->resize(st.st_size);
  850. bool result = ReadFully(fd, content->data(), content->size());
  851. if (!result) {
  852. PLOG(ERROR) << "Failed to read " << file;
  853. }
  854. return result;
  855. }
  856. };
  857. TEST_F(ProfileTest, ProfileSnapshotOk) {
  858. LOG(INFO) << "ProfileSnapshotOk";
  859. SetupProfiles(/*setup_ref*/ true);
  860. createProfileSnapshot(kTestAppId, package_name_, /*expected_result*/ true);
  861. }
  862. // The reference profile is created on the fly. We need to be able to
  863. // snapshot without one.
  864. TEST_F(ProfileTest, ProfileSnapshotOkNoReference) {
  865. LOG(INFO) << "ProfileSnapshotOkNoReference";
  866. SetupProfiles(/*setup_ref*/ false);
  867. createProfileSnapshot(kTestAppId, package_name_, /*expected_result*/ true);
  868. }
  869. TEST_F(ProfileTest, ProfileSnapshotFailWrongPackage) {
  870. LOG(INFO) << "ProfileSnapshotFailWrongPackage";
  871. SetupProfiles(/*setup_ref*/ true);
  872. createProfileSnapshot(kTestAppId, "not.there", /*expected_result*/ false);
  873. }
  874. TEST_F(ProfileTest, ProfileSnapshotDestroySnapshot) {
  875. LOG(INFO) << "ProfileSnapshotDestroySnapshot";
  876. SetupProfiles(/*setup_ref*/ true);
  877. createProfileSnapshot(kTestAppId, package_name_, /*expected_result*/ true);
  878. ASSERT_BINDER_SUCCESS(service_->destroyProfileSnapshot(package_name_, kPrimaryProfile));
  879. struct stat st;
  880. ASSERT_EQ(-1, stat(snap_profile_.c_str(), &st));
  881. ASSERT_EQ(ENOENT, errno);
  882. }
  883. TEST_F(ProfileTest, ProfileMergeOk) {
  884. LOG(INFO) << "ProfileMergeOk";
  885. SetupProfiles(/*setup_ref*/ true);
  886. mergePackageProfiles(package_name_, "primary.prof", /*expected_result*/ true);
  887. }
  888. // The reference profile is created on the fly. We need to be able to
  889. // merge without one.
  890. TEST_F(ProfileTest, ProfileMergeOkNoReference) {
  891. LOG(INFO) << "ProfileMergeOkNoReference";
  892. SetupProfiles(/*setup_ref*/ false);
  893. mergePackageProfiles(package_name_, "primary.prof", /*expected_result*/ true);
  894. }
  895. TEST_F(ProfileTest, ProfileMergeFailWrongPackage) {
  896. LOG(INFO) << "ProfileMergeFailWrongPackage";
  897. SetupProfiles(/*setup_ref*/ true);
  898. mergePackageProfiles("not.there", "primary.prof", /*expected_result*/ false);
  899. }
  900. TEST_F(ProfileTest, ProfileDirOk) {
  901. LOG(INFO) << "ProfileDirOk";
  902. std::string cur_profile_dir = create_primary_current_profile_package_dir_path(
  903. kTestUserId, package_name_);
  904. std::string cur_profile_file = create_current_profile_path(kTestUserId, package_name_,
  905. kPrimaryProfile, /*is_secondary_dex*/false);
  906. std::string ref_profile_dir = create_primary_reference_profile_package_dir_path(package_name_);
  907. CheckFileAccess(cur_profile_dir, kTestAppUid, kTestAppUid, 0700 | S_IFDIR);
  908. CheckFileAccess(ref_profile_dir, kSystemUid, kTestAppGid, 0770 | S_IFDIR);
  909. }
  910. // Verify that the profile directories are fixed up during an upgrade.
  911. // (The reference profile directory is prepared lazily).
  912. TEST_F(ProfileTest, ProfileDirOkAfterFixup) {
  913. LOG(INFO) << "ProfileDirOkAfterFixup";
  914. std::string cur_profile_dir = create_primary_current_profile_package_dir_path(
  915. kTestUserId, package_name_);
  916. std::string cur_profile_file = create_current_profile_path(kTestUserId, package_name_,
  917. kPrimaryProfile, /*is_secondary_dex*/false);
  918. std::string ref_profile_dir = create_primary_reference_profile_package_dir_path(package_name_);
  919. // Simulate a pre-P setup by changing the owner to kTestAppGid and permissions to 0700.
  920. ASSERT_EQ(0, chown(ref_profile_dir.c_str(), kTestAppGid, kTestAppGid));
  921. ASSERT_EQ(0, chmod(ref_profile_dir.c_str(), 0700));
  922. // Run createAppData again which will offer to fix-up the profile directories.
  923. ASSERT_BINDER_SUCCESS(service_->createAppData(
  924. volume_uuid_,
  925. package_name_,
  926. kTestUserId,
  927. kAppDataFlags,
  928. kTestAppUid,
  929. se_info_,
  930. kOSdkVersion,
  931. &ce_data_inode_));
  932. // Check the file access.
  933. CheckFileAccess(cur_profile_dir, kTestAppUid, kTestAppUid, 0700 | S_IFDIR);
  934. CheckFileAccess(ref_profile_dir, kSystemUid, kTestAppGid, 0770 | S_IFDIR);
  935. }
  936. TEST_F(ProfileTest, ProfilePrepareOk) {
  937. LOG(INFO) << "ProfilePrepareOk";
  938. preparePackageProfile(package_name_, "split.prof", /*expected_result*/ true);
  939. }
  940. TEST_F(ProfileTest, ProfilePrepareFailInvalidPackage) {
  941. LOG(INFO) << "ProfilePrepareFailInvalidPackage";
  942. preparePackageProfile("not.there.package", "split.prof", /*expected_result*/ false);
  943. }
  944. TEST_F(ProfileTest, ProfilePrepareFailProfileChangedUid) {
  945. LOG(INFO) << "ProfilePrepareFailProfileChangedUid";
  946. SetupProfiles(/*setup_ref*/ false);
  947. // Change the uid on the profile to trigger a failure.
  948. ::chown(cur_profile_.c_str(), kTestAppUid + 1, kTestAppGid + 1);
  949. preparePackageProfile(package_name_, "primary.prof", /*expected_result*/ false);
  950. }
  951. class BootProfileTest : public ProfileTest {
  952. public:
  953. virtual void setup() {
  954. ProfileTest::SetUp();
  955. intial_android_profiles_dir = android_profiles_dir;
  956. }
  957. virtual void TearDown() {
  958. android_profiles_dir = intial_android_profiles_dir;
  959. ProfileTest::TearDown();
  960. }
  961. void UpdateAndroidProfilesDir(const std::string& profile_dir) {
  962. android_profiles_dir = profile_dir;
  963. // We need to create the reference profile directory in the new profile dir.
  964. run_cmd("mkdir -p " + profile_dir + "/ref");
  965. }
  966. void createBootImageProfileSnapshot(const std::string& classpath, bool expected_result) {
  967. bool result;
  968. ASSERT_BINDER_SUCCESS(service_->createProfileSnapshot(
  969. -1, "android", "android.prof", classpath, &result));
  970. ASSERT_EQ(expected_result, result);
  971. if (!expected_result) {
  972. // Do not check the files if we expect to fail.
  973. return;
  974. }
  975. // Check that the snapshot was created with he expected access flags.
  976. const std::string boot_profile = create_snapshot_profile_path("android", "android.prof");
  977. CheckFileAccess(boot_profile, kSystemUid, kSystemGid, 0600 | S_IFREG);
  978. pid_t pid = fork();
  979. if (pid == 0) {
  980. /* child */
  981. TransitionToSystemServer();
  982. // System server should be able to open the snapshot.
  983. unique_fd fd(open(boot_profile.c_str(), O_RDONLY));
  984. ASSERT_TRUE(fd > -1) << "Failed to open profile as kSystemUid: " << strerror(errno);
  985. _exit(0);
  986. }
  987. /* parent */
  988. ASSERT_TRUE(WIFEXITED(wait_child(pid)));
  989. }
  990. protected:
  991. std::string intial_android_profiles_dir;
  992. };
  993. TEST_F(BootProfileTest, BootProfileSnapshotOk) {
  994. LOG(INFO) << "BootProfileSnapshotOk";
  995. char* boot_classpath = getenv("BOOTCLASSPATH");
  996. ASSERT_TRUE(boot_classpath != nullptr);
  997. createBootImageProfileSnapshot(boot_classpath, /*expected_result*/ true);
  998. }
  999. TEST_F(BootProfileTest, BootProfileSnapshotFailEmptyClasspath) {
  1000. LOG(INFO) << "BootProfileSnapshotFailEmptyClasspath";
  1001. createBootImageProfileSnapshot(/*boot_classpath*/ "", /*expected_result*/ false);
  1002. }
  1003. TEST_F(BootProfileTest, BootProfileSnapshotOkNoProfiles) {
  1004. LOG(INFO) << "BootProfileSnapshotOkNoProfiles";
  1005. char* boot_classpath = getenv("BOOTCLASSPATH");
  1006. ASSERT_TRUE(boot_classpath != nullptr);
  1007. // The app_apk_dir has no profiles. So we shouldn't be able to merge anything.
  1008. // Still, this is not a failure case.
  1009. UpdateAndroidProfilesDir(app_apk_dir_);
  1010. createBootImageProfileSnapshot(boot_classpath, /*expected_result*/ true);
  1011. }
  1012. // Verify that profile collection.
  1013. TEST_F(BootProfileTest, CollectProfiles) {
  1014. LOG(INFO) << "CollectProfiles";
  1015. // Create some profile directories mimicking the real profile structure.
  1016. run_cmd("mkdir -p " + app_private_dir_de_ + "/profiles/ref");
  1017. run_cmd("mkdir -p " + app_private_dir_de_ + "/profiles/cur/0/");
  1018. run_cmd("mkdir -p " + app_private_dir_de_ + "/profiles/cur/1/");
  1019. // Create an empty profile.
  1020. run_cmd("touch " + app_private_dir_de_ + "/profiles/cur/1/primary.prof");
  1021. // Create a random file.
  1022. run_cmd("touch " + app_private_dir_de_ + "/profiles/cur/0/non.profile.file");
  1023. // Create some non-empty profiles.
  1024. std::string current_prof = app_private_dir_de_ + "/profiles/cur/0/primary.prof";
  1025. run_cmd("echo 1 > " + current_prof);
  1026. std::string ref_prof = app_private_dir_de_ + "/profiles/ref/primary.prof";
  1027. run_cmd("echo 1 > " + ref_prof);
  1028. UpdateAndroidProfilesDir(app_private_dir_de_ + "/profiles");
  1029. std::vector<std::string> profiles;
  1030. collect_profiles(&profiles);
  1031. // Only two profiles should be in the output.
  1032. ASSERT_EQ(2u, profiles.size());
  1033. ASSERT_TRUE(std::find(profiles.begin(), profiles.end(), current_prof) != profiles.end());
  1034. ASSERT_TRUE(std::find(profiles.begin(), profiles.end(), ref_prof) != profiles.end());
  1035. }
  1036. TEST_F(DexoptTest, select_execution_binary) {
  1037. LOG(INFO) << "DexoptTestselect_execution_binary";
  1038. std::string release_str = app_private_dir_ce_ + "/release";
  1039. std::string debug_str = app_private_dir_ce_ + "/debug";
  1040. // Setup the binaries. Note that we only need executable files to actually
  1041. // test the execution binary selection
  1042. run_cmd("touch " + release_str);
  1043. run_cmd("touch " + debug_str);
  1044. run_cmd("chmod 777 " + release_str);
  1045. run_cmd("chmod 777 " + debug_str);
  1046. const char* release = release_str.c_str();
  1047. const char* debug = debug_str.c_str();
  1048. ASSERT_STREQ(release, select_execution_binary(
  1049. release,
  1050. debug,
  1051. /*background_job_compile=*/ false,
  1052. /*is_debug_runtime=*/ false,
  1053. /*is_release=*/ false,
  1054. /*is_debuggable_build=*/ false));
  1055. ASSERT_STREQ(release, select_execution_binary(
  1056. release,
  1057. debug,
  1058. /*background_job_compile=*/ true,
  1059. /*is_debug_runtime=*/ false,
  1060. /*is_release=*/ true,
  1061. /*is_debuggable_build=*/ true));
  1062. ASSERT_STREQ(debug, select_execution_binary(
  1063. release,
  1064. debug,
  1065. /*background_job_compile=*/ false,
  1066. /*is_debug_runtime=*/ true,
  1067. /*is_release=*/ false,
  1068. /*is_debuggable_build=*/ false));
  1069. ASSERT_STREQ(debug, select_execution_binary(
  1070. release,
  1071. debug,
  1072. /*background_job_compile=*/ true,
  1073. /*is_debug_runtime=*/ false,
  1074. /*is_release=*/ false,
  1075. /*is_debuggable_build=*/ true));
  1076. // Select the release when the debug file is not there.
  1077. ASSERT_STREQ(release, select_execution_binary(
  1078. release,
  1079. "does_not_exist",
  1080. /*background_job_compile=*/ false,
  1081. /*is_debug_runtime=*/ true,
  1082. /*is_release=*/ false,
  1083. /*is_debuggable_build=*/ false));
  1084. }
  1085. } // namespace installd
  1086. } // namespace android