1 /*
2  * Copyright (C) 2016 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 #define LOG_TAG "installd"
17 
18 #include <array>
19 #include <fcntl.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <sys/capability.h>
23 #include <sys/file.h>
24 #include <sys/stat.h>
25 #include <sys/time.h>
26 #include <sys/types.h>
27 #include <sys/resource.h>
28 #include <sys/wait.h>
29 #include <unistd.h>
30 
31 #include <iomanip>
32 
33 #include <android-base/file.h>
34 #include <android-base/logging.h>
35 #include <android-base/properties.h>
36 #include <android-base/stringprintf.h>
37 #include <android-base/strings.h>
38 #include <android-base/unique_fd.h>
39 #include <cutils/fs.h>
40 #include <cutils/properties.h>
41 #include <cutils/sched_policy.h>
42 #include <dex2oat_return_codes.h>
43 #include <log/log.h>               // TODO: Move everything to base/logging.
44 #include <openssl/sha.h>
45 #include <private/android_filesystem_config.h>
46 #include <processgroup/sched_policy.h>
47 #include <selinux/android.h>
48 #include <server_configurable_flags/get_flags.h>
49 #include <system/thread_defs.h>
50 
51 #include "dexopt.h"
52 #include "dexopt_return_codes.h"
53 #include "globals.h"
54 #include "installd_deps.h"
55 #include "otapreopt_utils.h"
56 #include "utils.h"
57 
58 using android::base::EndsWith;
59 using android::base::GetBoolProperty;
60 using android::base::GetProperty;
61 using android::base::ReadFdToString;
62 using android::base::ReadFully;
63 using android::base::StringPrintf;
64 using android::base::WriteFully;
65 using android::base::unique_fd;
66 
67 namespace android {
68 namespace installd {
69 
70 // Should minidebug info be included in compiled artifacts? Even if this value is
71 // "true," usage might still be conditional to other constraints, e.g., system
72 // property overrides.
73 static constexpr bool kEnableMinidebugInfo = true;
74 
75 static constexpr const char* kMinidebugInfoSystemProperty = "dalvik.vm.dex2oat-minidebuginfo";
76 static constexpr bool kMinidebugInfoSystemPropertyDefault = false;
77 static constexpr const char* kMinidebugDex2oatFlag = "--generate-mini-debug-info";
78 static constexpr const char* kDisableCompactDexFlag = "--compact-dex-level=none";
79 
80 
81 // Deleter using free() for use with std::unique_ptr<>. See also UniqueCPtr<> below.
82 struct FreeDelete {
83   // NOTE: Deleting a const object is valid but free() takes a non-const pointer.
operator ()android::installd::FreeDelete84   void operator()(const void* ptr) const {
85     free(const_cast<void*>(ptr));
86   }
87 };
88 
89 // Alias for std::unique_ptr<> that uses the C function free() to delete objects.
90 template <typename T>
91 using UniqueCPtr = std::unique_ptr<T, FreeDelete>;
92 
invalid_unique_fd()93 static unique_fd invalid_unique_fd() {
94     return unique_fd(-1);
95 }
96 
is_debug_runtime()97 static bool is_debug_runtime() {
98     return android::base::GetProperty("persist.sys.dalvik.vm.lib.2", "") == "libartd.so";
99 }
100 
is_debuggable_build()101 static bool is_debuggable_build() {
102     return android::base::GetBoolProperty("ro.debuggable", false);
103 }
104 
clear_profile(const std::string & profile)105 static bool clear_profile(const std::string& profile) {
106     unique_fd ufd(open(profile.c_str(), O_WRONLY | O_NOFOLLOW | O_CLOEXEC));
107     if (ufd.get() < 0) {
108         if (errno != ENOENT) {
109             PLOG(WARNING) << "Could not open profile " << profile;
110             return false;
111         } else {
112             // Nothing to clear. That's ok.
113             return true;
114         }
115     }
116 
117     if (flock(ufd.get(), LOCK_EX | LOCK_NB) != 0) {
118         if (errno != EWOULDBLOCK) {
119             PLOG(WARNING) << "Error locking profile " << profile;
120         }
121         // This implies that the app owning this profile is running
122         // (and has acquired the lock).
123         //
124         // If we can't acquire the lock bail out since clearing is useless anyway
125         // (the app will write again to the profile).
126         //
127         // Note:
128         // This does not impact the this is not an issue for the profiling correctness.
129         // In case this is needed because of an app upgrade, profiles will still be
130         // eventually cleared by the app itself due to checksum mismatch.
131         // If this is needed because profman advised, then keeping the data around
132         // until the next run is again not an issue.
133         //
134         // If the app attempts to acquire a lock while we've held one here,
135         // it will simply skip the current write cycle.
136         return false;
137     }
138 
139     bool truncated = ftruncate(ufd.get(), 0) == 0;
140     if (!truncated) {
141         PLOG(WARNING) << "Could not truncate " << profile;
142     }
143     if (flock(ufd.get(), LOCK_UN) != 0) {
144         PLOG(WARNING) << "Error unlocking profile " << profile;
145     }
146     return truncated;
147 }
148 
149 // Clear the reference profile for the given location.
150 // The location is the profile name for primary apks or the dex path for secondary dex files.
clear_reference_profile(const std::string & package_name,const std::string & location,bool is_secondary_dex)151 static bool clear_reference_profile(const std::string& package_name, const std::string& location,
152         bool is_secondary_dex) {
153     return clear_profile(create_reference_profile_path(package_name, location, is_secondary_dex));
154 }
155 
156 // Clear the reference profile for the given location.
157 // The location is the profile name for primary apks or the dex path for secondary dex files.
clear_current_profile(const std::string & package_name,const std::string & location,userid_t user,bool is_secondary_dex)158 static bool clear_current_profile(const std::string& package_name, const std::string& location,
159         userid_t user, bool is_secondary_dex) {
160     return clear_profile(create_current_profile_path(user, package_name, location,
161             is_secondary_dex));
162 }
163 
164 // Clear the reference profile for the primary apk of the given package.
165 // The location is the profile name for primary apks or the dex path for secondary dex files.
clear_primary_reference_profile(const std::string & package_name,const std::string & location)166 bool clear_primary_reference_profile(const std::string& package_name,
167         const std::string& location) {
168     return clear_reference_profile(package_name, location, /*is_secondary_dex*/false);
169 }
170 
171 // Clear all current profile for the primary apk of the given package.
172 // The location is the profile name for primary apks or the dex path for secondary dex files.
clear_primary_current_profiles(const std::string & package_name,const std::string & location)173 bool clear_primary_current_profiles(const std::string& package_name, const std::string& location) {
174     bool success = true;
175     // For secondary dex files, we don't really need the user but we use it for sanity checks.
176     std::vector<userid_t> users = get_known_users(/*volume_uuid*/ nullptr);
177     for (auto user : users) {
178         success &= clear_current_profile(package_name, location, user, /*is_secondary_dex*/false);
179     }
180     return success;
181 }
182 
183 // Clear the current profile for the primary apk of the given package and user.
clear_primary_current_profile(const std::string & package_name,const std::string & location,userid_t user)184 bool clear_primary_current_profile(const std::string& package_name, const std::string& location,
185         userid_t user) {
186     return clear_current_profile(package_name, location, user, /*is_secondary_dex*/false);
187 }
188 
SplitBySpaces(const std::string & str)189 static std::vector<std::string> SplitBySpaces(const std::string& str) {
190     if (str.empty()) {
191         return {};
192     }
193     return android::base::Split(str, " ");
194 }
195 
get_location_from_path(const char * path)196 static const char* get_location_from_path(const char* path) {
197     static constexpr char kLocationSeparator = '/';
198     const char *location = strrchr(path, kLocationSeparator);
199     if (location == nullptr) {
200         return path;
201     } else {
202         // Skip the separator character.
203         return location + 1;
204     }
205 }
206 
207 // ExecVHelper prepares and holds pointers to parsed command line arguments so that no allocations
208 // need to be performed between the fork and exec.
209 class ExecVHelper {
210   public:
211     // Store a placeholder for the binary name.
ExecVHelper()212     ExecVHelper() : args_(1u, std::string()) {}
213 
PrepareArgs(const std::string & bin)214     void PrepareArgs(const std::string& bin) {
215         CHECK(!args_.empty());
216         CHECK(args_[0].empty());
217         args_[0] = bin;
218         // Write char* into array.
219         for (const std::string& arg : args_) {
220             argv_.push_back(arg.c_str());
221         }
222         argv_.push_back(nullptr);  // Add null terminator.
223     }
224 
225     [[ noreturn ]]
Exec(int exit_code)226     void Exec(int exit_code) {
227         execv(argv_[0], (char * const *)&argv_[0]);
228         PLOG(ERROR) << "execv(" << argv_[0] << ") failed";
229         exit(exit_code);
230     }
231 
232     // Add an arg if it's not empty.
AddArg(const std::string & arg)233     void AddArg(const std::string& arg) {
234         if (!arg.empty()) {
235             args_.push_back(arg);
236         }
237     }
238 
239     // Add a runtime arg if it's not empty.
AddRuntimeArg(const std::string & arg)240     void AddRuntimeArg(const std::string& arg) {
241         if (!arg.empty()) {
242             args_.push_back("--runtime-arg");
243             args_.push_back(arg);
244         }
245     }
246 
247   protected:
248     // Holder arrays for backing arg storage.
249     std::vector<std::string> args_;
250 
251     // Argument poiners.
252     std::vector<const char*> argv_;
253 };
254 
MapPropertyToArg(const std::string & property,const std::string & format,const std::string & default_value="")255 static std::string MapPropertyToArg(const std::string& property,
256                                     const std::string& format,
257                                     const std::string& default_value = "") {
258   std::string prop = GetProperty(property, default_value);
259   if (!prop.empty()) {
260     return StringPrintf(format.c_str(), prop.c_str());
261   }
262   return "";
263 }
264 
MapPropertyToArgWithBackup(const std::string & property,const std::string & backupProperty,const std::string & format,const std::string & default_value="")265 static std::string MapPropertyToArgWithBackup(const std::string& property,
266                                               const std::string& backupProperty,
267                                               const std::string& format,
268                                               const std::string& default_value = "") {
269   std::string value = GetProperty(property, default_value);
270   if (!value.empty()) {
271     return StringPrintf(format.c_str(), value.c_str());
272   }
273   return MapPropertyToArg(backupProperty, format, default_value);
274 }
275 
276 // Determines which binary we should use for execution (the debug or non-debug version).
277 // e.g. dex2oatd vs dex2oat
select_execution_binary(const char * binary,const char * debug_binary,bool background_job_compile)278 static const char* select_execution_binary(const char* binary, const char* debug_binary,
279         bool background_job_compile) {
280     return select_execution_binary(
281         binary,
282         debug_binary,
283         background_job_compile,
284         is_debug_runtime(),
285         (android::base::GetProperty("ro.build.version.codename", "") == "REL"),
286         is_debuggable_build());
287 }
288 
289 // Determines which binary we should use for execution (the debug or non-debug version).
290 // e.g. dex2oatd vs dex2oat
291 // This is convenient method which is much easier to test because it doesn't read
292 // system properties.
select_execution_binary(const char * binary,const char * debug_binary,bool background_job_compile,bool is_debug_runtime,bool is_release,bool is_debuggable_build)293 const char* select_execution_binary(
294         const char* binary,
295         const char* debug_binary,
296         bool background_job_compile,
297         bool is_debug_runtime,
298         bool is_release,
299         bool is_debuggable_build) {
300     // Do not use debug binaries for release candidates (to give more soak time).
301     bool is_debug_bg_job = background_job_compile && is_debuggable_build && !is_release;
302 
303     // If the runtime was requested to use libartd.so, we'll run the debug version - assuming
304     // the file is present (it may not be on images with very little space available).
305     bool useDebug = (is_debug_runtime || is_debug_bg_job) && (access(debug_binary, X_OK) == 0);
306 
307     return useDebug ? debug_binary : binary;
308 }
309 
310 // Namespace for Android Runtime flags applied during boot time.
311 static const char* RUNTIME_NATIVE_BOOT_NAMESPACE = "runtime_native_boot";
312 // Feature flag name for running the JIT in Zygote experiment, b/119800099.
313 static const char* ENABLE_JITZYGOTE_IMAGE = "enable_apex_image";
314 // Location of the JIT Zygote image.
315 static const char* kJitZygoteImage =
316     "boot.art:/nonx/boot-framework.art!/system/etc/boot-image.prof";
317 
318 // Phenotype property name for enabling profiling the boot class path.
319 static const char* PROFILE_BOOT_CLASS_PATH = "profilebootclasspath";
320 
IsBootClassPathProfilingEnable()321 static bool IsBootClassPathProfilingEnable() {
322     std::string profile_boot_class_path = GetProperty("dalvik.vm.profilebootclasspath", "");
323     profile_boot_class_path =
324         server_configurable_flags::GetServerConfigurableFlag(
325             RUNTIME_NATIVE_BOOT_NAMESPACE,
326             PROFILE_BOOT_CLASS_PATH,
327             /*default_value=*/ profile_boot_class_path);
328     return profile_boot_class_path == "true";
329 }
330 
331 class RunDex2Oat : public ExecVHelper {
332   public:
RunDex2Oat(int zip_fd,int oat_fd,int input_vdex_fd,int output_vdex_fd,int image_fd,const char * input_file_name,const char * output_file_name,int swap_fd,const char * instruction_set,const char * compiler_filter,bool debuggable,bool post_bootcomplete,bool for_restore,bool background_job_compile,int profile_fd,const char * class_loader_context,const std::string & class_loader_context_fds,int target_sdk_version,bool enable_hidden_api_checks,bool generate_compact_dex,int dex_metadata_fd,const char * compilation_reason)333     RunDex2Oat(int zip_fd,
334                int oat_fd,
335                int input_vdex_fd,
336                int output_vdex_fd,
337                int image_fd,
338                const char* input_file_name,
339                const char* output_file_name,
340                int swap_fd,
341                const char* instruction_set,
342                const char* compiler_filter,
343                bool debuggable,
344                bool post_bootcomplete,
345                bool for_restore,
346                bool background_job_compile,
347                int profile_fd,
348                const char* class_loader_context,
349                const std::string& class_loader_context_fds,
350                int target_sdk_version,
351                bool enable_hidden_api_checks,
352                bool generate_compact_dex,
353                int dex_metadata_fd,
354                const char* compilation_reason) {
355         // Get the relative path to the input file.
356         const char* relative_input_file_name = get_location_from_path(input_file_name);
357 
358         std::string dex2oat_Xms_arg = MapPropertyToArg("dalvik.vm.dex2oat-Xms", "-Xms%s");
359         std::string dex2oat_Xmx_arg = MapPropertyToArg("dalvik.vm.dex2oat-Xmx", "-Xmx%s");
360 
361         std::string threads_format = "-j%s";
362         std::string dex2oat_threads_arg = post_bootcomplete
363                 ? (for_restore
364                     ? MapPropertyToArgWithBackup(
365                             "dalvik.vm.restore-dex2oat-threads",
366                             "dalvik.vm.dex2oat-threads",
367                             threads_format)
368                     : MapPropertyToArg("dalvik.vm.dex2oat-threads", threads_format))
369                 : MapPropertyToArg("dalvik.vm.boot-dex2oat-threads", threads_format);
370         std::string cpu_set_format = "--cpu-set=%s";
371         std::string dex2oat_cpu_set_arg = post_bootcomplete
372                 ? (for_restore
373                     ? MapPropertyToArgWithBackup(
374                             "dalvik.vm.restore-dex2oat-cpu-set",
375                             "dalvik.vm.dex2oat-cpu-set",
376                             cpu_set_format)
377                     : MapPropertyToArg("dalvik.vm.dex2oat-cpu-set", cpu_set_format))
378                 : MapPropertyToArg("dalvik.vm.boot-dex2oat-cpu-set", cpu_set_format);
379 
380         std::string bootclasspath;
381         char* dex2oat_bootclasspath = getenv("DEX2OATBOOTCLASSPATH");
382         if (dex2oat_bootclasspath != nullptr) {
383             bootclasspath = StringPrintf("-Xbootclasspath:%s", dex2oat_bootclasspath);
384         }
385         // If DEX2OATBOOTCLASSPATH is not in the environment, dex2oat is going to query
386         // BOOTCLASSPATH.
387 
388         const std::string dex2oat_isa_features_key =
389                 StringPrintf("dalvik.vm.isa.%s.features", instruction_set);
390         std::string instruction_set_features_arg =
391             MapPropertyToArg(dex2oat_isa_features_key, "--instruction-set-features=%s");
392 
393         const std::string dex2oat_isa_variant_key =
394                 StringPrintf("dalvik.vm.isa.%s.variant", instruction_set);
395         std::string instruction_set_variant_arg =
396             MapPropertyToArg(dex2oat_isa_variant_key, "--instruction-set-variant=%s");
397 
398         const char* dex2oat_norelocation = "-Xnorelocate";
399 
400         const std::string dex2oat_flags = GetProperty("dalvik.vm.dex2oat-flags", "");
401         std::vector<std::string> dex2oat_flags_args = SplitBySpaces(dex2oat_flags);
402         ALOGV("dalvik.vm.dex2oat-flags=%s\n", dex2oat_flags.c_str());
403 
404         // If we are booting without the real /data, don't spend time compiling.
405         std::string vold_decrypt = GetProperty("vold.decrypt", "");
406         bool skip_compilation = vold_decrypt == "trigger_restart_min_framework" ||
407                                 vold_decrypt == "1";
408 
409         std::string updatable_bcp_packages =
410             MapPropertyToArg("dalvik.vm.dex2oat-updatable-bcp-packages-file",
411                              "--updatable-bcp-packages-file=%s");
412         if (updatable_bcp_packages.empty()) {
413           // Make dex2oat fail by providing non-existent file name.
414           updatable_bcp_packages = "--updatable-bcp-packages-file=/nonx/updatable-bcp-packages.txt";
415         }
416 
417         std::string resolve_startup_string_arg =
418                 MapPropertyToArg("persist.device_config.runtime.dex2oat_resolve_startup_strings",
419                                  "--resolve-startup-const-strings=%s");
420         if (resolve_startup_string_arg.empty()) {
421           // If empty, fall back to system property.
422           resolve_startup_string_arg =
423                 MapPropertyToArg("dalvik.vm.dex2oat-resolve-startup-strings",
424                                  "--resolve-startup-const-strings=%s");
425         }
426 
427         const std::string image_block_size_arg =
428                 MapPropertyToArg("dalvik.vm.dex2oat-max-image-block-size",
429                                  "--max-image-block-size=%s");
430 
431         const bool generate_debug_info = GetBoolProperty("debug.generate-debug-info", false);
432 
433         std::string image_format_arg;
434         if (image_fd >= 0) {
435             image_format_arg = MapPropertyToArg("dalvik.vm.appimageformat", "--image-format=%s");
436         }
437 
438         std::string dex2oat_large_app_threshold_arg =
439             MapPropertyToArg("dalvik.vm.dex2oat-very-large", "--very-large-app-threshold=%s");
440 
441 
442 
443         // Decide whether to use dex2oat64.
444         bool use_dex2oat64 = false;
445         // Check whether the device even supports 64-bit ABIs.
446         if (!GetProperty("ro.product.cpu.abilist64", "").empty()) {
447           use_dex2oat64 = GetBoolProperty("dalvik.vm.dex2oat64.enabled", false);
448         }
449         const char* dex2oat_bin = select_execution_binary(
450             (use_dex2oat64 ? kDex2oat64Path : kDex2oat32Path),
451             (use_dex2oat64 ? kDex2oatDebug64Path : kDex2oatDebug32Path),
452             background_job_compile);
453 
454         bool generate_minidebug_info = kEnableMinidebugInfo &&
455                 GetBoolProperty(kMinidebugInfoSystemProperty, kMinidebugInfoSystemPropertyDefault);
456 
457         std::string boot_image;
458         std::string use_jitzygote_image =
459             server_configurable_flags::GetServerConfigurableFlag(RUNTIME_NATIVE_BOOT_NAMESPACE,
460                                                                  ENABLE_JITZYGOTE_IMAGE,
461                                                                  /*default_value=*/ "");
462 
463         if (use_jitzygote_image == "true" || IsBootClassPathProfilingEnable()) {
464           boot_image = StringPrintf("--boot-image=%s", kJitZygoteImage);
465         } else {
466           boot_image = MapPropertyToArg("dalvik.vm.boot-image", "--boot-image=%s");
467         }
468 
469         // clang FORTIFY doesn't let us use strlen in constant array bounds, so we
470         // use arraysize instead.
471         std::string zip_fd_arg = StringPrintf("--zip-fd=%d", zip_fd);
472         std::string zip_location_arg = StringPrintf("--zip-location=%s", relative_input_file_name);
473         std::string input_vdex_fd_arg = StringPrintf("--input-vdex-fd=%d", input_vdex_fd);
474         std::string output_vdex_fd_arg = StringPrintf("--output-vdex-fd=%d", output_vdex_fd);
475         std::string oat_fd_arg = StringPrintf("--oat-fd=%d", oat_fd);
476         std::string oat_location_arg = StringPrintf("--oat-location=%s", output_file_name);
477         std::string instruction_set_arg = StringPrintf("--instruction-set=%s", instruction_set);
478         std::string dex2oat_compiler_filter_arg;
479         std::string dex2oat_swap_fd;
480         std::string dex2oat_image_fd;
481         std::string target_sdk_version_arg;
482         if (target_sdk_version != 0) {
483             target_sdk_version_arg = StringPrintf("-Xtarget-sdk-version:%d", target_sdk_version);
484         }
485         std::string class_loader_context_arg;
486         std::string class_loader_context_fds_arg;
487         if (class_loader_context != nullptr) {
488             class_loader_context_arg = StringPrintf("--class-loader-context=%s",
489                                                     class_loader_context);
490             if (!class_loader_context_fds.empty()) {
491                 class_loader_context_fds_arg = StringPrintf("--class-loader-context-fds=%s",
492                                                             class_loader_context_fds.c_str());
493             }
494         }
495 
496         if (swap_fd >= 0) {
497             dex2oat_swap_fd = StringPrintf("--swap-fd=%d", swap_fd);
498         }
499         if (image_fd >= 0) {
500             dex2oat_image_fd = StringPrintf("--app-image-fd=%d", image_fd);
501         }
502 
503         // Compute compiler filter.
504         bool have_dex2oat_relocation_skip_flag = false;
505         if (skip_compilation) {
506             dex2oat_compiler_filter_arg = "--compiler-filter=extract";
507             have_dex2oat_relocation_skip_flag = true;
508         } else if (compiler_filter != nullptr) {
509             dex2oat_compiler_filter_arg = StringPrintf("--compiler-filter=%s", compiler_filter);
510         }
511 
512         if (dex2oat_compiler_filter_arg.empty()) {
513             dex2oat_compiler_filter_arg = MapPropertyToArg("dalvik.vm.dex2oat-filter",
514                                                            "--compiler-filter=%s");
515         }
516 
517         // Check whether all apps should be compiled debuggable.
518         if (!debuggable) {
519             debuggable = GetProperty("dalvik.vm.always_debuggable", "") == "1";
520         }
521         std::string profile_arg;
522         if (profile_fd != -1) {
523             profile_arg = StringPrintf("--profile-file-fd=%d", profile_fd);
524         }
525 
526         // Get the directory of the apk to pass as a base classpath directory.
527         std::string base_dir;
528         std::string apk_dir(input_file_name);
529         unsigned long dir_index = apk_dir.rfind('/');
530         bool has_base_dir = dir_index != std::string::npos;
531         if (has_base_dir) {
532             apk_dir = apk_dir.substr(0, dir_index);
533             base_dir = StringPrintf("--classpath-dir=%s", apk_dir.c_str());
534         }
535 
536         std::string dex_metadata_fd_arg = "--dm-fd=" + std::to_string(dex_metadata_fd);
537 
538         std::string compilation_reason_arg = compilation_reason == nullptr
539                 ? ""
540                 : std::string("--compilation-reason=") + compilation_reason;
541 
542         ALOGV("Running %s in=%s out=%s\n", dex2oat_bin, relative_input_file_name, output_file_name);
543 
544         // Disable cdex if update input vdex is true since this combination of options is not
545         // supported.
546         const bool disable_cdex = !generate_compact_dex || (input_vdex_fd == output_vdex_fd);
547 
548         AddArg(zip_fd_arg);
549         AddArg(zip_location_arg);
550         AddArg(input_vdex_fd_arg);
551         AddArg(output_vdex_fd_arg);
552         AddArg(oat_fd_arg);
553         AddArg(oat_location_arg);
554         AddArg(instruction_set_arg);
555 
556         AddArg(instruction_set_variant_arg);
557         AddArg(instruction_set_features_arg);
558 
559         AddArg(boot_image);
560 
561         AddRuntimeArg(bootclasspath);
562         AddRuntimeArg(dex2oat_Xms_arg);
563         AddRuntimeArg(dex2oat_Xmx_arg);
564 
565         AddArg(updatable_bcp_packages);
566         AddArg(resolve_startup_string_arg);
567         AddArg(image_block_size_arg);
568         AddArg(dex2oat_compiler_filter_arg);
569         AddArg(dex2oat_threads_arg);
570         AddArg(dex2oat_cpu_set_arg);
571         AddArg(dex2oat_swap_fd);
572         AddArg(dex2oat_image_fd);
573 
574         if (generate_debug_info) {
575             AddArg("--generate-debug-info");
576         }
577         if (debuggable) {
578             AddArg("--debuggable");
579         }
580         AddArg(image_format_arg);
581         AddArg(dex2oat_large_app_threshold_arg);
582 
583         if (have_dex2oat_relocation_skip_flag) {
584             AddRuntimeArg(dex2oat_norelocation);
585         }
586         AddArg(profile_arg);
587         AddArg(base_dir);
588         AddArg(class_loader_context_arg);
589         AddArg(class_loader_context_fds_arg);
590         if (generate_minidebug_info) {
591             AddArg(kMinidebugDex2oatFlag);
592         }
593         if (disable_cdex) {
594             AddArg(kDisableCompactDexFlag);
595         }
596         AddRuntimeArg(target_sdk_version_arg);
597         if (enable_hidden_api_checks) {
598             AddRuntimeArg("-Xhidden-api-policy:enabled");
599         }
600 
601         if (dex_metadata_fd > -1) {
602             AddArg(dex_metadata_fd_arg);
603         }
604 
605         AddArg(compilation_reason_arg);
606 
607         // Do not add args after dex2oat_flags, they should override others for debugging.
608         args_.insert(args_.end(), dex2oat_flags_args.begin(), dex2oat_flags_args.end());
609 
610         PrepareArgs(dex2oat_bin);
611     }
612 };
613 
614 /*
615  * Whether dexopt should use a swap file when compiling an APK.
616  *
617  * If kAlwaysProvideSwapFile, do this on all devices (dex2oat will make a more informed decision
618  * itself, anyways).
619  *
620  * Otherwise, read "dalvik.vm.dex2oat-swap". If the property exists, return whether it is "true".
621  *
622  * Otherwise, return true if this is a low-mem device.
623  *
624  * Otherwise, return default value.
625  */
626 static bool kAlwaysProvideSwapFile = false;
627 static bool kDefaultProvideSwapFile = true;
628 
ShouldUseSwapFileForDexopt()629 static bool ShouldUseSwapFileForDexopt() {
630     if (kAlwaysProvideSwapFile) {
631         return true;
632     }
633 
634     // Check the "override" property. If it exists, return value == "true".
635     std::string dex2oat_prop_buf = GetProperty("dalvik.vm.dex2oat-swap", "");
636     if (!dex2oat_prop_buf.empty()) {
637         return dex2oat_prop_buf == "true";
638     }
639 
640     // Shortcut for default value. This is an implementation optimization for the process sketched
641     // above. If the default value is true, we can avoid to check whether this is a low-mem device,
642     // as low-mem is never returning false. The compiler will optimize this away if it can.
643     if (kDefaultProvideSwapFile) {
644         return true;
645     }
646 
647     if (GetBoolProperty("ro.config.low_ram", false)) {
648         return true;
649     }
650 
651     // Default value must be false here.
652     return kDefaultProvideSwapFile;
653 }
654 
SetDex2OatScheduling(bool set_to_bg)655 static void SetDex2OatScheduling(bool set_to_bg) {
656     if (set_to_bg) {
657         if (set_sched_policy(0, SP_BACKGROUND) < 0) {
658             PLOG(ERROR) << "set_sched_policy failed";
659             exit(DexoptReturnCodes::kSetSchedPolicy);
660         }
661         if (setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_BACKGROUND) < 0) {
662             PLOG(ERROR) << "setpriority failed";
663             exit(DexoptReturnCodes::kSetPriority);
664         }
665     }
666 }
667 
create_profile(uid_t uid,const std::string & profile,int32_t flags)668 static unique_fd create_profile(uid_t uid, const std::string& profile, int32_t flags) {
669     unique_fd fd(TEMP_FAILURE_RETRY(open(profile.c_str(), flags, 0600)));
670     if (fd.get() < 0) {
671         if (errno != EEXIST) {
672             PLOG(ERROR) << "Failed to create profile " << profile;
673             return invalid_unique_fd();
674         }
675     }
676     // Profiles should belong to the app; make sure of that by giving ownership to
677     // the app uid. If we cannot do that, there's no point in returning the fd
678     // since dex2oat/profman will fail with SElinux denials.
679     if (fchown(fd.get(), uid, uid) < 0) {
680         PLOG(ERROR) << "Could not chown profile " << profile;
681         return invalid_unique_fd();
682     }
683     return fd;
684 }
685 
open_profile(uid_t uid,const std::string & profile,int32_t flags)686 static unique_fd open_profile(uid_t uid, const std::string& profile, int32_t flags) {
687     // Do not follow symlinks when opening a profile:
688     //   - primary profiles should not contain symlinks in their paths
689     //   - secondary dex paths should have been already resolved and validated
690     flags |= O_NOFOLLOW;
691 
692     // Check if we need to create the profile
693     // Reference profiles and snapshots are created on the fly; so they might not exist beforehand.
694     unique_fd fd;
695     if ((flags & O_CREAT) != 0) {
696         fd = create_profile(uid, profile, flags);
697     } else {
698         fd.reset(TEMP_FAILURE_RETRY(open(profile.c_str(), flags)));
699     }
700 
701     if (fd.get() < 0) {
702         if (errno != ENOENT) {
703             // Profiles might be missing for various reasons. For example, in a
704             // multi-user environment, the profile directory for one user can be created
705             // after we start a merge. In this case the current profile for that user
706             // will not be found.
707             // Also, the secondary dex profiles might be deleted by the app at any time,
708             // so we can't we need to prepare if they are missing.
709             PLOG(ERROR) << "Failed to open profile " << profile;
710         }
711         return invalid_unique_fd();
712     }
713 
714     return fd;
715 }
716 
open_current_profile(uid_t uid,userid_t user,const std::string & package_name,const std::string & location,bool is_secondary_dex)717 static unique_fd open_current_profile(uid_t uid, userid_t user, const std::string& package_name,
718         const std::string& location, bool is_secondary_dex) {
719     std::string profile = create_current_profile_path(user, package_name, location,
720             is_secondary_dex);
721     return open_profile(uid, profile, O_RDONLY);
722 }
723 
open_reference_profile(uid_t uid,const std::string & package_name,const std::string & location,bool read_write,bool is_secondary_dex)724 static unique_fd open_reference_profile(uid_t uid, const std::string& package_name,
725         const std::string& location, bool read_write, bool is_secondary_dex) {
726     std::string profile = create_reference_profile_path(package_name, location, is_secondary_dex);
727     return open_profile(uid, profile, read_write ? (O_CREAT | O_RDWR) : O_RDONLY);
728 }
729 
open_spnashot_profile(uid_t uid,const std::string & package_name,const std::string & location)730 static unique_fd open_spnashot_profile(uid_t uid, const std::string& package_name,
731         const std::string& location) {
732     std::string profile = create_snapshot_profile_path(package_name, location);
733     return open_profile(uid, profile, O_CREAT | O_RDWR | O_TRUNC);
734 }
735 
open_profile_files(uid_t uid,const std::string & package_name,const std::string & location,bool is_secondary_dex,std::vector<unique_fd> * profiles_fd,unique_fd * reference_profile_fd)736 static void open_profile_files(uid_t uid, const std::string& package_name,
737             const std::string& location, bool is_secondary_dex,
738             /*out*/ std::vector<unique_fd>* profiles_fd, /*out*/ unique_fd* reference_profile_fd) {
739     // Open the reference profile in read-write mode as profman might need to save the merge.
740     *reference_profile_fd = open_reference_profile(uid, package_name, location,
741             /*read_write*/ true, is_secondary_dex);
742 
743     // For secondary dex files, we don't really need the user but we use it for sanity checks.
744     // Note: the user owning the dex file should be the current user.
745     std::vector<userid_t> users;
746     if (is_secondary_dex){
747         users.push_back(multiuser_get_user_id(uid));
748     } else {
749         users = get_known_users(/*volume_uuid*/ nullptr);
750     }
751     for (auto user : users) {
752         unique_fd profile_fd = open_current_profile(uid, user, package_name, location,
753                 is_secondary_dex);
754         // Add to the lists only if both fds are valid.
755         if (profile_fd.get() >= 0) {
756             profiles_fd->push_back(std::move(profile_fd));
757         }
758     }
759 }
760 
761 static constexpr int PROFMAN_BIN_RETURN_CODE_SUCCESS = 0;
762 static constexpr int PROFMAN_BIN_RETURN_CODE_COMPILE = 1;
763 static constexpr int PROFMAN_BIN_RETURN_CODE_SKIP_COMPILATION = 2;
764 static constexpr int PROFMAN_BIN_RETURN_CODE_BAD_PROFILES = 3;
765 static constexpr int PROFMAN_BIN_RETURN_CODE_ERROR_IO = 4;
766 static constexpr int PROFMAN_BIN_RETURN_CODE_ERROR_LOCKING = 5;
767 static constexpr int PROFMAN_BIN_RETURN_CODE_ERROR_DIFFERENT_VERSIONS = 6;
768 
769 class RunProfman : public ExecVHelper {
770   public:
SetupArgs(const std::vector<unique_fd> & profile_fds,const unique_fd & reference_profile_fd,const std::vector<unique_fd> & apk_fds,const std::vector<std::string> & dex_locations,bool copy_and_update,bool for_snapshot,bool for_boot_image)771    void SetupArgs(const std::vector<unique_fd>& profile_fds,
772                   const unique_fd& reference_profile_fd,
773                   const std::vector<unique_fd>& apk_fds,
774                   const std::vector<std::string>& dex_locations,
775                   bool copy_and_update,
776                   bool for_snapshot,
777                   bool for_boot_image) {
778 
779         // TODO(calin): Assume for now we run in the bg compile job (which is in
780         // most of the invocation). With the current data flow, is not very easy or
781         // clean to discover this in RunProfman (it will require quite a messy refactoring).
782         const char* profman_bin = select_execution_binary(
783             kProfmanPath, kProfmanDebugPath, /*background_job_compile=*/ true);
784 
785         if (copy_and_update) {
786             CHECK_EQ(1u, profile_fds.size());
787             CHECK_EQ(1u, apk_fds.size());
788         }
789         if (reference_profile_fd != -1) {
790             AddArg("--reference-profile-file-fd=" + std::to_string(reference_profile_fd.get()));
791         }
792 
793         for (const unique_fd& fd : profile_fds) {
794             AddArg("--profile-file-fd=" + std::to_string(fd.get()));
795         }
796 
797         for (const unique_fd& fd : apk_fds) {
798             AddArg("--apk-fd=" + std::to_string(fd.get()));
799         }
800 
801         for (const std::string& dex_location : dex_locations) {
802             AddArg("--dex-location=" + dex_location);
803         }
804 
805         if (copy_and_update) {
806             AddArg("--copy-and-update-profile-key");
807         }
808 
809         if (for_snapshot) {
810             AddArg("--force-merge");
811         }
812 
813         if (for_boot_image) {
814             AddArg("--boot-image-merge");
815         }
816 
817         // Do not add after dex2oat_flags, they should override others for debugging.
818         PrepareArgs(profman_bin);
819     }
820 
SetupMerge(const std::vector<unique_fd> & profiles_fd,const unique_fd & reference_profile_fd,const std::vector<unique_fd> & apk_fds=std::vector<unique_fd> (),const std::vector<std::string> & dex_locations=std::vector<std::string> (),bool for_snapshot=false,bool for_boot_image=false)821     void SetupMerge(const std::vector<unique_fd>& profiles_fd,
822                     const unique_fd& reference_profile_fd,
823                     const std::vector<unique_fd>& apk_fds = std::vector<unique_fd>(),
824                     const std::vector<std::string>& dex_locations = std::vector<std::string>(),
825                     bool for_snapshot = false,
826                     bool for_boot_image = false) {
827         SetupArgs(profiles_fd,
828                   reference_profile_fd,
829                   apk_fds,
830                   dex_locations,
831                   /*copy_and_update=*/ false,
832                   for_snapshot,
833                   for_boot_image);
834     }
835 
SetupCopyAndUpdate(unique_fd && profile_fd,unique_fd && reference_profile_fd,unique_fd && apk_fd,const std::string & dex_location)836     void SetupCopyAndUpdate(unique_fd&& profile_fd,
837                             unique_fd&& reference_profile_fd,
838                             unique_fd&& apk_fd,
839                             const std::string& dex_location) {
840         // The fds need to stay open longer than the scope of the function, so put them into a local
841         // variable vector.
842         profiles_fd_.push_back(std::move(profile_fd));
843         apk_fds_.push_back(std::move(apk_fd));
844         reference_profile_fd_ = std::move(reference_profile_fd);
845         std::vector<std::string> dex_locations = {dex_location};
846         SetupArgs(profiles_fd_,
847                   reference_profile_fd_,
848                   apk_fds_,
849                   dex_locations,
850                   /*copy_and_update=*/true,
851                   /*for_snapshot*/false,
852                   /*for_boot_image*/false);
853     }
854 
SetupDump(const std::vector<unique_fd> & profiles_fd,const unique_fd & reference_profile_fd,const std::vector<std::string> & dex_locations,const std::vector<unique_fd> & apk_fds,const unique_fd & output_fd)855     void SetupDump(const std::vector<unique_fd>& profiles_fd,
856                    const unique_fd& reference_profile_fd,
857                    const std::vector<std::string>& dex_locations,
858                    const std::vector<unique_fd>& apk_fds,
859                    const unique_fd& output_fd) {
860         AddArg("--dump-only");
861         AddArg(StringPrintf("--dump-output-to-fd=%d", output_fd.get()));
862         SetupArgs(profiles_fd,
863                   reference_profile_fd,
864                   apk_fds,
865                   dex_locations,
866                   /*copy_and_update=*/false,
867                   /*for_snapshot*/false,
868                   /*for_boot_image*/false);
869     }
870 
Exec()871     void Exec() {
872         ExecVHelper::Exec(DexoptReturnCodes::kProfmanExec);
873     }
874 
875   private:
876     unique_fd reference_profile_fd_;
877     std::vector<unique_fd> profiles_fd_;
878     std::vector<unique_fd> apk_fds_;
879 };
880 
881 
882 
883 // Decides if profile guided compilation is needed or not based on existing profiles.
884 // The location is the package name for primary apks or the dex path for secondary dex files.
885 // Returns true if there is enough information in the current profiles that makes it
886 // worth to recompile the given location.
887 // If the return value is true all the current profiles would have been merged into
888 // the reference profiles accessible with open_reference_profile().
analyze_profiles(uid_t uid,const std::string & package_name,const std::string & location,bool is_secondary_dex)889 static bool analyze_profiles(uid_t uid, const std::string& package_name,
890         const std::string& location, bool is_secondary_dex) {
891     std::vector<unique_fd> profiles_fd;
892     unique_fd reference_profile_fd;
893     open_profile_files(uid, package_name, location, is_secondary_dex,
894         &profiles_fd, &reference_profile_fd);
895     if (profiles_fd.empty() || (reference_profile_fd.get() < 0)) {
896         // Skip profile guided compilation because no profiles were found.
897         // Or if the reference profile info couldn't be opened.
898         return false;
899     }
900 
901     RunProfman profman_merge;
902     const std::vector<unique_fd>& apk_fds = std::vector<unique_fd>();
903     const std::vector<std::string>& dex_locations = std::vector<std::string>();
904     profman_merge.SetupMerge(
905             profiles_fd,
906             reference_profile_fd,
907             apk_fds,
908             dex_locations,
909             /* for_snapshot= */ false,
910             IsBootClassPathProfilingEnable());
911     pid_t pid = fork();
912     if (pid == 0) {
913         /* child -- drop privileges before continuing */
914         drop_capabilities(uid);
915         profman_merge.Exec();
916     }
917     /* parent */
918     int return_code = wait_child(pid);
919     bool need_to_compile = false;
920     bool should_clear_current_profiles = false;
921     bool should_clear_reference_profile = false;
922     if (!WIFEXITED(return_code)) {
923         LOG(WARNING) << "profman failed for location " << location << ": " << return_code;
924     } else {
925         return_code = WEXITSTATUS(return_code);
926         switch (return_code) {
927             case PROFMAN_BIN_RETURN_CODE_COMPILE:
928                 need_to_compile = true;
929                 should_clear_current_profiles = true;
930                 should_clear_reference_profile = false;
931                 break;
932             case PROFMAN_BIN_RETURN_CODE_SKIP_COMPILATION:
933                 need_to_compile = false;
934                 should_clear_current_profiles = false;
935                 should_clear_reference_profile = false;
936                 break;
937             case PROFMAN_BIN_RETURN_CODE_BAD_PROFILES:
938                 LOG(WARNING) << "Bad profiles for location " << location;
939                 need_to_compile = false;
940                 should_clear_current_profiles = true;
941                 should_clear_reference_profile = true;
942                 break;
943             case PROFMAN_BIN_RETURN_CODE_ERROR_IO:  // fall-through
944             case PROFMAN_BIN_RETURN_CODE_ERROR_LOCKING:
945                 // Temporary IO problem (e.g. locking). Ignore but log a warning.
946                 LOG(WARNING) << "IO error while reading profiles for location " << location;
947                 need_to_compile = false;
948                 should_clear_current_profiles = false;
949                 should_clear_reference_profile = false;
950                 break;
951             case PROFMAN_BIN_RETURN_CODE_ERROR_DIFFERENT_VERSIONS:
952                 need_to_compile = false;
953                 should_clear_current_profiles = true;
954                 should_clear_reference_profile = true;
955                 break;
956            default:
957                 // Unknown return code or error. Unlink profiles.
958                 LOG(WARNING) << "Unexpected error code while processing profiles for location "
959                         << location << ": " << return_code;
960                 need_to_compile = false;
961                 should_clear_current_profiles = true;
962                 should_clear_reference_profile = true;
963                 break;
964         }
965     }
966 
967     if (should_clear_current_profiles) {
968         if (is_secondary_dex) {
969             // For secondary dex files, the owning user is the current user.
970             clear_current_profile(package_name, location, multiuser_get_user_id(uid),
971                     is_secondary_dex);
972         } else  {
973             clear_primary_current_profiles(package_name, location);
974         }
975     }
976     if (should_clear_reference_profile) {
977         clear_reference_profile(package_name, location, is_secondary_dex);
978     }
979     return need_to_compile;
980 }
981 
982 // Decides if profile guided compilation is needed or not based on existing profiles.
983 // The analysis is done for the primary apks of the given package.
984 // Returns true if there is enough information in the current profiles that makes it
985 // worth to recompile the package.
986 // If the return value is true all the current profiles would have been merged into
987 // the reference profiles accessible with open_reference_profile().
analyze_primary_profiles(uid_t uid,const std::string & package_name,const std::string & profile_name)988 bool analyze_primary_profiles(uid_t uid, const std::string& package_name,
989         const std::string& profile_name) {
990     return analyze_profiles(uid, package_name, profile_name, /*is_secondary_dex*/false);
991 }
992 
dump_profiles(int32_t uid,const std::string & pkgname,const std::string & profile_name,const std::string & code_path)993 bool dump_profiles(int32_t uid, const std::string& pkgname, const std::string& profile_name,
994         const std::string& code_path) {
995     std::vector<unique_fd> profile_fds;
996     unique_fd reference_profile_fd;
997     std::string out_file_name = StringPrintf("/data/misc/profman/%s-%s.txt",
998         pkgname.c_str(), profile_name.c_str());
999 
1000     open_profile_files(uid, pkgname, profile_name, /*is_secondary_dex*/false,
1001             &profile_fds, &reference_profile_fd);
1002 
1003     const bool has_reference_profile = (reference_profile_fd.get() != -1);
1004     const bool has_profiles = !profile_fds.empty();
1005 
1006     if (!has_reference_profile && !has_profiles) {
1007         LOG(ERROR)  << "profman dump: no profiles to dump for " << pkgname;
1008         return false;
1009     }
1010 
1011     unique_fd output_fd(open(out_file_name.c_str(),
1012             O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW, 0644));
1013     if (fchmod(output_fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
1014         LOG(ERROR) << "installd cannot chmod file for dump_profile" << out_file_name;
1015         return false;
1016     }
1017 
1018     std::vector<std::string> dex_locations;
1019     std::vector<unique_fd> apk_fds;
1020     unique_fd apk_fd(open(code_path.c_str(), O_RDONLY | O_NOFOLLOW));
1021     if (apk_fd == -1) {
1022         PLOG(ERROR) << "installd cannot open " << code_path.c_str();
1023         return false;
1024     }
1025     dex_locations.push_back(get_location_from_path(code_path.c_str()));
1026     apk_fds.push_back(std::move(apk_fd));
1027 
1028 
1029     RunProfman profman_dump;
1030     profman_dump.SetupDump(profile_fds, reference_profile_fd, dex_locations, apk_fds, output_fd);
1031     pid_t pid = fork();
1032     if (pid == 0) {
1033         /* child -- drop privileges before continuing */
1034         drop_capabilities(uid);
1035         profman_dump.Exec();
1036     }
1037     /* parent */
1038     int return_code = wait_child(pid);
1039     if (!WIFEXITED(return_code)) {
1040         LOG(WARNING) << "profman failed for package " << pkgname << ": "
1041                 << return_code;
1042         return false;
1043     }
1044     return true;
1045 }
1046 
copy_system_profile(const std::string & system_profile,uid_t packageUid,const std::string & package_name,const std::string & profile_name)1047 bool copy_system_profile(const std::string& system_profile,
1048         uid_t packageUid, const std::string& package_name, const std::string& profile_name) {
1049     unique_fd in_fd(open(system_profile.c_str(), O_RDONLY | O_NOFOLLOW | O_CLOEXEC));
1050     unique_fd out_fd(open_reference_profile(packageUid,
1051                      package_name,
1052                      profile_name,
1053                      /*read_write*/ true,
1054                      /*secondary*/ false));
1055     if (in_fd.get() < 0) {
1056         PLOG(WARNING) << "Could not open profile " << system_profile;
1057         return false;
1058     }
1059     if (out_fd.get() < 0) {
1060         PLOG(WARNING) << "Could not open profile " << package_name;
1061         return false;
1062     }
1063 
1064     // As a security measure we want to write the profile information with the reduced capabilities
1065     // of the package user id. So we fork and drop capabilities in the child.
1066     pid_t pid = fork();
1067     if (pid == 0) {
1068         /* child -- drop privileges before continuing */
1069         drop_capabilities(packageUid);
1070 
1071         if (flock(out_fd.get(), LOCK_EX | LOCK_NB) != 0) {
1072             if (errno != EWOULDBLOCK) {
1073                 PLOG(WARNING) << "Error locking profile " << package_name;
1074             }
1075             // This implies that the app owning this profile is running
1076             // (and has acquired the lock).
1077             //
1078             // The app never acquires the lock for the reference profiles of primary apks.
1079             // Only dex2oat from installd will do that. Since installd is single threaded
1080             // we should not see this case. Nevertheless be prepared for it.
1081             PLOG(WARNING) << "Failed to flock " << package_name;
1082             return false;
1083         }
1084 
1085         bool truncated = ftruncate(out_fd.get(), 0) == 0;
1086         if (!truncated) {
1087             PLOG(WARNING) << "Could not truncate " << package_name;
1088         }
1089 
1090         // Copy over data.
1091         static constexpr size_t kBufferSize = 4 * 1024;
1092         char buffer[kBufferSize];
1093         while (true) {
1094             ssize_t bytes = read(in_fd.get(), buffer, kBufferSize);
1095             if (bytes == 0) {
1096                 break;
1097             }
1098             write(out_fd.get(), buffer, bytes);
1099         }
1100         if (flock(out_fd.get(), LOCK_UN) != 0) {
1101             PLOG(WARNING) << "Error unlocking profile " << package_name;
1102         }
1103         // Use _exit since we don't want to run the global destructors in the child.
1104         // b/62597429
1105         _exit(0);
1106     }
1107     /* parent */
1108     int return_code = wait_child(pid);
1109     return return_code == 0;
1110 }
1111 
replace_file_extension(const std::string & oat_path,const std::string & new_ext)1112 static std::string replace_file_extension(const std::string& oat_path, const std::string& new_ext) {
1113   // A standard dalvik-cache entry. Replace ".dex" with `new_ext`.
1114   if (EndsWith(oat_path, ".dex")) {
1115     std::string new_path = oat_path;
1116     new_path.replace(new_path.length() - strlen(".dex"), strlen(".dex"), new_ext);
1117     CHECK(EndsWith(new_path, new_ext));
1118     return new_path;
1119   }
1120 
1121   // An odex entry. Not that this may not be an extension, e.g., in the OTA
1122   // case (where the base name will have an extension for the B artifact).
1123   size_t odex_pos = oat_path.rfind(".odex");
1124   if (odex_pos != std::string::npos) {
1125     std::string new_path = oat_path;
1126     new_path.replace(odex_pos, strlen(".odex"), new_ext);
1127     CHECK_NE(new_path.find(new_ext), std::string::npos);
1128     return new_path;
1129   }
1130 
1131   // Don't know how to handle this.
1132   return "";
1133 }
1134 
1135 // Translate the given oat path to an art (app image) path. An empty string
1136 // denotes an error.
create_image_filename(const std::string & oat_path)1137 static std::string create_image_filename(const std::string& oat_path) {
1138     return replace_file_extension(oat_path, ".art");
1139 }
1140 
1141 // Translate the given oat path to a vdex path. An empty string denotes an error.
create_vdex_filename(const std::string & oat_path)1142 static std::string create_vdex_filename(const std::string& oat_path) {
1143     return replace_file_extension(oat_path, ".vdex");
1144 }
1145 
open_output_file(const char * file_name,bool recreate,int permissions)1146 static int open_output_file(const char* file_name, bool recreate, int permissions) {
1147     int flags = O_RDWR | O_CREAT;
1148     if (recreate) {
1149         if (unlink(file_name) < 0) {
1150             if (errno != ENOENT) {
1151                 PLOG(ERROR) << "open_output_file: Couldn't unlink " << file_name;
1152             }
1153         }
1154         flags |= O_EXCL;
1155     }
1156     return open(file_name, flags, permissions);
1157 }
1158 
set_permissions_and_ownership(int fd,bool is_public,int uid,const char * path,bool is_secondary_dex)1159 static bool set_permissions_and_ownership(
1160         int fd, bool is_public, int uid, const char* path, bool is_secondary_dex) {
1161     // Primary apks are owned by the system. Secondary dex files are owned by the app.
1162     int owning_uid = is_secondary_dex ? uid : AID_SYSTEM;
1163     if (fchmod(fd,
1164                S_IRUSR|S_IWUSR|S_IRGRP |
1165                (is_public ? S_IROTH : 0)) < 0) {
1166         ALOGE("installd cannot chmod '%s' during dexopt\n", path);
1167         return false;
1168     } else if (fchown(fd, owning_uid, uid) < 0) {
1169         ALOGE("installd cannot chown '%s' during dexopt\n", path);
1170         return false;
1171     }
1172     return true;
1173 }
1174 
IsOutputDalvikCache(const char * oat_dir)1175 static bool IsOutputDalvikCache(const char* oat_dir) {
1176   // InstallerConnection.java (which invokes installd) transforms Java null arguments
1177   // into '!'. Play it safe by handling it both.
1178   // TODO: ensure we never get null.
1179   // TODO: pass a flag instead of inferring if the output is dalvik cache.
1180   return oat_dir == nullptr || oat_dir[0] == '!';
1181 }
1182 
1183 // Best-effort check whether we can fit the the path into our buffers.
1184 // Note: the cache path will require an additional 5 bytes for ".swap", but we'll try to run
1185 // without a swap file, if necessary. Reference profiles file also add an extra ".prof"
1186 // extension to the cache path (5 bytes).
1187 // TODO(calin): move away from char* buffers and PKG_PATH_MAX.
validate_dex_path_size(const std::string & dex_path)1188 static bool validate_dex_path_size(const std::string& dex_path) {
1189     if (dex_path.size() >= (PKG_PATH_MAX - 8)) {
1190         LOG(ERROR) << "dex_path too long: " << dex_path;
1191         return false;
1192     }
1193     return true;
1194 }
1195 
create_oat_out_path(const char * apk_path,const char * instruction_set,const char * oat_dir,bool is_secondary_dex,char * out_oat_path)1196 static bool create_oat_out_path(const char* apk_path, const char* instruction_set,
1197             const char* oat_dir, bool is_secondary_dex, /*out*/ char* out_oat_path) {
1198     if (!validate_dex_path_size(apk_path)) {
1199         return false;
1200     }
1201 
1202     if (!IsOutputDalvikCache(oat_dir)) {
1203         // Oat dirs for secondary dex files are already validated.
1204         if (!is_secondary_dex && validate_apk_path(oat_dir)) {
1205             ALOGE("cannot validate apk path with oat_dir '%s'\n", oat_dir);
1206             return false;
1207         }
1208         if (!calculate_oat_file_path(out_oat_path, oat_dir, apk_path, instruction_set)) {
1209             return false;
1210         }
1211     } else {
1212         if (!create_cache_path(out_oat_path, apk_path, instruction_set)) {
1213             return false;
1214         }
1215     }
1216     return true;
1217 }
1218 
1219 // Helper for fd management. This is similar to a unique_fd in that it closes the file descriptor
1220 // on destruction. It will also run the given cleanup (unless told not to) after closing.
1221 //
1222 // Usage example:
1223 //
1224 //   Dex2oatFileWrapper file(open(...),
1225 //                                                   [name]() {
1226 //                                                       unlink(name.c_str());
1227 //                                                   });
1228 //   // Note: care needs to be taken about name, as it needs to have a lifetime longer than the
1229 //            wrapper if captured as a reference.
1230 //
1231 //   if (file.get() == -1) {
1232 //       // Error opening...
1233 //   }
1234 //
1235 //   ...
1236 //   if (error) {
1237 //       // At this point, when the Dex2oatFileWrapper is destructed, the cleanup function will run
1238 //       // and delete the file (after the fd is closed).
1239 //       return -1;
1240 //   }
1241 //
1242 //   (Success case)
1243 //   file.SetCleanup(false);
1244 //   // At this point, when the Dex2oatFileWrapper is destructed, the cleanup function will not run
1245 //   // (leaving the file around; after the fd is closed).
1246 //
1247 class Dex2oatFileWrapper {
1248  public:
Dex2oatFileWrapper()1249     Dex2oatFileWrapper() : value_(-1), cleanup_(), do_cleanup_(true), auto_close_(true) {
1250     }
1251 
Dex2oatFileWrapper(int value,std::function<void ()> cleanup)1252     Dex2oatFileWrapper(int value, std::function<void ()> cleanup)
1253             : value_(value), cleanup_(cleanup), do_cleanup_(true), auto_close_(true) {}
1254 
Dex2oatFileWrapper(Dex2oatFileWrapper && other)1255     Dex2oatFileWrapper(Dex2oatFileWrapper&& other) {
1256         value_ = other.value_;
1257         cleanup_ = other.cleanup_;
1258         do_cleanup_ = other.do_cleanup_;
1259         auto_close_ = other.auto_close_;
1260         other.release();
1261     }
1262 
operator =(Dex2oatFileWrapper && other)1263     Dex2oatFileWrapper& operator=(Dex2oatFileWrapper&& other) {
1264         value_ = other.value_;
1265         cleanup_ = other.cleanup_;
1266         do_cleanup_ = other.do_cleanup_;
1267         auto_close_ = other.auto_close_;
1268         other.release();
1269         return *this;
1270     }
1271 
~Dex2oatFileWrapper()1272     ~Dex2oatFileWrapper() {
1273         reset(-1);
1274     }
1275 
get()1276     int get() {
1277         return value_;
1278     }
1279 
SetCleanup(bool cleanup)1280     void SetCleanup(bool cleanup) {
1281         do_cleanup_ = cleanup;
1282     }
1283 
reset(int new_value)1284     void reset(int new_value) {
1285         if (auto_close_ && value_ >= 0) {
1286             close(value_);
1287         }
1288         if (do_cleanup_ && cleanup_ != nullptr) {
1289             cleanup_();
1290         }
1291 
1292         value_ = new_value;
1293     }
1294 
reset(int new_value,std::function<void ()> new_cleanup)1295     void reset(int new_value, std::function<void ()> new_cleanup) {
1296         if (auto_close_ && value_ >= 0) {
1297             close(value_);
1298         }
1299         if (do_cleanup_ && cleanup_ != nullptr) {
1300             cleanup_();
1301         }
1302 
1303         value_ = new_value;
1304         cleanup_ = new_cleanup;
1305     }
1306 
DisableAutoClose()1307     void DisableAutoClose() {
1308         auto_close_ = false;
1309     }
1310 
1311  private:
release()1312     void release() {
1313         value_ = -1;
1314         do_cleanup_ = false;
1315         cleanup_ = nullptr;
1316     }
1317     int value_;
1318     std::function<void ()> cleanup_;
1319     bool do_cleanup_;
1320     bool auto_close_;
1321 };
1322 
1323 // (re)Creates the app image if needed.
maybe_open_app_image(const char * out_oat_path,bool generate_app_image,bool is_public,int uid,bool is_secondary_dex)1324 Dex2oatFileWrapper maybe_open_app_image(const char* out_oat_path,
1325         bool generate_app_image, bool is_public, int uid, bool is_secondary_dex) {
1326 
1327     const std::string image_path = create_image_filename(out_oat_path);
1328     if (image_path.empty()) {
1329         // Happens when the out_oat_path has an unknown extension.
1330         return Dex2oatFileWrapper();
1331     }
1332 
1333     // In case there is a stale image, remove it now. Ignore any error.
1334     unlink(image_path.c_str());
1335 
1336     // Not enabled, exit.
1337     if (!generate_app_image) {
1338         return Dex2oatFileWrapper();
1339     }
1340     std::string app_image_format = GetProperty("dalvik.vm.appimageformat", "");
1341     if (app_image_format.empty()) {
1342         return Dex2oatFileWrapper();
1343     }
1344     // Recreate is true since we do not want to modify a mapped image. If the app is
1345     // already running and we modify the image file, it can cause crashes (b/27493510).
1346     Dex2oatFileWrapper wrapper_fd(
1347             open_output_file(image_path.c_str(), true /*recreate*/, 0600 /*permissions*/),
1348             [image_path]() { unlink(image_path.c_str()); });
1349     if (wrapper_fd.get() < 0) {
1350         // Could not create application image file. Go on since we can compile without it.
1351         LOG(ERROR) << "installd could not create '" << image_path
1352                 << "' for image file during dexopt";
1353          // If we have a valid image file path but no image fd, explicitly erase the image file.
1354         if (unlink(image_path.c_str()) < 0) {
1355             if (errno != ENOENT) {
1356                 PLOG(ERROR) << "Couldn't unlink image file " << image_path;
1357             }
1358         }
1359     } else if (!set_permissions_and_ownership(
1360                 wrapper_fd.get(), is_public, uid, image_path.c_str(), is_secondary_dex)) {
1361         ALOGE("installd cannot set owner '%s' for image during dexopt\n", image_path.c_str());
1362         wrapper_fd.reset(-1);
1363     }
1364 
1365     return wrapper_fd;
1366 }
1367 
1368 // Creates the dexopt swap file if necessary and return its fd.
1369 // Returns -1 if there's no need for a swap or in case of errors.
maybe_open_dexopt_swap_file(const char * out_oat_path)1370 unique_fd maybe_open_dexopt_swap_file(const char* out_oat_path) {
1371     if (!ShouldUseSwapFileForDexopt()) {
1372         return invalid_unique_fd();
1373     }
1374     auto swap_file_name = std::string(out_oat_path) + ".swap";
1375     unique_fd swap_fd(open_output_file(
1376             swap_file_name.c_str(), /*recreate*/true, /*permissions*/0600));
1377     if (swap_fd.get() < 0) {
1378         // Could not create swap file. Optimistically go on and hope that we can compile
1379         // without it.
1380         ALOGE("installd could not create '%s' for swap during dexopt\n", swap_file_name.c_str());
1381     } else {
1382         // Immediately unlink. We don't really want to hit flash.
1383         if (unlink(swap_file_name.c_str()) < 0) {
1384             PLOG(ERROR) << "Couldn't unlink swap file " << swap_file_name;
1385         }
1386     }
1387     return swap_fd;
1388 }
1389 
1390 // Opens the reference profiles if needed.
1391 // Note that the reference profile might not exist so it's OK if the fd will be -1.
maybe_open_reference_profile(const std::string & pkgname,const std::string & dex_path,const char * profile_name,bool profile_guided,bool is_public,int uid,bool is_secondary_dex)1392 Dex2oatFileWrapper maybe_open_reference_profile(const std::string& pkgname,
1393         const std::string& dex_path, const char* profile_name, bool profile_guided,
1394         bool is_public, int uid, bool is_secondary_dex) {
1395     // If we are not profile guided compilation, or we are compiling system server
1396     // do not bother to open the profiles; we won't be using them.
1397     if (!profile_guided || (pkgname[0] == '*')) {
1398         return Dex2oatFileWrapper();
1399     }
1400 
1401     // If this is a secondary dex path which is public do not open the profile.
1402     // We cannot compile public secondary dex paths with profiles. That's because
1403     // it will expose how the dex files are used by their owner.
1404     //
1405     // Note that the PackageManager is responsible to set the is_public flag for
1406     // primary apks and we do not check it here. In some cases, e.g. when
1407     // compiling with a public profile from the .dm file the PackageManager will
1408     // set is_public toghether with the profile guided compilation.
1409     if (is_secondary_dex && is_public) {
1410         return Dex2oatFileWrapper();
1411     }
1412 
1413     // Open reference profile in read only mode as dex2oat does not get write permissions.
1414     std::string location;
1415     if (is_secondary_dex) {
1416         location = dex_path;
1417     } else {
1418         if (profile_name == nullptr) {
1419             // This path is taken for system server re-compilation lunched from ZygoteInit.
1420             return Dex2oatFileWrapper();
1421         } else {
1422             location = profile_name;
1423         }
1424     }
1425     unique_fd ufd = open_reference_profile(uid, pkgname, location, /*read_write*/false,
1426             is_secondary_dex);
1427     const auto& cleanup = [pkgname, location, is_secondary_dex]() {
1428         clear_reference_profile(pkgname, location, is_secondary_dex);
1429     };
1430     return Dex2oatFileWrapper(ufd.release(), cleanup);
1431 }
1432 
1433 // Opens the vdex files and assigns the input fd to in_vdex_wrapper_fd and the output fd to
1434 // out_vdex_wrapper_fd. Returns true for success or false in case of errors.
open_vdex_files_for_dex2oat(const char * apk_path,const char * out_oat_path,int dexopt_needed,const char * instruction_set,bool is_public,int uid,bool is_secondary_dex,bool profile_guided,Dex2oatFileWrapper * in_vdex_wrapper_fd,Dex2oatFileWrapper * out_vdex_wrapper_fd)1435 bool open_vdex_files_for_dex2oat(const char* apk_path, const char* out_oat_path, int dexopt_needed,
1436         const char* instruction_set, bool is_public, int uid, bool is_secondary_dex,
1437         bool profile_guided, Dex2oatFileWrapper* in_vdex_wrapper_fd,
1438         Dex2oatFileWrapper* out_vdex_wrapper_fd) {
1439     CHECK(in_vdex_wrapper_fd != nullptr);
1440     CHECK(out_vdex_wrapper_fd != nullptr);
1441     // Open the existing VDEX. We do this before creating the new output VDEX, which will
1442     // unlink the old one.
1443     char in_odex_path[PKG_PATH_MAX];
1444     int dexopt_action = abs(dexopt_needed);
1445     bool is_odex_location = dexopt_needed < 0;
1446     std::string in_vdex_path_str;
1447 
1448     // Infer the name of the output VDEX.
1449     const std::string out_vdex_path_str = create_vdex_filename(out_oat_path);
1450     if (out_vdex_path_str.empty()) {
1451         return false;
1452     }
1453 
1454     bool update_vdex_in_place = false;
1455     if (dexopt_action != DEX2OAT_FROM_SCRATCH) {
1456         // Open the possibly existing vdex. If none exist, we pass -1 to dex2oat for input-vdex-fd.
1457         const char* path = nullptr;
1458         if (is_odex_location) {
1459             if (calculate_odex_file_path(in_odex_path, apk_path, instruction_set)) {
1460                 path = in_odex_path;
1461             } else {
1462                 ALOGE("installd cannot compute input vdex location for '%s'\n", apk_path);
1463                 return false;
1464             }
1465         } else {
1466             path = out_oat_path;
1467         }
1468         in_vdex_path_str = create_vdex_filename(path);
1469         if (in_vdex_path_str.empty()) {
1470             ALOGE("installd cannot compute input vdex location for '%s'\n", path);
1471             return false;
1472         }
1473         // We can update in place when all these conditions are met:
1474         // 1) The vdex location to write to is the same as the vdex location to read (vdex files
1475         //    on /system typically cannot be updated in place).
1476         // 2) We dex2oat due to boot image change, because we then know the existing vdex file
1477         //    cannot be currently used by a running process.
1478         // 3) We are not doing a profile guided compilation, because dexlayout requires two
1479         //    different vdex files to operate.
1480         update_vdex_in_place =
1481             (in_vdex_path_str == out_vdex_path_str) &&
1482             (dexopt_action == DEX2OAT_FOR_BOOT_IMAGE) &&
1483             !profile_guided;
1484         if (update_vdex_in_place) {
1485             // Open the file read-write to be able to update it.
1486             in_vdex_wrapper_fd->reset(open(in_vdex_path_str.c_str(), O_RDWR, 0));
1487             if (in_vdex_wrapper_fd->get() == -1) {
1488                 // If we failed to open the file, we cannot update it in place.
1489                 update_vdex_in_place = false;
1490             }
1491         } else {
1492             in_vdex_wrapper_fd->reset(open(in_vdex_path_str.c_str(), O_RDONLY, 0));
1493         }
1494     }
1495 
1496     // If we are updating the vdex in place, we do not need to recreate a vdex,
1497     // and can use the same existing one.
1498     if (update_vdex_in_place) {
1499         // We unlink the file in case the invocation of dex2oat fails, to ensure we don't
1500         // have bogus stale vdex files.
1501         out_vdex_wrapper_fd->reset(
1502               in_vdex_wrapper_fd->get(),
1503               [out_vdex_path_str]() { unlink(out_vdex_path_str.c_str()); });
1504         // Disable auto close for the in wrapper fd (it will be done when destructing the out
1505         // wrapper).
1506         in_vdex_wrapper_fd->DisableAutoClose();
1507     } else {
1508         out_vdex_wrapper_fd->reset(
1509               open_output_file(out_vdex_path_str.c_str(), /*recreate*/true, /*permissions*/0644),
1510               [out_vdex_path_str]() { unlink(out_vdex_path_str.c_str()); });
1511         if (out_vdex_wrapper_fd->get() < 0) {
1512             ALOGE("installd cannot open vdex'%s' during dexopt\n", out_vdex_path_str.c_str());
1513             return false;
1514         }
1515     }
1516     if (!set_permissions_and_ownership(out_vdex_wrapper_fd->get(), is_public, uid,
1517             out_vdex_path_str.c_str(), is_secondary_dex)) {
1518         ALOGE("installd cannot set owner '%s' for vdex during dexopt\n", out_vdex_path_str.c_str());
1519         return false;
1520     }
1521 
1522     // If we got here we successfully opened the vdex files.
1523     return true;
1524 }
1525 
1526 // Opens the output oat file for the given apk.
1527 // If successful it stores the output path into out_oat_path and returns true.
open_oat_out_file(const char * apk_path,const char * oat_dir,bool is_public,int uid,const char * instruction_set,bool is_secondary_dex,char * out_oat_path)1528 Dex2oatFileWrapper open_oat_out_file(const char* apk_path, const char* oat_dir,
1529         bool is_public, int uid, const char* instruction_set, bool is_secondary_dex,
1530         char* out_oat_path) {
1531     if (!create_oat_out_path(apk_path, instruction_set, oat_dir, is_secondary_dex, out_oat_path)) {
1532         return Dex2oatFileWrapper();
1533     }
1534     const std::string out_oat_path_str(out_oat_path);
1535     Dex2oatFileWrapper wrapper_fd(
1536             open_output_file(out_oat_path, /*recreate*/true, /*permissions*/0644),
1537             [out_oat_path_str]() { unlink(out_oat_path_str.c_str()); });
1538     if (wrapper_fd.get() < 0) {
1539         PLOG(ERROR) << "installd cannot open output during dexopt" <<  out_oat_path;
1540     } else if (!set_permissions_and_ownership(
1541                 wrapper_fd.get(), is_public, uid, out_oat_path, is_secondary_dex)) {
1542         ALOGE("installd cannot set owner '%s' for output during dexopt\n", out_oat_path);
1543         wrapper_fd.reset(-1);
1544     }
1545     return wrapper_fd;
1546 }
1547 
1548 // Creates RDONLY fds for oat and vdex files, if exist.
1549 // Returns false if it fails to create oat out path for the given apk path.
1550 // Note that the method returns true even if the files could not be opened.
maybe_open_oat_and_vdex_file(const std::string & apk_path,const std::string & oat_dir,const std::string & instruction_set,bool is_secondary_dex,unique_fd * oat_file_fd,unique_fd * vdex_file_fd)1551 bool maybe_open_oat_and_vdex_file(const std::string& apk_path,
1552                                   const std::string& oat_dir,
1553                                   const std::string& instruction_set,
1554                                   bool is_secondary_dex,
1555                                   unique_fd* oat_file_fd,
1556                                   unique_fd* vdex_file_fd) {
1557     char oat_path[PKG_PATH_MAX];
1558     if (!create_oat_out_path(apk_path.c_str(),
1559                              instruction_set.c_str(),
1560                              oat_dir.c_str(),
1561                              is_secondary_dex,
1562                              oat_path)) {
1563         LOG(ERROR) << "Could not create oat out path for "
1564                 << apk_path << " with oat dir " << oat_dir;
1565         return false;
1566     }
1567     oat_file_fd->reset(open(oat_path, O_RDONLY));
1568     if (oat_file_fd->get() < 0) {
1569         PLOG(INFO) << "installd cannot open oat file during dexopt" <<  oat_path;
1570     }
1571 
1572     std::string vdex_filename = create_vdex_filename(oat_path);
1573     vdex_file_fd->reset(open(vdex_filename.c_str(), O_RDONLY));
1574     if (vdex_file_fd->get() < 0) {
1575         PLOG(INFO) << "installd cannot open vdex file during dexopt" <<  vdex_filename;
1576     }
1577 
1578     return true;
1579 }
1580 
1581 // Updates the access times of out_oat_path based on those from apk_path.
update_out_oat_access_times(const char * apk_path,const char * out_oat_path)1582 void update_out_oat_access_times(const char* apk_path, const char* out_oat_path) {
1583     struct stat input_stat;
1584     memset(&input_stat, 0, sizeof(input_stat));
1585     if (stat(apk_path, &input_stat) != 0) {
1586         PLOG(ERROR) << "Could not stat " << apk_path << " during dexopt";
1587         return;
1588     }
1589 
1590     struct utimbuf ut;
1591     ut.actime = input_stat.st_atime;
1592     ut.modtime = input_stat.st_mtime;
1593     if (utime(out_oat_path, &ut) != 0) {
1594         PLOG(WARNING) << "Could not update access times for " << apk_path << " during dexopt";
1595     }
1596 }
1597 
1598 // Runs (execv) dexoptanalyzer on the given arguments.
1599 // The analyzer will check if the dex_file needs to be (re)compiled to match the compiler_filter.
1600 // If this is for a profile guided compilation, profile_was_updated will tell whether or not
1601 // the profile has changed.
1602 class RunDexoptAnalyzer : public ExecVHelper {
1603  public:
RunDexoptAnalyzer(const std::string & dex_file,int vdex_fd,int oat_fd,int zip_fd,const std::string & instruction_set,const std::string & compiler_filter,bool profile_was_updated,bool downgrade,const char * class_loader_context,const std::string & class_loader_context_fds)1604     RunDexoptAnalyzer(const std::string& dex_file,
1605                       int vdex_fd,
1606                       int oat_fd,
1607                       int zip_fd,
1608                       const std::string& instruction_set,
1609                       const std::string& compiler_filter,
1610                       bool profile_was_updated,
1611                       bool downgrade,
1612                       const char* class_loader_context,
1613                       const std::string& class_loader_context_fds) {
1614         CHECK_GE(zip_fd, 0);
1615 
1616         // We always run the analyzer in the background job.
1617         const char* dexoptanalyzer_bin = select_execution_binary(
1618              kDexoptanalyzerPath, kDexoptanalyzerDebugPath, /*background_job_compile=*/ true);
1619 
1620         std::string dex_file_arg = "--dex-file=" + dex_file;
1621         std::string oat_fd_arg = "--oat-fd=" + std::to_string(oat_fd);
1622         std::string vdex_fd_arg = "--vdex-fd=" + std::to_string(vdex_fd);
1623         std::string zip_fd_arg = "--zip-fd=" + std::to_string(zip_fd);
1624         std::string isa_arg = "--isa=" + instruction_set;
1625         std::string compiler_filter_arg = "--compiler-filter=" + compiler_filter;
1626         const char* assume_profile_changed = "--assume-profile-changed";
1627         const char* downgrade_flag = "--downgrade";
1628         std::string class_loader_context_arg = "--class-loader-context=";
1629         if (class_loader_context != nullptr) {
1630             class_loader_context_arg += class_loader_context;
1631         }
1632         std::string class_loader_context_fds_arg = "--class-loader-context-fds=";
1633         if (!class_loader_context_fds.empty()) {
1634             class_loader_context_fds_arg += class_loader_context_fds;
1635         }
1636 
1637         // program name, dex file, isa, filter
1638         AddArg(dex_file_arg);
1639         AddArg(isa_arg);
1640         AddArg(compiler_filter_arg);
1641         if (oat_fd >= 0) {
1642             AddArg(oat_fd_arg);
1643         }
1644         if (vdex_fd >= 0) {
1645             AddArg(vdex_fd_arg);
1646         }
1647         AddArg(zip_fd_arg);
1648         if (profile_was_updated) {
1649             AddArg(assume_profile_changed);
1650         }
1651         if (downgrade) {
1652             AddArg(downgrade_flag);
1653         }
1654         if (class_loader_context != nullptr) {
1655             AddArg(class_loader_context_arg);
1656             if (!class_loader_context_fds.empty()) {
1657                 AddArg(class_loader_context_fds_arg);
1658             }
1659         }
1660 
1661         PrepareArgs(dexoptanalyzer_bin);
1662     }
1663 
1664     // Dexoptanalyzer mode which flattens the given class loader context and
1665     // prints a list of its dex files in that flattened order.
RunDexoptAnalyzer(const char * class_loader_context)1666     RunDexoptAnalyzer(const char* class_loader_context) {
1667         CHECK(class_loader_context != nullptr);
1668 
1669         // We always run the analyzer in the background job.
1670         const char* dexoptanalyzer_bin = select_execution_binary(
1671              kDexoptanalyzerPath, kDexoptanalyzerDebugPath, /*background_job_compile=*/ true);
1672 
1673         AddArg("--flatten-class-loader-context");
1674         AddArg(std::string("--class-loader-context=") + class_loader_context);
1675         PrepareArgs(dexoptanalyzer_bin);
1676     }
1677 };
1678 
1679 // Prepares the oat dir for the secondary dex files.
prepare_secondary_dex_oat_dir(const std::string & dex_path,int uid,const char * instruction_set)1680 static bool prepare_secondary_dex_oat_dir(const std::string& dex_path, int uid,
1681         const char* instruction_set) {
1682     unsigned long dirIndex = dex_path.rfind('/');
1683     if (dirIndex == std::string::npos) {
1684         LOG(ERROR ) << "Unexpected dir structure for secondary dex " << dex_path;
1685         return false;
1686     }
1687     std::string dex_dir = dex_path.substr(0, dirIndex);
1688 
1689     // Create oat file output directory.
1690     mode_t oat_dir_mode = S_IRWXU | S_IRWXG | S_IXOTH;
1691     if (prepare_app_cache_dir(dex_dir, "oat", oat_dir_mode, uid, uid) != 0) {
1692         LOG(ERROR) << "Could not prepare oat dir for secondary dex: " << dex_path;
1693         return false;
1694     }
1695 
1696     char oat_dir[PKG_PATH_MAX];
1697     snprintf(oat_dir, PKG_PATH_MAX, "%s/oat", dex_dir.c_str());
1698 
1699     if (prepare_app_cache_dir(oat_dir, instruction_set, oat_dir_mode, uid, uid) != 0) {
1700         LOG(ERROR) << "Could not prepare oat/isa dir for secondary dex: " << dex_path;
1701         return false;
1702     }
1703 
1704     return true;
1705 }
1706 
1707 // Return codes for identifying the reason why dexoptanalyzer was not invoked when processing
1708 // secondary dex files. This return codes are returned by the child process created for
1709 // analyzing secondary dex files in process_secondary_dex_dexopt.
1710 
1711 enum DexoptAnalyzerSkipCodes {
1712   // The dexoptanalyzer was not invoked because of validation or IO errors.
1713   // Specific errors are encoded in the name.
1714   kSecondaryDexDexoptAnalyzerSkippedValidatePath = 200,
1715   kSecondaryDexDexoptAnalyzerSkippedOpenZip = 201,
1716   kSecondaryDexDexoptAnalyzerSkippedPrepareDir = 202,
1717   kSecondaryDexDexoptAnalyzerSkippedOpenOutput = 203,
1718   kSecondaryDexDexoptAnalyzerSkippedFailExec = 204,
1719   // The dexoptanalyzer was not invoked because the dex file does not exist anymore.
1720   kSecondaryDexDexoptAnalyzerSkippedNoFile = 205,
1721 };
1722 
1723 // Verifies the result of analyzing secondary dex files from process_secondary_dex_dexopt.
1724 // If the result is valid returns true and sets dexopt_needed_out to a valid value.
1725 // Returns false for errors or unexpected result values.
1726 // The result is expected to be either one of SECONDARY_DEX_* codes or a valid exit code
1727 // of dexoptanalyzer.
process_secondary_dexoptanalyzer_result(const std::string & dex_path,int result,int * dexopt_needed_out,std::string * error_msg)1728 static bool process_secondary_dexoptanalyzer_result(const std::string& dex_path, int result,
1729             int* dexopt_needed_out, std::string* error_msg) {
1730     // The result values are defined in dexoptanalyzer.
1731     switch (result) {
1732         case 0:  // dexoptanalyzer: no_dexopt_needed
1733             *dexopt_needed_out = NO_DEXOPT_NEEDED; return true;
1734         case 1:  // dexoptanalyzer: dex2oat_from_scratch
1735             *dexopt_needed_out = DEX2OAT_FROM_SCRATCH; return true;
1736         case 4:  // dexoptanalyzer: dex2oat_for_bootimage_odex
1737             *dexopt_needed_out = -DEX2OAT_FOR_BOOT_IMAGE; return true;
1738         case 5:  // dexoptanalyzer: dex2oat_for_filter_odex
1739             *dexopt_needed_out = -DEX2OAT_FOR_FILTER; return true;
1740         case 2:  // dexoptanalyzer: dex2oat_for_bootimage_oat
1741         case 3:  // dexoptanalyzer: dex2oat_for_filter_oat
1742             *error_msg = StringPrintf("Dexoptanalyzer return the status of an oat file."
1743                                       " Expected odex file status for secondary dex %s"
1744                                       " : dexoptanalyzer result=%d",
1745                                       dex_path.c_str(),
1746                                       result);
1747             return false;
1748     }
1749 
1750     // Use a second switch for enum switch-case analysis.
1751     switch (static_cast<DexoptAnalyzerSkipCodes>(result)) {
1752         case kSecondaryDexDexoptAnalyzerSkippedNoFile:
1753             // If the file does not exist there's no need for dexopt.
1754             *dexopt_needed_out = NO_DEXOPT_NEEDED;
1755             return true;
1756 
1757         case kSecondaryDexDexoptAnalyzerSkippedValidatePath:
1758             *error_msg = "Dexoptanalyzer path validation failed";
1759             return false;
1760         case kSecondaryDexDexoptAnalyzerSkippedOpenZip:
1761             *error_msg = "Dexoptanalyzer open zip failed";
1762             return false;
1763         case kSecondaryDexDexoptAnalyzerSkippedPrepareDir:
1764             *error_msg = "Dexoptanalyzer dir preparation failed";
1765             return false;
1766         case kSecondaryDexDexoptAnalyzerSkippedOpenOutput:
1767             *error_msg = "Dexoptanalyzer open output failed";
1768             return false;
1769         case kSecondaryDexDexoptAnalyzerSkippedFailExec:
1770             *error_msg = "Dexoptanalyzer failed to execute";
1771             return false;
1772     }
1773 
1774     *error_msg = StringPrintf("Unexpected result from analyzing secondary dex %s result=%d",
1775                               dex_path.c_str(),
1776                               result);
1777     return false;
1778 }
1779 
1780 enum SecondaryDexAccess {
1781     kSecondaryDexAccessReadOk = 0,
1782     kSecondaryDexAccessDoesNotExist = 1,
1783     kSecondaryDexAccessPermissionError = 2,
1784     kSecondaryDexAccessIOError = 3
1785 };
1786 
check_secondary_dex_access(const std::string & dex_path)1787 static SecondaryDexAccess check_secondary_dex_access(const std::string& dex_path) {
1788     // Check if the path exists and can be read. If not, there's nothing to do.
1789     if (access(dex_path.c_str(), R_OK) == 0) {
1790         return kSecondaryDexAccessReadOk;
1791     } else {
1792         if (errno == ENOENT) {
1793             LOG(INFO) << "Secondary dex does not exist: " <<  dex_path;
1794             return kSecondaryDexAccessDoesNotExist;
1795         } else {
1796             PLOG(ERROR) << "Could not access secondary dex " << dex_path;
1797             return errno == EACCES
1798                 ? kSecondaryDexAccessPermissionError
1799                 : kSecondaryDexAccessIOError;
1800         }
1801     }
1802 }
1803 
is_file_public(const std::string & filename)1804 static bool is_file_public(const std::string& filename) {
1805     struct stat file_stat;
1806     if (stat(filename.c_str(), &file_stat) == 0) {
1807         return (file_stat.st_mode & S_IROTH) != 0;
1808     }
1809     return false;
1810 }
1811 
1812 // Create the oat file structure for the secondary dex 'dex_path' and assign
1813 // the individual path component to the 'out_' parameters.
create_secondary_dex_oat_layout(const std::string & dex_path,const std::string & isa,char * out_oat_dir,char * out_oat_isa_dir,char * out_oat_path,std::string * error_msg)1814 static bool create_secondary_dex_oat_layout(const std::string& dex_path, const std::string& isa,
1815         char* out_oat_dir, char* out_oat_isa_dir, char* out_oat_path, std::string* error_msg) {
1816     size_t dirIndex = dex_path.rfind('/');
1817     if (dirIndex == std::string::npos) {
1818         *error_msg = std::string("Unexpected dir structure for dex file ").append(dex_path);
1819         return false;
1820     }
1821     // TODO(calin): we have similar computations in at lest 3 other places
1822     // (InstalldNativeService, otapropt and dexopt). Unify them and get rid of snprintf by
1823     // using string append.
1824     std::string apk_dir = dex_path.substr(0, dirIndex);
1825     snprintf(out_oat_dir, PKG_PATH_MAX, "%s/oat", apk_dir.c_str());
1826     snprintf(out_oat_isa_dir, PKG_PATH_MAX, "%s/%s", out_oat_dir, isa.c_str());
1827 
1828     if (!create_oat_out_path(dex_path.c_str(), isa.c_str(), out_oat_dir,
1829             /*is_secondary_dex*/true, out_oat_path)) {
1830         *error_msg = std::string("Could not create oat path for secondary dex ").append(dex_path);
1831         return false;
1832     }
1833     return true;
1834 }
1835 
1836 // Validate that the dexopt_flags contain a valid storage flag and convert that to an installd
1837 // recognized storage flags (FLAG_STORAGE_CE or FLAG_STORAGE_DE).
validate_dexopt_storage_flags(int dexopt_flags,int * out_storage_flag,std::string * error_msg)1838 static bool validate_dexopt_storage_flags(int dexopt_flags,
1839                                           int* out_storage_flag,
1840                                           std::string* error_msg) {
1841     if ((dexopt_flags & DEXOPT_STORAGE_CE) != 0) {
1842         *out_storage_flag = FLAG_STORAGE_CE;
1843         if ((dexopt_flags & DEXOPT_STORAGE_DE) != 0) {
1844             *error_msg = "Ambiguous secondary dex storage flag. Both, CE and DE, flags are set";
1845             return false;
1846         }
1847     } else if ((dexopt_flags & DEXOPT_STORAGE_DE) != 0) {
1848         *out_storage_flag = FLAG_STORAGE_DE;
1849     } else {
1850         *error_msg = "Secondary dex storage flag must be set";
1851         return false;
1852     }
1853     return true;
1854 }
1855 
get_class_loader_context_dex_paths(const char * class_loader_context,int uid,std::vector<std::string> * context_dex_paths)1856 static bool get_class_loader_context_dex_paths(const char* class_loader_context, int uid,
1857         /* out */ std::vector<std::string>* context_dex_paths) {
1858     if (class_loader_context == nullptr) {
1859       return true;
1860     }
1861 
1862     LOG(DEBUG) << "Getting dex paths for context " << class_loader_context;
1863 
1864     // Pipe to get the hash result back from our child process.
1865     unique_fd pipe_read, pipe_write;
1866     if (!Pipe(&pipe_read, &pipe_write)) {
1867         PLOG(ERROR) << "Failed to create pipe";
1868         return false;
1869     }
1870 
1871     pid_t pid = fork();
1872     if (pid == 0) {
1873         // child -- drop privileges before continuing.
1874         drop_capabilities(uid);
1875 
1876         // Route stdout to `pipe_write`
1877         while ((dup2(pipe_write, STDOUT_FILENO) == -1) && (errno == EINTR)) {}
1878         pipe_write.reset();
1879         pipe_read.reset();
1880 
1881         RunDexoptAnalyzer run_dexopt_analyzer(class_loader_context);
1882         run_dexopt_analyzer.Exec(kSecondaryDexDexoptAnalyzerSkippedFailExec);
1883     }
1884 
1885     /* parent */
1886     pipe_write.reset();
1887 
1888     std::string str_dex_paths;
1889     if (!ReadFdToString(pipe_read, &str_dex_paths)) {
1890         PLOG(ERROR) << "Failed to read from pipe";
1891         return false;
1892     }
1893     pipe_read.reset();
1894 
1895     int return_code = wait_child(pid);
1896     if (!WIFEXITED(return_code)) {
1897         PLOG(ERROR) << "Error waiting for child dexoptanalyzer process";
1898         return false;
1899     }
1900 
1901     constexpr int kFlattenClassLoaderContextSuccess = 50;
1902     return_code = WEXITSTATUS(return_code);
1903     if (return_code != kFlattenClassLoaderContextSuccess) {
1904         LOG(ERROR) << "Dexoptanalyzer could not flatten class loader context, code=" << return_code;
1905         return false;
1906     }
1907 
1908     if (!str_dex_paths.empty()) {
1909         *context_dex_paths = android::base::Split(str_dex_paths, ":");
1910     }
1911     return true;
1912 }
1913 
open_dex_paths(const std::vector<std::string> & dex_paths,std::vector<unique_fd> * zip_fds,std::string * error_msg)1914 static int open_dex_paths(const std::vector<std::string>& dex_paths,
1915         /* out */ std::vector<unique_fd>* zip_fds, /* out */ std::string* error_msg) {
1916     for (const std::string& dex_path : dex_paths) {
1917         zip_fds->emplace_back(open(dex_path.c_str(), O_RDONLY));
1918         if (zip_fds->back().get() < 0) {
1919             *error_msg = StringPrintf(
1920                     "installd cannot open '%s' for input during dexopt", dex_path.c_str());
1921             if (errno == ENOENT) {
1922                 return kSecondaryDexDexoptAnalyzerSkippedNoFile;
1923             } else {
1924                 return kSecondaryDexDexoptAnalyzerSkippedOpenZip;
1925             }
1926         }
1927     }
1928     return 0;
1929 }
1930 
join_fds(const std::vector<unique_fd> & fds)1931 static std::string join_fds(const std::vector<unique_fd>& fds) {
1932     std::stringstream ss;
1933     bool is_first = true;
1934     for (const unique_fd& fd : fds) {
1935         if (is_first) {
1936             is_first = false;
1937         } else {
1938             ss << ":";
1939         }
1940         ss << fd.get();
1941     }
1942     return ss.str();
1943 }
1944 
1945 // Processes the dex_path as a secondary dex files and return true if the path dex file should
1946 // be compiled. Returns false for errors (logged) or true if the secondary dex path was process
1947 // successfully.
1948 // When returning true, the output parameters will be:
1949 //   - is_public_out: whether or not the oat file should not be made public
1950 //   - dexopt_needed_out: valid OatFileAsssitant::DexOptNeeded
1951 //   - oat_dir_out: the oat dir path where the oat file should be stored
process_secondary_dex_dexopt(const std::string & dex_path,const char * pkgname,int dexopt_flags,const char * volume_uuid,int uid,const char * instruction_set,const char * compiler_filter,bool * is_public_out,int * dexopt_needed_out,std::string * oat_dir_out,bool downgrade,const char * class_loader_context,const std::vector<std::string> & context_dex_paths,std::string * error_msg)1952 static bool process_secondary_dex_dexopt(const std::string& dex_path, const char* pkgname,
1953         int dexopt_flags, const char* volume_uuid, int uid, const char* instruction_set,
1954         const char* compiler_filter, bool* is_public_out, int* dexopt_needed_out,
1955         std::string* oat_dir_out, bool downgrade, const char* class_loader_context,
1956         const std::vector<std::string>& context_dex_paths, /* out */ std::string* error_msg) {
1957     LOG(DEBUG) << "Processing secondary dex path " << dex_path;
1958     int storage_flag;
1959     if (!validate_dexopt_storage_flags(dexopt_flags, &storage_flag, error_msg)) {
1960         LOG(ERROR) << *error_msg;
1961         return false;
1962     }
1963     // Compute the oat dir as it's not easy to extract it from the child computation.
1964     char oat_path[PKG_PATH_MAX];
1965     char oat_dir[PKG_PATH_MAX];
1966     char oat_isa_dir[PKG_PATH_MAX];
1967     if (!create_secondary_dex_oat_layout(
1968             dex_path, instruction_set, oat_dir, oat_isa_dir, oat_path, error_msg)) {
1969         LOG(ERROR) << "Could not create secondary odex layout: " << *error_msg;
1970         return false;
1971     }
1972     oat_dir_out->assign(oat_dir);
1973 
1974     pid_t pid = fork();
1975     if (pid == 0) {
1976         // child -- drop privileges before continuing.
1977         drop_capabilities(uid);
1978 
1979         // Validate the path structure.
1980         if (!validate_secondary_dex_path(pkgname, dex_path, volume_uuid, uid, storage_flag)) {
1981             LOG(ERROR) << "Could not validate secondary dex path " << dex_path;
1982             _exit(kSecondaryDexDexoptAnalyzerSkippedValidatePath);
1983         }
1984 
1985         // Open the dex file.
1986         unique_fd zip_fd;
1987         zip_fd.reset(open(dex_path.c_str(), O_RDONLY));
1988         if (zip_fd.get() < 0) {
1989             if (errno == ENOENT) {
1990                 _exit(kSecondaryDexDexoptAnalyzerSkippedNoFile);
1991             } else {
1992                 _exit(kSecondaryDexDexoptAnalyzerSkippedOpenZip);
1993             }
1994         }
1995 
1996         // Open class loader context dex files.
1997         std::vector<unique_fd> context_zip_fds;
1998         int open_dex_paths_rc = open_dex_paths(context_dex_paths, &context_zip_fds, error_msg);
1999         if (open_dex_paths_rc != 0) {
2000             _exit(open_dex_paths_rc);
2001         }
2002 
2003         // Prepare the oat directories.
2004         if (!prepare_secondary_dex_oat_dir(dex_path, uid, instruction_set)) {
2005             _exit(kSecondaryDexDexoptAnalyzerSkippedPrepareDir);
2006         }
2007 
2008         // Open the vdex/oat files if any.
2009         unique_fd oat_file_fd;
2010         unique_fd vdex_file_fd;
2011         if (!maybe_open_oat_and_vdex_file(dex_path,
2012                                           *oat_dir_out,
2013                                           instruction_set,
2014                                           true /* is_secondary_dex */,
2015                                           &oat_file_fd,
2016                                           &vdex_file_fd)) {
2017             _exit(kSecondaryDexDexoptAnalyzerSkippedOpenOutput);
2018         }
2019 
2020         // Analyze profiles.
2021         bool profile_was_updated = analyze_profiles(uid, pkgname, dex_path,
2022                 /*is_secondary_dex*/true);
2023 
2024         // Run dexoptanalyzer to get dexopt_needed code. This is not expected to return.
2025         // Note that we do not do it before the fork since opening the files is required to happen
2026         // after forking.
2027         RunDexoptAnalyzer run_dexopt_analyzer(dex_path,
2028                                               vdex_file_fd.get(),
2029                                               oat_file_fd.get(),
2030                                               zip_fd.get(),
2031                                               instruction_set,
2032                                               compiler_filter, profile_was_updated,
2033                                               downgrade,
2034                                               class_loader_context,
2035                                               join_fds(context_zip_fds));
2036         run_dexopt_analyzer.Exec(kSecondaryDexDexoptAnalyzerSkippedFailExec);
2037     }
2038 
2039     /* parent */
2040     int result = wait_child(pid);
2041     if (!WIFEXITED(result)) {
2042         *error_msg = StringPrintf("dexoptanalyzer failed for path %s: 0x%04x",
2043                                   dex_path.c_str(),
2044                                   result);
2045         LOG(ERROR) << *error_msg;
2046         return false;
2047     }
2048     result = WEXITSTATUS(result);
2049     // Check that we successfully executed dexoptanalyzer.
2050     bool success = process_secondary_dexoptanalyzer_result(dex_path,
2051                                                            result,
2052                                                            dexopt_needed_out,
2053                                                            error_msg);
2054     if (!success) {
2055         LOG(ERROR) << *error_msg;
2056     }
2057 
2058     LOG(DEBUG) << "Processed secondary dex file " << dex_path << " result=" << result;
2059 
2060     // Run dexopt only if needed or forced.
2061     // Note that dexoptanalyzer is executed even if force compilation is enabled (because it
2062     // makes the code simpler; force compilation is only needed during tests).
2063     if (success &&
2064         (result != kSecondaryDexDexoptAnalyzerSkippedNoFile) &&
2065         ((dexopt_flags & DEXOPT_FORCE) != 0)) {
2066         *dexopt_needed_out = DEX2OAT_FROM_SCRATCH;
2067     }
2068 
2069     // Check if we should make the oat file public.
2070     // Note that if the dex file is not public the compiled code cannot be made public.
2071     // It is ok to check this flag outside in the parent process.
2072     *is_public_out = ((dexopt_flags & DEXOPT_PUBLIC) != 0) && is_file_public(dex_path);
2073 
2074     return success;
2075 }
2076 
format_dexopt_error(int status,const char * dex_path)2077 static std::string format_dexopt_error(int status, const char* dex_path) {
2078   if (WIFEXITED(status)) {
2079     int int_code = WEXITSTATUS(status);
2080     const char* code_name = get_return_code_name(static_cast<DexoptReturnCodes>(int_code));
2081     if (code_name != nullptr) {
2082       return StringPrintf("Dex2oat invocation for %s failed: %s", dex_path, code_name);
2083     }
2084   }
2085   return StringPrintf("Dex2oat invocation for %s failed with 0x%04x", dex_path, status);
2086 }
2087 
dexopt(const char * dex_path,uid_t uid,const char * pkgname,const char * instruction_set,int dexopt_needed,const char * oat_dir,int dexopt_flags,const char * compiler_filter,const char * volume_uuid,const char * class_loader_context,const char * se_info,bool downgrade,int target_sdk_version,const char * profile_name,const char * dex_metadata_path,const char * compilation_reason,std::string * error_msg)2088 int dexopt(const char* dex_path, uid_t uid, const char* pkgname, const char* instruction_set,
2089         int dexopt_needed, const char* oat_dir, int dexopt_flags, const char* compiler_filter,
2090         const char* volume_uuid, const char* class_loader_context, const char* se_info,
2091         bool downgrade, int target_sdk_version, const char* profile_name,
2092         const char* dex_metadata_path, const char* compilation_reason, std::string* error_msg) {
2093     CHECK(pkgname != nullptr);
2094     CHECK(pkgname[0] != 0);
2095     CHECK(error_msg != nullptr);
2096     CHECK_EQ(dexopt_flags & ~DEXOPT_MASK, 0)
2097         << "dexopt flags contains unknown fields: " << dexopt_flags;
2098 
2099     if (!validate_dex_path_size(dex_path)) {
2100         *error_msg = StringPrintf("Failed to validate %s", dex_path);
2101         return -1;
2102     }
2103 
2104     if (class_loader_context != nullptr && strlen(class_loader_context) > PKG_PATH_MAX) {
2105         *error_msg = StringPrintf("Class loader context exceeds the allowed size: %s",
2106                                   class_loader_context);
2107         LOG(ERROR) << *error_msg;
2108         return -1;
2109     }
2110 
2111     bool is_public = (dexopt_flags & DEXOPT_PUBLIC) != 0;
2112     bool debuggable = (dexopt_flags & DEXOPT_DEBUGGABLE) != 0;
2113     bool boot_complete = (dexopt_flags & DEXOPT_BOOTCOMPLETE) != 0;
2114     bool profile_guided = (dexopt_flags & DEXOPT_PROFILE_GUIDED) != 0;
2115     bool is_secondary_dex = (dexopt_flags & DEXOPT_SECONDARY_DEX) != 0;
2116     bool background_job_compile = (dexopt_flags & DEXOPT_IDLE_BACKGROUND_JOB) != 0;
2117     bool enable_hidden_api_checks = (dexopt_flags & DEXOPT_ENABLE_HIDDEN_API_CHECKS) != 0;
2118     bool generate_compact_dex = (dexopt_flags & DEXOPT_GENERATE_COMPACT_DEX) != 0;
2119     bool generate_app_image = (dexopt_flags & DEXOPT_GENERATE_APP_IMAGE) != 0;
2120     bool for_restore = (dexopt_flags & DEXOPT_FOR_RESTORE) != 0;
2121 
2122     // Check if we're dealing with a secondary dex file and if we need to compile it.
2123     std::string oat_dir_str;
2124     std::vector<std::string> context_dex_paths;
2125     if (is_secondary_dex) {
2126         if (!get_class_loader_context_dex_paths(class_loader_context, uid, &context_dex_paths)) {
2127             *error_msg = "Failed acquiring context dex paths";
2128             return -1;  // We had an error, logged in the process method.
2129         }
2130 
2131         if (process_secondary_dex_dexopt(dex_path, pkgname, dexopt_flags, volume_uuid, uid,
2132                 instruction_set, compiler_filter, &is_public, &dexopt_needed, &oat_dir_str,
2133                 downgrade, class_loader_context, context_dex_paths, error_msg)) {
2134             oat_dir = oat_dir_str.c_str();
2135             if (dexopt_needed == NO_DEXOPT_NEEDED) {
2136                 return 0;  // Nothing to do, report success.
2137             }
2138         } else {
2139             if (error_msg->empty()) {  // TODO: Make this a CHECK.
2140                 *error_msg = "Failed processing secondary.";
2141             }
2142             return -1;  // We had an error, logged in the process method.
2143         }
2144     } else {
2145         // Currently these flags are only used for secondary dex files.
2146         // Verify that they are not set for primary apks.
2147         CHECK((dexopt_flags & DEXOPT_STORAGE_CE) == 0);
2148         CHECK((dexopt_flags & DEXOPT_STORAGE_DE) == 0);
2149     }
2150 
2151     // Open the input file.
2152     unique_fd input_fd(open(dex_path, O_RDONLY, 0));
2153     if (input_fd.get() < 0) {
2154         *error_msg = StringPrintf("installd cannot open '%s' for input during dexopt", dex_path);
2155         LOG(ERROR) << *error_msg;
2156         return -1;
2157     }
2158 
2159     // Open class loader context dex files.
2160     std::vector<unique_fd> context_input_fds;
2161     if (open_dex_paths(context_dex_paths, &context_input_fds, error_msg) != 0) {
2162         LOG(ERROR) << *error_msg;
2163         return -1;
2164     }
2165 
2166     // Create the output OAT file.
2167     char out_oat_path[PKG_PATH_MAX];
2168     Dex2oatFileWrapper out_oat_fd = open_oat_out_file(dex_path, oat_dir, is_public, uid,
2169             instruction_set, is_secondary_dex, out_oat_path);
2170     if (out_oat_fd.get() < 0) {
2171         *error_msg = "Could not open out oat file.";
2172         return -1;
2173     }
2174 
2175     // Open vdex files.
2176     Dex2oatFileWrapper in_vdex_fd;
2177     Dex2oatFileWrapper out_vdex_fd;
2178     if (!open_vdex_files_for_dex2oat(dex_path, out_oat_path, dexopt_needed, instruction_set,
2179             is_public, uid, is_secondary_dex, profile_guided, &in_vdex_fd, &out_vdex_fd)) {
2180         *error_msg = "Could not open vdex files.";
2181         return -1;
2182     }
2183 
2184     // Ensure that the oat dir and the compiler artifacts of secondary dex files have the correct
2185     // selinux context (we generate them on the fly during the dexopt invocation and they don't
2186     // fully inherit their parent context).
2187     // Note that for primary apk the oat files are created before, in a separate installd
2188     // call which also does the restorecon. TODO(calin): unify the paths.
2189     if (is_secondary_dex) {
2190         if (selinux_android_restorecon_pkgdir(oat_dir, se_info, uid,
2191                 SELINUX_ANDROID_RESTORECON_RECURSE)) {
2192             *error_msg = std::string("Failed to restorecon ").append(oat_dir);
2193             LOG(ERROR) << *error_msg;
2194             return -1;
2195         }
2196     }
2197 
2198     // Create a swap file if necessary.
2199     unique_fd swap_fd = maybe_open_dexopt_swap_file(out_oat_path);
2200 
2201     // Open the reference profile if needed.
2202     Dex2oatFileWrapper reference_profile_fd = maybe_open_reference_profile(
2203             pkgname, dex_path, profile_name, profile_guided, is_public, uid, is_secondary_dex);
2204 
2205     if (reference_profile_fd.get() == -1) {
2206         // We don't create an app image without reference profile since there is no speedup from
2207         // loading it in that case and instead will be a small overhead.
2208         generate_app_image = false;
2209     }
2210 
2211     // Create the app image file if needed.
2212     Dex2oatFileWrapper image_fd = maybe_open_app_image(
2213             out_oat_path, generate_app_image, is_public, uid, is_secondary_dex);
2214 
2215     unique_fd dex_metadata_fd;
2216     if (dex_metadata_path != nullptr) {
2217         dex_metadata_fd.reset(TEMP_FAILURE_RETRY(open(dex_metadata_path, O_RDONLY | O_NOFOLLOW)));
2218         if (dex_metadata_fd.get() < 0) {
2219             PLOG(ERROR) << "Failed to open dex metadata file " << dex_metadata_path;
2220         }
2221     }
2222 
2223     LOG(VERBOSE) << "DexInv: --- BEGIN '" << dex_path << "' ---";
2224 
2225     RunDex2Oat runner(input_fd.get(),
2226                       out_oat_fd.get(),
2227                       in_vdex_fd.get(),
2228                       out_vdex_fd.get(),
2229                       image_fd.get(),
2230                       dex_path,
2231                       out_oat_path,
2232                       swap_fd.get(),
2233                       instruction_set,
2234                       compiler_filter,
2235                       debuggable,
2236                       boot_complete,
2237                       for_restore,
2238                       background_job_compile,
2239                       reference_profile_fd.get(),
2240                       class_loader_context,
2241                       join_fds(context_input_fds),
2242                       target_sdk_version,
2243                       enable_hidden_api_checks,
2244                       generate_compact_dex,
2245                       dex_metadata_fd.get(),
2246                       compilation_reason);
2247 
2248     pid_t pid = fork();
2249     if (pid == 0) {
2250         /* child -- drop privileges before continuing */
2251         drop_capabilities(uid);
2252 
2253         SetDex2OatScheduling(boot_complete);
2254         if (flock(out_oat_fd.get(), LOCK_EX | LOCK_NB) != 0) {
2255             PLOG(ERROR) << "flock(" << out_oat_path << ") failed";
2256             _exit(DexoptReturnCodes::kFlock);
2257         }
2258 
2259         runner.Exec(DexoptReturnCodes::kDex2oatExec);
2260     } else {
2261         int res = wait_child(pid);
2262         if (res == 0) {
2263             LOG(VERBOSE) << "DexInv: --- END '" << dex_path << "' (success) ---";
2264         } else {
2265             LOG(VERBOSE) << "DexInv: --- END '" << dex_path << "' --- status=0x"
2266                          << std::hex << std::setw(4) << res << ", process failed";
2267             *error_msg = format_dexopt_error(res, dex_path);
2268             return res;
2269         }
2270     }
2271 
2272     update_out_oat_access_times(dex_path, out_oat_path);
2273 
2274     // We've been successful, don't delete output.
2275     out_oat_fd.SetCleanup(false);
2276     out_vdex_fd.SetCleanup(false);
2277     image_fd.SetCleanup(false);
2278     reference_profile_fd.SetCleanup(false);
2279 
2280     return 0;
2281 }
2282 
2283 // Try to remove the given directory. Log an error if the directory exists
2284 // and is empty but could not be removed.
rmdir_if_empty(const char * dir)2285 static bool rmdir_if_empty(const char* dir) {
2286     if (rmdir(dir) == 0) {
2287         return true;
2288     }
2289     if (errno == ENOENT || errno == ENOTEMPTY) {
2290         return true;
2291     }
2292     PLOG(ERROR) << "Failed to remove dir: " << dir;
2293     return false;
2294 }
2295 
2296 // Try to unlink the given file. Log an error if the file exists and could not
2297 // be unlinked.
unlink_if_exists(const std::string & file)2298 static bool unlink_if_exists(const std::string& file) {
2299     if (unlink(file.c_str()) == 0) {
2300         return true;
2301     }
2302     if (errno == ENOENT) {
2303         return true;
2304 
2305     }
2306     PLOG(ERROR) << "Could not unlink: " << file;
2307     return false;
2308 }
2309 
2310 enum ReconcileSecondaryDexResult {
2311     kReconcileSecondaryDexExists = 0,
2312     kReconcileSecondaryDexCleanedUp = 1,
2313     kReconcileSecondaryDexValidationError = 2,
2314     kReconcileSecondaryDexCleanUpError = 3,
2315     kReconcileSecondaryDexAccessIOError = 4,
2316 };
2317 
2318 // Reconcile the secondary dex 'dex_path' and its generated oat files.
2319 // Return true if all the parameters are valid and the secondary dex file was
2320 //   processed successfully (i.e. the dex_path either exists, or if not, its corresponding
2321 //   oat/vdex/art files where deleted successfully). In this case, out_secondary_dex_exists
2322 //   will be true if the secondary dex file still exists. If the secondary dex file does not exist,
2323 //   the method cleans up any previously generated compiler artifacts (oat, vdex, art).
2324 // Return false if there were errors during processing. In this case
2325 //   out_secondary_dex_exists will be set to false.
reconcile_secondary_dex_file(const std::string & dex_path,const std::string & pkgname,int uid,const std::vector<std::string> & isas,const std::optional<std::string> & volume_uuid,int storage_flag,bool * out_secondary_dex_exists)2326 bool reconcile_secondary_dex_file(const std::string& dex_path,
2327         const std::string& pkgname, int uid, const std::vector<std::string>& isas,
2328         const std::optional<std::string>& volume_uuid, int storage_flag,
2329         /*out*/bool* out_secondary_dex_exists) {
2330     *out_secondary_dex_exists = false;  // start by assuming the file does not exist.
2331     if (isas.size() == 0) {
2332         LOG(ERROR) << "reconcile_secondary_dex_file called with empty isas vector";
2333         return false;
2334     }
2335 
2336     if (storage_flag != FLAG_STORAGE_CE && storage_flag != FLAG_STORAGE_DE) {
2337         LOG(ERROR) << "reconcile_secondary_dex_file called with invalid storage_flag: "
2338                 << storage_flag;
2339         return false;
2340     }
2341 
2342     // As a security measure we want to unlink art artifacts with the reduced capabilities
2343     // of the package user id. So we fork and drop capabilities in the child.
2344     pid_t pid = fork();
2345     if (pid == 0) {
2346         /* child -- drop privileges before continuing */
2347         drop_capabilities(uid);
2348 
2349         const char* volume_uuid_cstr = volume_uuid ? volume_uuid->c_str() : nullptr;
2350         if (!validate_secondary_dex_path(pkgname, dex_path, volume_uuid_cstr,
2351                 uid, storage_flag)) {
2352             LOG(ERROR) << "Could not validate secondary dex path " << dex_path;
2353             _exit(kReconcileSecondaryDexValidationError);
2354         }
2355 
2356         SecondaryDexAccess access_check = check_secondary_dex_access(dex_path);
2357         switch (access_check) {
2358             case kSecondaryDexAccessDoesNotExist:
2359                  // File does not exist. Proceed with cleaning.
2360                 break;
2361             case kSecondaryDexAccessReadOk: _exit(kReconcileSecondaryDexExists);
2362             case kSecondaryDexAccessIOError: _exit(kReconcileSecondaryDexAccessIOError);
2363             case kSecondaryDexAccessPermissionError: _exit(kReconcileSecondaryDexValidationError);
2364             default:
2365                 LOG(ERROR) << "Unexpected result from check_secondary_dex_access: " << access_check;
2366                 _exit(kReconcileSecondaryDexValidationError);
2367         }
2368 
2369         // The secondary dex does not exist anymore or it's. Clear any generated files.
2370         char oat_path[PKG_PATH_MAX];
2371         char oat_dir[PKG_PATH_MAX];
2372         char oat_isa_dir[PKG_PATH_MAX];
2373         bool result = true;
2374         for (size_t i = 0; i < isas.size(); i++) {
2375             std::string error_msg;
2376             if (!create_secondary_dex_oat_layout(
2377                     dex_path,isas[i], oat_dir, oat_isa_dir, oat_path, &error_msg)) {
2378                 LOG(ERROR) << error_msg;
2379                 _exit(kReconcileSecondaryDexValidationError);
2380             }
2381 
2382             // Delete oat/vdex/art files.
2383             result = unlink_if_exists(oat_path) && result;
2384             result = unlink_if_exists(create_vdex_filename(oat_path)) && result;
2385             result = unlink_if_exists(create_image_filename(oat_path)) && result;
2386 
2387             // Delete profiles.
2388             std::string current_profile = create_current_profile_path(
2389                 multiuser_get_user_id(uid), pkgname, dex_path, /*is_secondary*/true);
2390             std::string reference_profile = create_reference_profile_path(
2391                 pkgname, dex_path, /*is_secondary*/true);
2392             result = unlink_if_exists(current_profile) && result;
2393             result = unlink_if_exists(reference_profile) && result;
2394 
2395             // We upgraded once the location of current profile for secondary dex files.
2396             // Check for any previous left-overs and remove them as well.
2397             std::string old_current_profile = dex_path + ".prof";
2398             result = unlink_if_exists(old_current_profile);
2399 
2400             // Try removing the directories as well, they might be empty.
2401             result = rmdir_if_empty(oat_isa_dir) && result;
2402             result = rmdir_if_empty(oat_dir) && result;
2403         }
2404         if (!result) {
2405             PLOG(ERROR) << "Failed to clean secondary dex artifacts for location " << dex_path;
2406         }
2407         _exit(result ? kReconcileSecondaryDexCleanedUp : kReconcileSecondaryDexAccessIOError);
2408     }
2409 
2410     int return_code = wait_child(pid);
2411     if (!WIFEXITED(return_code)) {
2412         LOG(WARNING) << "reconcile dex failed for location " << dex_path << ": " << return_code;
2413     } else {
2414         return_code = WEXITSTATUS(return_code);
2415     }
2416 
2417     LOG(DEBUG) << "Reconcile secondary dex path " << dex_path << " result=" << return_code;
2418 
2419     switch (return_code) {
2420         case kReconcileSecondaryDexCleanedUp:
2421         case kReconcileSecondaryDexValidationError:
2422             // If we couldn't validate assume the dex file does not exist.
2423             // This will purge the entry from the PM records.
2424             *out_secondary_dex_exists = false;
2425             return true;
2426         case kReconcileSecondaryDexExists:
2427             *out_secondary_dex_exists = true;
2428             return true;
2429         case kReconcileSecondaryDexAccessIOError:
2430             // We had an access IO error.
2431             // Return false so that we can try again.
2432             // The value of out_secondary_dex_exists does not matter in this case and by convention
2433             // is set to false.
2434             *out_secondary_dex_exists = false;
2435             return false;
2436         default:
2437             LOG(ERROR) << "Unexpected code from reconcile_secondary_dex_file: " << return_code;
2438             *out_secondary_dex_exists = false;
2439             return false;
2440     }
2441 }
2442 
2443 // Compute and return the hash (SHA-256) of the secondary dex file at dex_path.
2444 // Returns true if all parameters are valid and the hash successfully computed and stored in
2445 // out_secondary_dex_hash.
2446 // Also returns true with an empty hash if the file does not currently exist or is not accessible to
2447 // the app.
2448 // For any other errors (e.g. if any of the parameters are invalid) returns false.
hash_secondary_dex_file(const std::string & dex_path,const std::string & pkgname,int uid,const std::optional<std::string> & volume_uuid,int storage_flag,std::vector<uint8_t> * out_secondary_dex_hash)2449 bool hash_secondary_dex_file(const std::string& dex_path, const std::string& pkgname, int uid,
2450         const std::optional<std::string>& volume_uuid, int storage_flag,
2451         std::vector<uint8_t>* out_secondary_dex_hash) {
2452     out_secondary_dex_hash->clear();
2453 
2454     const char* volume_uuid_cstr = volume_uuid ? volume_uuid->c_str() : nullptr;
2455 
2456     if (storage_flag != FLAG_STORAGE_CE && storage_flag != FLAG_STORAGE_DE) {
2457         LOG(ERROR) << "hash_secondary_dex_file called with invalid storage_flag: "
2458                 << storage_flag;
2459         return false;
2460     }
2461 
2462     // Pipe to get the hash result back from our child process.
2463     unique_fd pipe_read, pipe_write;
2464     if (!Pipe(&pipe_read, &pipe_write)) {
2465         PLOG(ERROR) << "Failed to create pipe";
2466         return false;
2467     }
2468 
2469     // Fork so that actual access to the files is done in the app's own UID, to ensure we only
2470     // access data the app itself can access.
2471     pid_t pid = fork();
2472     if (pid == 0) {
2473         // child -- drop privileges before continuing
2474         drop_capabilities(uid);
2475         pipe_read.reset();
2476 
2477         if (!validate_secondary_dex_path(pkgname, dex_path, volume_uuid_cstr, uid, storage_flag)) {
2478             LOG(ERROR) << "Could not validate secondary dex path " << dex_path;
2479             _exit(DexoptReturnCodes::kHashValidatePath);
2480         }
2481 
2482         unique_fd fd(TEMP_FAILURE_RETRY(open(dex_path.c_str(), O_RDONLY | O_CLOEXEC | O_NOFOLLOW)));
2483         if (fd == -1) {
2484             if (errno == EACCES || errno == ENOENT) {
2485                 // Not treated as an error.
2486                 _exit(0);
2487             }
2488             PLOG(ERROR) << "Failed to open secondary dex " << dex_path;
2489             _exit(DexoptReturnCodes::kHashOpenPath);
2490         }
2491 
2492         SHA256_CTX ctx;
2493         SHA256_Init(&ctx);
2494 
2495         std::vector<uint8_t> buffer(65536);
2496         while (true) {
2497             ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd, buffer.data(), buffer.size()));
2498             if (bytes_read == 0) {
2499                 break;
2500             } else if (bytes_read == -1) {
2501                 PLOG(ERROR) << "Failed to read secondary dex " << dex_path;
2502                 _exit(DexoptReturnCodes::kHashReadDex);
2503             }
2504 
2505             SHA256_Update(&ctx, buffer.data(), bytes_read);
2506         }
2507 
2508         std::array<uint8_t, SHA256_DIGEST_LENGTH> hash;
2509         SHA256_Final(hash.data(), &ctx);
2510         if (!WriteFully(pipe_write, hash.data(), hash.size())) {
2511             _exit(DexoptReturnCodes::kHashWrite);
2512         }
2513 
2514         _exit(0);
2515     }
2516 
2517     // parent
2518     pipe_write.reset();
2519 
2520     out_secondary_dex_hash->resize(SHA256_DIGEST_LENGTH);
2521     if (!ReadFully(pipe_read, out_secondary_dex_hash->data(), out_secondary_dex_hash->size())) {
2522         out_secondary_dex_hash->clear();
2523     }
2524     return wait_child(pid) == 0;
2525 }
2526 
2527 // Helper for move_ab, so that we can have common failure-case cleanup.
unlink_and_rename(const char * from,const char * to)2528 static bool unlink_and_rename(const char* from, const char* to) {
2529     // Check whether "from" exists, and if so whether it's regular. If it is, unlink. Otherwise,
2530     // return a failure.
2531     struct stat s;
2532     if (stat(to, &s) == 0) {
2533         if (!S_ISREG(s.st_mode)) {
2534             LOG(ERROR) << from << " is not a regular file to replace for A/B.";
2535             return false;
2536         }
2537         if (unlink(to) != 0) {
2538             LOG(ERROR) << "Could not unlink " << to << " to move A/B.";
2539             return false;
2540         }
2541     } else {
2542         // This may be a permission problem. We could investigate the error code, but we'll just
2543         // let the rename failure do the work for us.
2544     }
2545 
2546     // Try to rename "to" to "from."
2547     if (rename(from, to) != 0) {
2548         PLOG(ERROR) << "Could not rename " << from << " to " << to;
2549         return false;
2550     }
2551     return true;
2552 }
2553 
2554 // Move/rename a B artifact (from) to an A artifact (to).
move_ab_path(const std::string & b_path,const std::string & a_path)2555 static bool move_ab_path(const std::string& b_path, const std::string& a_path) {
2556     // Check whether B exists.
2557     {
2558         struct stat s;
2559         if (stat(b_path.c_str(), &s) != 0) {
2560             // Silently ignore for now. The service calling this isn't smart enough to understand
2561             // lack of artifacts at the moment.
2562             return false;
2563         }
2564         if (!S_ISREG(s.st_mode)) {
2565             LOG(ERROR) << "A/B artifact " << b_path << " is not a regular file.";
2566             // Try to unlink, but swallow errors.
2567             unlink(b_path.c_str());
2568             return false;
2569         }
2570     }
2571 
2572     // Rename B to A.
2573     if (!unlink_and_rename(b_path.c_str(), a_path.c_str())) {
2574         // Delete the b_path so we don't try again (or fail earlier).
2575         if (unlink(b_path.c_str()) != 0) {
2576             PLOG(ERROR) << "Could not unlink " << b_path;
2577         }
2578 
2579         return false;
2580     }
2581 
2582     return true;
2583 }
2584 
move_ab(const char * apk_path,const char * instruction_set,const char * oat_dir)2585 bool move_ab(const char* apk_path, const char* instruction_set, const char* oat_dir) {
2586     // Get the current slot suffix. No suffix, no A/B.
2587     const std::string slot_suffix = GetProperty("ro.boot.slot_suffix", "");
2588     if (slot_suffix.empty()) {
2589         return false;
2590     }
2591 
2592     if (!ValidateTargetSlotSuffix(slot_suffix)) {
2593         LOG(ERROR) << "Target slot suffix not legal: " << slot_suffix;
2594         return false;
2595     }
2596 
2597     // Validate other inputs.
2598     if (validate_apk_path(apk_path) != 0) {
2599         LOG(ERROR) << "Invalid apk_path: " << apk_path;
2600         return false;
2601     }
2602     if (validate_apk_path(oat_dir) != 0) {
2603         LOG(ERROR) << "Invalid oat_dir: " << oat_dir;
2604         return false;
2605     }
2606 
2607     char a_path[PKG_PATH_MAX];
2608     if (!calculate_oat_file_path(a_path, oat_dir, apk_path, instruction_set)) {
2609         return false;
2610     }
2611     const std::string a_vdex_path = create_vdex_filename(a_path);
2612     const std::string a_image_path = create_image_filename(a_path);
2613 
2614     // B path = A path + slot suffix.
2615     const std::string b_path = StringPrintf("%s.%s", a_path, slot_suffix.c_str());
2616     const std::string b_vdex_path = StringPrintf("%s.%s", a_vdex_path.c_str(), slot_suffix.c_str());
2617     const std::string b_image_path = StringPrintf("%s.%s",
2618                                                   a_image_path.c_str(),
2619                                                   slot_suffix.c_str());
2620 
2621     bool success = true;
2622     if (move_ab_path(b_path, a_path)) {
2623         if (move_ab_path(b_vdex_path, a_vdex_path)) {
2624             // Note: we can live without an app image. As such, ignore failure to move the image file.
2625             //       If we decide to require the app image, or the app image being moved correctly,
2626             //       then change accordingly.
2627             constexpr bool kIgnoreAppImageFailure = true;
2628 
2629             if (!a_image_path.empty()) {
2630                 if (!move_ab_path(b_image_path, a_image_path)) {
2631                     unlink(a_image_path.c_str());
2632                     if (!kIgnoreAppImageFailure) {
2633                         success = false;
2634                     }
2635                 }
2636             }
2637         } else {
2638             // Cleanup: delete B image, ignore errors.
2639             unlink(b_image_path.c_str());
2640             success = false;
2641         }
2642     } else {
2643         // Cleanup: delete B image, ignore errors.
2644         unlink(b_vdex_path.c_str());
2645         unlink(b_image_path.c_str());
2646         success = false;
2647     }
2648     return success;
2649 }
2650 
delete_odex(const char * apk_path,const char * instruction_set,const char * oat_dir)2651 bool delete_odex(const char* apk_path, const char* instruction_set, const char* oat_dir) {
2652     // Delete the oat/odex file.
2653     char out_path[PKG_PATH_MAX];
2654     if (!create_oat_out_path(apk_path, instruction_set, oat_dir,
2655             /*is_secondary_dex*/false, out_path)) {
2656         return false;
2657     }
2658 
2659     // In case of a permission failure report the issue. Otherwise just print a warning.
2660     auto unlink_and_check = [](const char* path) -> bool {
2661         int result = unlink(path);
2662         if (result != 0) {
2663             if (errno == EACCES || errno == EPERM) {
2664                 PLOG(ERROR) << "Could not unlink " << path;
2665                 return false;
2666             }
2667             PLOG(WARNING) << "Could not unlink " << path;
2668         }
2669         return true;
2670     };
2671 
2672     // Delete the oat/odex file.
2673     bool return_value_oat = unlink_and_check(out_path);
2674 
2675     // Derive and delete the app image.
2676     bool return_value_art = unlink_and_check(create_image_filename(out_path).c_str());
2677 
2678     // Derive and delete the vdex file.
2679     bool return_value_vdex = unlink_and_check(create_vdex_filename(out_path).c_str());
2680 
2681     // Report success.
2682     return return_value_oat && return_value_art && return_value_vdex;
2683 }
2684 
is_absolute_path(const std::string & path)2685 static bool is_absolute_path(const std::string& path) {
2686     if (path.find('/') != 0 || path.find("..") != std::string::npos) {
2687         LOG(ERROR) << "Invalid absolute path " << path;
2688         return false;
2689     } else {
2690         return true;
2691     }
2692 }
2693 
is_valid_instruction_set(const std::string & instruction_set)2694 static bool is_valid_instruction_set(const std::string& instruction_set) {
2695     // TODO: add explicit whitelisting of instruction sets
2696     if (instruction_set.find('/') != std::string::npos) {
2697         LOG(ERROR) << "Invalid instruction set " << instruction_set;
2698         return false;
2699     } else {
2700         return true;
2701     }
2702 }
2703 
calculate_oat_file_path_default(char path[PKG_PATH_MAX],const char * oat_dir,const char * apk_path,const char * instruction_set)2704 bool calculate_oat_file_path_default(char path[PKG_PATH_MAX], const char *oat_dir,
2705         const char *apk_path, const char *instruction_set) {
2706     std::string oat_dir_ = oat_dir;
2707     std::string apk_path_ = apk_path;
2708     std::string instruction_set_ = instruction_set;
2709 
2710     if (!is_absolute_path(oat_dir_)) return false;
2711     if (!is_absolute_path(apk_path_)) return false;
2712     if (!is_valid_instruction_set(instruction_set_)) return false;
2713 
2714     std::string::size_type end = apk_path_.rfind('.');
2715     std::string::size_type start = apk_path_.rfind('/', end);
2716     if (end == std::string::npos || start == std::string::npos) {
2717         LOG(ERROR) << "Invalid apk_path " << apk_path_;
2718         return false;
2719     }
2720 
2721     std::string res_ = oat_dir_ + '/' + instruction_set + '/'
2722             + apk_path_.substr(start + 1, end - start - 1) + ".odex";
2723     const char* res = res_.c_str();
2724     if (strlen(res) >= PKG_PATH_MAX) {
2725         LOG(ERROR) << "Result too large";
2726         return false;
2727     } else {
2728         strlcpy(path, res, PKG_PATH_MAX);
2729         return true;
2730     }
2731 }
2732 
calculate_odex_file_path_default(char path[PKG_PATH_MAX],const char * apk_path,const char * instruction_set)2733 bool calculate_odex_file_path_default(char path[PKG_PATH_MAX], const char *apk_path,
2734         const char *instruction_set) {
2735     std::string apk_path_ = apk_path;
2736     std::string instruction_set_ = instruction_set;
2737 
2738     if (!is_absolute_path(apk_path_)) return false;
2739     if (!is_valid_instruction_set(instruction_set_)) return false;
2740 
2741     std::string::size_type end = apk_path_.rfind('.');
2742     std::string::size_type start = apk_path_.rfind('/', end);
2743     if (end == std::string::npos || start == std::string::npos) {
2744         LOG(ERROR) << "Invalid apk_path " << apk_path_;
2745         return false;
2746     }
2747 
2748     std::string oat_dir = apk_path_.substr(0, start + 1) + "oat";
2749     return calculate_oat_file_path_default(path, oat_dir.c_str(), apk_path, instruction_set);
2750 }
2751 
create_cache_path_default(char path[PKG_PATH_MAX],const char * src,const char * instruction_set)2752 bool create_cache_path_default(char path[PKG_PATH_MAX], const char *src,
2753         const char *instruction_set) {
2754     std::string src_ = src;
2755     std::string instruction_set_ = instruction_set;
2756 
2757     if (!is_absolute_path(src_)) return false;
2758     if (!is_valid_instruction_set(instruction_set_)) return false;
2759 
2760     for (auto it = src_.begin() + 1; it < src_.end(); ++it) {
2761         if (*it == '/') {
2762             *it = '@';
2763         }
2764     }
2765 
2766     std::string res_ = android_data_dir + DALVIK_CACHE + '/' + instruction_set_ + src_
2767             + DALVIK_CACHE_POSTFIX;
2768     const char* res = res_.c_str();
2769     if (strlen(res) >= PKG_PATH_MAX) {
2770         LOG(ERROR) << "Result too large";
2771         return false;
2772     } else {
2773         strlcpy(path, res, PKG_PATH_MAX);
2774         return true;
2775     }
2776 }
2777 
open_classpath_files(const std::string & classpath,std::vector<unique_fd> * apk_fds,std::vector<std::string> * dex_locations)2778 bool open_classpath_files(const std::string& classpath, std::vector<unique_fd>* apk_fds,
2779         std::vector<std::string>* dex_locations) {
2780     std::vector<std::string> classpaths_elems = base::Split(classpath, ":");
2781     for (const std::string& elem : classpaths_elems) {
2782         unique_fd fd(TEMP_FAILURE_RETRY(open(elem.c_str(), O_RDONLY)));
2783         if (fd < 0) {
2784             PLOG(ERROR) << "Could not open classpath elem " << elem;
2785             return false;
2786         } else {
2787             apk_fds->push_back(std::move(fd));
2788             dex_locations->push_back(elem);
2789         }
2790     }
2791     return true;
2792 }
2793 
create_app_profile_snapshot(int32_t app_id,const std::string & package_name,const std::string & profile_name,const std::string & classpath)2794 static bool create_app_profile_snapshot(int32_t app_id,
2795                                         const std::string& package_name,
2796                                         const std::string& profile_name,
2797                                         const std::string& classpath) {
2798     int app_shared_gid = multiuser_get_shared_gid(/*user_id*/ 0, app_id);
2799 
2800     unique_fd snapshot_fd = open_spnashot_profile(AID_SYSTEM, package_name, profile_name);
2801     if (snapshot_fd < 0) {
2802         return false;
2803     }
2804 
2805     std::vector<unique_fd> profiles_fd;
2806     unique_fd reference_profile_fd;
2807     open_profile_files(app_shared_gid, package_name, profile_name, /*is_secondary_dex*/ false,
2808             &profiles_fd, &reference_profile_fd);
2809     if (profiles_fd.empty() || (reference_profile_fd.get() < 0)) {
2810         return false;
2811     }
2812 
2813     profiles_fd.push_back(std::move(reference_profile_fd));
2814 
2815     // Open the class paths elements. These will be used to filter out profile data that does
2816     // not belong to the classpath during merge.
2817     std::vector<unique_fd> apk_fds;
2818     std::vector<std::string> dex_locations;
2819     if (!open_classpath_files(classpath, &apk_fds, &dex_locations)) {
2820         return false;
2821     }
2822 
2823     RunProfman args;
2824     // This is specifically a snapshot for an app, so don't use boot image profiles.
2825     args.SetupMerge(profiles_fd,
2826             snapshot_fd,
2827             apk_fds,
2828             dex_locations,
2829             /* for_snapshot= */ true,
2830             /* for_boot_image= */ false);
2831     pid_t pid = fork();
2832     if (pid == 0) {
2833         /* child -- drop privileges before continuing */
2834         drop_capabilities(app_shared_gid);
2835         args.Exec();
2836     }
2837 
2838     /* parent */
2839     int return_code = wait_child(pid);
2840     if (!WIFEXITED(return_code)) {
2841         LOG(WARNING) << "profman failed for " << package_name << ":" << profile_name;
2842         return false;
2843     }
2844 
2845     // Verify that profman finished successfully.
2846     int profman_code = WEXITSTATUS(return_code);
2847     if (profman_code != PROFMAN_BIN_RETURN_CODE_SUCCESS) {
2848         LOG(WARNING) << "profman error for " << package_name << ":" << profile_name
2849                 << ":" << profman_code;
2850         return false;
2851     }
2852     return true;
2853 }
2854 
create_boot_image_profile_snapshot(const std::string & package_name,const std::string & profile_name,const std::string & classpath)2855 static bool create_boot_image_profile_snapshot(const std::string& package_name,
2856                                                const std::string& profile_name,
2857                                                const std::string& classpath) {
2858     // The reference profile directory for the android package might not be prepared. Do it now.
2859     const std::string ref_profile_dir =
2860             create_primary_reference_profile_package_dir_path(package_name);
2861     if (fs_prepare_dir(ref_profile_dir.c_str(), 0770, AID_SYSTEM, AID_SYSTEM) != 0) {
2862         PLOG(ERROR) << "Failed to prepare " << ref_profile_dir;
2863         return false;
2864     }
2865 
2866     // Return false for empty class path since it may otherwise return true below if profiles is
2867     // empty.
2868     if (classpath.empty()) {
2869         PLOG(ERROR) << "Class path is empty";
2870         return false;
2871     }
2872 
2873     // Open and create the snapshot profile.
2874     unique_fd snapshot_fd = open_spnashot_profile(AID_SYSTEM, package_name, profile_name);
2875 
2876     // Collect all non empty profiles.
2877     // The collection will traverse all applications profiles and find the non empty files.
2878     // This has the potential of inspecting a large number of files and directories (depending
2879     // on the number of applications and users). So there is a slight increase in the chance
2880     // to get get occasionally I/O errors (e.g. for opening the file). When that happens do not
2881     // fail the snapshot and aggregate whatever profile we could open.
2882     //
2883     // The profile snapshot is a best effort based on available data it's ok if some data
2884     // from some apps is missing. It will be counter productive for the snapshot to fail
2885     // because we could not open or read some of the files.
2886     std::vector<std::string> profiles;
2887     if (!collect_profiles(&profiles)) {
2888         LOG(WARNING) << "There were errors while collecting the profiles for the boot image.";
2889     }
2890 
2891     // If we have no profiles return early.
2892     if (profiles.empty()) {
2893         return true;
2894     }
2895 
2896     // Open the classpath elements. These will be used to filter out profile data that does
2897     // not belong to the classpath during merge.
2898     std::vector<unique_fd> apk_fds;
2899     std::vector<std::string> dex_locations;
2900     if (!open_classpath_files(classpath, &apk_fds, &dex_locations)) {
2901         return false;
2902     }
2903 
2904     // If we could not open any files from the classpath return an error.
2905     if (apk_fds.empty()) {
2906         LOG(ERROR) << "Could not open any of the classpath elements.";
2907         return false;
2908     }
2909 
2910     // Aggregate the profiles in batches of kAggregationBatchSize.
2911     // We do this to avoid opening a huge a amount of files.
2912     static constexpr size_t kAggregationBatchSize = 10;
2913 
2914     for (size_t i = 0; i < profiles.size(); )  {
2915         std::vector<unique_fd> profiles_fd;
2916         for (size_t k = 0; k < kAggregationBatchSize && i < profiles.size(); k++, i++) {
2917             unique_fd fd = open_profile(AID_SYSTEM, profiles[i], O_RDONLY);
2918             if (fd.get() >= 0) {
2919                 profiles_fd.push_back(std::move(fd));
2920             }
2921         }
2922 
2923         // We aggregate (read & write) into the same fd multiple times in a row.
2924         // We need to reset the cursor every time to ensure we read the whole file every time.
2925         if (TEMP_FAILURE_RETRY(lseek(snapshot_fd, 0, SEEK_SET)) == static_cast<off_t>(-1)) {
2926             PLOG(ERROR) << "Cannot reset position for snapshot profile";
2927             return false;
2928         }
2929 
2930         RunProfman args;
2931         args.SetupMerge(profiles_fd,
2932                         snapshot_fd,
2933                         apk_fds,
2934                         dex_locations,
2935                         /*for_snapshot=*/true,
2936                         /*for_boot_image=*/true);
2937         pid_t pid = fork();
2938         if (pid == 0) {
2939             /* child -- drop privileges before continuing */
2940             drop_capabilities(AID_SYSTEM);
2941 
2942             // The introduction of new access flags into boot jars causes them to
2943             // fail dex file verification.
2944             args.Exec();
2945         }
2946 
2947         /* parent */
2948         int return_code = wait_child(pid);
2949 
2950         if (!WIFEXITED(return_code)) {
2951             PLOG(WARNING) << "profman failed for " << package_name << ":" << profile_name;
2952             return false;
2953         }
2954 
2955         // Verify that profman finished successfully.
2956         int profman_code = WEXITSTATUS(return_code);
2957         if (profman_code != PROFMAN_BIN_RETURN_CODE_SUCCESS) {
2958             LOG(WARNING) << "profman error for " << package_name << ":" << profile_name
2959                     << ":" << profman_code;
2960             return false;
2961         }
2962     }
2963 
2964     return true;
2965 }
2966 
create_profile_snapshot(int32_t app_id,const std::string & package_name,const std::string & profile_name,const std::string & classpath)2967 bool create_profile_snapshot(int32_t app_id, const std::string& package_name,
2968         const std::string& profile_name, const std::string& classpath) {
2969     if (app_id == -1) {
2970         return create_boot_image_profile_snapshot(package_name, profile_name, classpath);
2971     } else {
2972         return create_app_profile_snapshot(app_id, package_name, profile_name, classpath);
2973     }
2974 }
2975 
prepare_app_profile(const std::string & package_name,userid_t user_id,appid_t app_id,const std::string & profile_name,const std::string & code_path,const std::optional<std::string> & dex_metadata)2976 bool prepare_app_profile(const std::string& package_name,
2977                          userid_t user_id,
2978                          appid_t app_id,
2979                          const std::string& profile_name,
2980                          const std::string& code_path,
2981                          const std::optional<std::string>& dex_metadata) {
2982     // Prepare the current profile.
2983     std::string cur_profile  = create_current_profile_path(user_id, package_name, profile_name,
2984             /*is_secondary_dex*/ false);
2985     uid_t uid = multiuser_get_uid(user_id, app_id);
2986     if (fs_prepare_file_strict(cur_profile.c_str(), 0600, uid, uid) != 0) {
2987         PLOG(ERROR) << "Failed to prepare " << cur_profile;
2988         return false;
2989     }
2990 
2991     // Check if we need to install the profile from the dex metadata.
2992     if (!dex_metadata) {
2993         return true;
2994     }
2995 
2996     // We have a dex metdata. Merge the profile into the reference profile.
2997     unique_fd ref_profile_fd = open_reference_profile(uid, package_name, profile_name,
2998             /*read_write*/ true, /*is_secondary_dex*/ false);
2999     unique_fd dex_metadata_fd(TEMP_FAILURE_RETRY(
3000             open(dex_metadata->c_str(), O_RDONLY | O_NOFOLLOW)));
3001     unique_fd apk_fd(TEMP_FAILURE_RETRY(open(code_path.c_str(), O_RDONLY | O_NOFOLLOW)));
3002     if (apk_fd < 0) {
3003         PLOG(ERROR) << "Could not open code path " << code_path;
3004         return false;
3005     }
3006 
3007     RunProfman args;
3008     args.SetupCopyAndUpdate(std::move(dex_metadata_fd),
3009                             std::move(ref_profile_fd),
3010                             std::move(apk_fd),
3011                             code_path);
3012     pid_t pid = fork();
3013     if (pid == 0) {
3014         /* child -- drop privileges before continuing */
3015         gid_t app_shared_gid = multiuser_get_shared_gid(user_id, app_id);
3016         drop_capabilities(app_shared_gid);
3017 
3018         // The copy and update takes ownership over the fds.
3019         args.Exec();
3020     }
3021 
3022     /* parent */
3023     int return_code = wait_child(pid);
3024     if (!WIFEXITED(return_code)) {
3025         PLOG(WARNING) << "profman failed for " << package_name << ":" << profile_name;
3026         return false;
3027     }
3028     return true;
3029 }
3030 
3031 }  // namespace installd
3032 }  // namespace android
3033