dexopt.cpp revision 9014ca88a9412cb1a1168ae842f30f8783ea1e3d
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 "installed"
17
18#include <fcntl.h>
19#include <stdlib.h>
20#include <string.h>
21#include <sys/capability.h>
22#include <sys/file.h>
23#include <sys/stat.h>
24#include <sys/time.h>
25#include <sys/types.h>
26#include <sys/resource.h>
27#include <sys/wait.h>
28#include <unistd.h>
29
30#include <android-base/logging.h>
31#include <android-base/stringprintf.h>
32#include <android-base/strings.h>
33#include <android-base/unique_fd.h>
34#include <cutils/fs.h>
35#include <cutils/properties.h>
36#include <cutils/sched_policy.h>
37#include <log/log.h>               // TODO: Move everything to base/logging.
38#include <private/android_filesystem_config.h>
39#include <selinux/android.h>
40#include <system/thread_defs.h>
41
42#include "dexopt.h"
43#include "installd_deps.h"
44#include "otapreopt_utils.h"
45#include "utils.h"
46
47using android::base::StringPrintf;
48using android::base::EndsWith;
49using android::base::unique_fd;
50
51namespace android {
52namespace installd {
53
54// Deleter using free() for use with std::unique_ptr<>. See also UniqueCPtr<> below.
55struct FreeDelete {
56  // NOTE: Deleting a const object is valid but free() takes a non-const pointer.
57  void operator()(const void* ptr) const {
58    free(const_cast<void*>(ptr));
59  }
60};
61
62// Alias for std::unique_ptr<> that uses the C function free() to delete objects.
63template <typename T>
64using UniqueCPtr = std::unique_ptr<T, FreeDelete>;
65
66static unique_fd invalid_unique_fd() {
67    return unique_fd(-1);
68}
69
70static bool clear_profile(const std::string& profile) {
71    unique_fd ufd(open(profile.c_str(), O_WRONLY | O_NOFOLLOW | O_CLOEXEC));
72    if (ufd.get() < 0) {
73        if (errno != ENOENT) {
74            PLOG(WARNING) << "Could not open profile " << profile;
75            return false;
76        } else {
77            // Nothing to clear. That's ok.
78            return true;
79        }
80    }
81
82    if (flock(ufd.get(), LOCK_EX | LOCK_NB) != 0) {
83        if (errno != EWOULDBLOCK) {
84            PLOG(WARNING) << "Error locking profile " << profile;
85        }
86        // This implies that the app owning this profile is running
87        // (and has acquired the lock).
88        //
89        // If we can't acquire the lock bail out since clearing is useless anyway
90        // (the app will write again to the profile).
91        //
92        // Note:
93        // This does not impact the this is not an issue for the profiling correctness.
94        // In case this is needed because of an app upgrade, profiles will still be
95        // eventually cleared by the app itself due to checksum mismatch.
96        // If this is needed because profman advised, then keeping the data around
97        // until the next run is again not an issue.
98        //
99        // If the app attempts to acquire a lock while we've held one here,
100        // it will simply skip the current write cycle.
101        return false;
102    }
103
104    bool truncated = ftruncate(ufd.get(), 0) == 0;
105    if (!truncated) {
106        PLOG(WARNING) << "Could not truncate " << profile;
107    }
108    if (flock(ufd.get(), LOCK_UN) != 0) {
109        PLOG(WARNING) << "Error unlocking profile " << profile;
110    }
111    return truncated;
112}
113
114// Clear the reference profile for the given location.
115// The location is the package name for primary apks or the dex path for secondary dex files.
116static bool clear_reference_profile(const std::string& location, bool is_secondary_dex) {
117    return clear_profile(create_reference_profile_path(location, is_secondary_dex));
118}
119
120// Clear the reference profile for the given location.
121// The location is the package name for primary apks or the dex path for secondary dex files.
122static bool clear_current_profile(const std::string& pkgname, userid_t user,
123        bool is_secondary_dex) {
124    return clear_profile(create_current_profile_path(user, pkgname, is_secondary_dex));
125}
126
127// Clear the reference profile for the primary apk of the given package.
128bool clear_primary_reference_profile(const std::string& pkgname) {
129    return clear_reference_profile(pkgname, /*is_secondary_dex*/false);
130}
131
132// Clear all current profile for the primary apk of the given package.
133bool clear_primary_current_profiles(const std::string& pkgname) {
134    bool success = true;
135    // For secondary dex files, we don't really need the user but we use it for sanity checks.
136    std::vector<userid_t> users = get_known_users(/*volume_uuid*/ nullptr);
137    for (auto user : users) {
138        success &= clear_current_profile(pkgname, user, /*is_secondary_dex*/false);
139    }
140    return success;
141}
142
143// Clear the current profile for the primary apk of the given package and user.
144bool clear_primary_current_profile(const std::string& pkgname, userid_t user) {
145    return clear_current_profile(pkgname, user, /*is_secondary_dex*/false);
146}
147
148static int split_count(const char *str)
149{
150  char *ctx;
151  int count = 0;
152  char buf[kPropertyValueMax];
153
154  strncpy(buf, str, sizeof(buf));
155  char *pBuf = buf;
156
157  while(strtok_r(pBuf, " ", &ctx) != NULL) {
158    count++;
159    pBuf = NULL;
160  }
161
162  return count;
163}
164
165static int split(char *buf, const char **argv)
166{
167  char *ctx;
168  int count = 0;
169  char *tok;
170  char *pBuf = buf;
171
172  while((tok = strtok_r(pBuf, " ", &ctx)) != NULL) {
173    argv[count++] = tok;
174    pBuf = NULL;
175  }
176
177  return count;
178}
179
180static const char* get_location_from_path(const char* path) {
181    static constexpr char kLocationSeparator = '/';
182    const char *location = strrchr(path, kLocationSeparator);
183    if (location == NULL) {
184        return path;
185    } else {
186        // Skip the separator character.
187        return location + 1;
188    }
189}
190
191static void run_dex2oat(int zip_fd, int oat_fd, int input_vdex_fd, int output_vdex_fd, int image_fd,
192        const char* input_file_name, const char* output_file_name, int swap_fd,
193        const char* instruction_set, const char* compiler_filter, bool vm_safe_mode,
194        bool debuggable, bool post_bootcomplete, int profile_fd, const char* shared_libraries) {
195    static const unsigned int MAX_INSTRUCTION_SET_LEN = 7;
196
197    if (strlen(instruction_set) >= MAX_INSTRUCTION_SET_LEN) {
198        ALOGE("Instruction set %s longer than max length of %d",
199              instruction_set, MAX_INSTRUCTION_SET_LEN);
200        return;
201    }
202
203    // Get the relative path to the input file.
204    const char* relative_input_file_name = get_location_from_path(input_file_name);
205
206    char dex2oat_Xms_flag[kPropertyValueMax];
207    bool have_dex2oat_Xms_flag = get_property("dalvik.vm.dex2oat-Xms", dex2oat_Xms_flag, NULL) > 0;
208
209    char dex2oat_Xmx_flag[kPropertyValueMax];
210    bool have_dex2oat_Xmx_flag = get_property("dalvik.vm.dex2oat-Xmx", dex2oat_Xmx_flag, NULL) > 0;
211
212    char dex2oat_threads_buf[kPropertyValueMax];
213    bool have_dex2oat_threads_flag = get_property(post_bootcomplete
214                                                      ? "dalvik.vm.dex2oat-threads"
215                                                      : "dalvik.vm.boot-dex2oat-threads",
216                                                  dex2oat_threads_buf,
217                                                  NULL) > 0;
218    char dex2oat_threads_arg[kPropertyValueMax + 2];
219    if (have_dex2oat_threads_flag) {
220        sprintf(dex2oat_threads_arg, "-j%s", dex2oat_threads_buf);
221    }
222
223    char dex2oat_isa_features_key[kPropertyKeyMax];
224    sprintf(dex2oat_isa_features_key, "dalvik.vm.isa.%s.features", instruction_set);
225    char dex2oat_isa_features[kPropertyValueMax];
226    bool have_dex2oat_isa_features = get_property(dex2oat_isa_features_key,
227                                                  dex2oat_isa_features, NULL) > 0;
228
229    char dex2oat_isa_variant_key[kPropertyKeyMax];
230    sprintf(dex2oat_isa_variant_key, "dalvik.vm.isa.%s.variant", instruction_set);
231    char dex2oat_isa_variant[kPropertyValueMax];
232    bool have_dex2oat_isa_variant = get_property(dex2oat_isa_variant_key,
233                                                 dex2oat_isa_variant, NULL) > 0;
234
235    const char *dex2oat_norelocation = "-Xnorelocate";
236    bool have_dex2oat_relocation_skip_flag = false;
237
238    char dex2oat_flags[kPropertyValueMax];
239    int dex2oat_flags_count = get_property("dalvik.vm.dex2oat-flags",
240                                 dex2oat_flags, NULL) <= 0 ? 0 : split_count(dex2oat_flags);
241    ALOGV("dalvik.vm.dex2oat-flags=%s\n", dex2oat_flags);
242
243    // If we booting without the real /data, don't spend time compiling.
244    char vold_decrypt[kPropertyValueMax];
245    bool have_vold_decrypt = get_property("vold.decrypt", vold_decrypt, "") > 0;
246    bool skip_compilation = (have_vold_decrypt &&
247                             (strcmp(vold_decrypt, "trigger_restart_min_framework") == 0 ||
248                             (strcmp(vold_decrypt, "1") == 0)));
249
250    bool generate_debug_info = property_get_bool("debug.generate-debug-info", false);
251
252    char app_image_format[kPropertyValueMax];
253    char image_format_arg[strlen("--image-format=") + kPropertyValueMax];
254    bool have_app_image_format =
255            image_fd >= 0 && get_property("dalvik.vm.appimageformat", app_image_format, NULL) > 0;
256    if (have_app_image_format) {
257        sprintf(image_format_arg, "--image-format=%s", app_image_format);
258    }
259
260    char dex2oat_large_app_threshold[kPropertyValueMax];
261    bool have_dex2oat_large_app_threshold =
262            get_property("dalvik.vm.dex2oat-very-large", dex2oat_large_app_threshold, NULL) > 0;
263    char dex2oat_large_app_threshold_arg[strlen("--very-large-app-threshold=") + kPropertyValueMax];
264    if (have_dex2oat_large_app_threshold) {
265        sprintf(dex2oat_large_app_threshold_arg,
266                "--very-large-app-threshold=%s",
267                dex2oat_large_app_threshold);
268    }
269
270    static const char* DEX2OAT_BIN = "/system/bin/dex2oat";
271
272    static const char* RUNTIME_ARG = "--runtime-arg";
273
274    static const int MAX_INT_LEN = 12;      // '-'+10dig+'\0' -OR- 0x+8dig
275
276    // clang FORTIFY doesn't let us use strlen in constant array bounds, so we
277    // use arraysize instead.
278    char zip_fd_arg[arraysize("--zip-fd=") + MAX_INT_LEN];
279    char zip_location_arg[arraysize("--zip-location=") + PKG_PATH_MAX];
280    char input_vdex_fd_arg[arraysize("--input-vdex-fd=") + MAX_INT_LEN];
281    char output_vdex_fd_arg[arraysize("--output-vdex-fd=") + MAX_INT_LEN];
282    char oat_fd_arg[arraysize("--oat-fd=") + MAX_INT_LEN];
283    char oat_location_arg[arraysize("--oat-location=") + PKG_PATH_MAX];
284    char instruction_set_arg[arraysize("--instruction-set=") + MAX_INSTRUCTION_SET_LEN];
285    char instruction_set_variant_arg[arraysize("--instruction-set-variant=") + kPropertyValueMax];
286    char instruction_set_features_arg[arraysize("--instruction-set-features=") + kPropertyValueMax];
287    char dex2oat_Xms_arg[arraysize("-Xms") + kPropertyValueMax];
288    char dex2oat_Xmx_arg[arraysize("-Xmx") + kPropertyValueMax];
289    char dex2oat_compiler_filter_arg[arraysize("--compiler-filter=") + kPropertyValueMax];
290    bool have_dex2oat_swap_fd = false;
291    char dex2oat_swap_fd[arraysize("--swap-fd=") + MAX_INT_LEN];
292    bool have_dex2oat_image_fd = false;
293    char dex2oat_image_fd[arraysize("--app-image-fd=") + MAX_INT_LEN];
294
295    sprintf(zip_fd_arg, "--zip-fd=%d", zip_fd);
296    sprintf(zip_location_arg, "--zip-location=%s", relative_input_file_name);
297    sprintf(input_vdex_fd_arg, "--input-vdex-fd=%d", input_vdex_fd);
298    sprintf(output_vdex_fd_arg, "--output-vdex-fd=%d", output_vdex_fd);
299    sprintf(oat_fd_arg, "--oat-fd=%d", oat_fd);
300    sprintf(oat_location_arg, "--oat-location=%s", output_file_name);
301    sprintf(instruction_set_arg, "--instruction-set=%s", instruction_set);
302    sprintf(instruction_set_variant_arg, "--instruction-set-variant=%s", dex2oat_isa_variant);
303    sprintf(instruction_set_features_arg, "--instruction-set-features=%s", dex2oat_isa_features);
304    if (swap_fd >= 0) {
305        have_dex2oat_swap_fd = true;
306        sprintf(dex2oat_swap_fd, "--swap-fd=%d", swap_fd);
307    }
308    if (image_fd >= 0) {
309        have_dex2oat_image_fd = true;
310        sprintf(dex2oat_image_fd, "--app-image-fd=%d", image_fd);
311    }
312
313    if (have_dex2oat_Xms_flag) {
314        sprintf(dex2oat_Xms_arg, "-Xms%s", dex2oat_Xms_flag);
315    }
316    if (have_dex2oat_Xmx_flag) {
317        sprintf(dex2oat_Xmx_arg, "-Xmx%s", dex2oat_Xmx_flag);
318    }
319
320    // Compute compiler filter.
321
322    bool have_dex2oat_compiler_filter_flag;
323    if (skip_compilation) {
324        strcpy(dex2oat_compiler_filter_arg, "--compiler-filter=extract");
325        have_dex2oat_compiler_filter_flag = true;
326        have_dex2oat_relocation_skip_flag = true;
327    } else if (vm_safe_mode) {
328        strcpy(dex2oat_compiler_filter_arg, "--compiler-filter=quicken");
329        have_dex2oat_compiler_filter_flag = true;
330    } else if (compiler_filter != nullptr &&
331            strlen(compiler_filter) + strlen("--compiler-filter=") <
332                    arraysize(dex2oat_compiler_filter_arg)) {
333        sprintf(dex2oat_compiler_filter_arg, "--compiler-filter=%s", compiler_filter);
334        have_dex2oat_compiler_filter_flag = true;
335    } else {
336        char dex2oat_compiler_filter_flag[kPropertyValueMax];
337        have_dex2oat_compiler_filter_flag = get_property("dalvik.vm.dex2oat-filter",
338                                                         dex2oat_compiler_filter_flag, NULL) > 0;
339        if (have_dex2oat_compiler_filter_flag) {
340            sprintf(dex2oat_compiler_filter_arg,
341                    "--compiler-filter=%s",
342                    dex2oat_compiler_filter_flag);
343        }
344    }
345
346    // Check whether all apps should be compiled debuggable.
347    if (!debuggable) {
348        char prop_buf[kPropertyValueMax];
349        debuggable =
350                (get_property("dalvik.vm.always_debuggable", prop_buf, "0") > 0) &&
351                (prop_buf[0] == '1');
352    }
353    char profile_arg[strlen("--profile-file-fd=") + MAX_INT_LEN];
354    if (profile_fd != -1) {
355        sprintf(profile_arg, "--profile-file-fd=%d", profile_fd);
356    }
357
358    // Get the directory of the apk to pass as a base classpath directory.
359    char base_dir[arraysize("--classpath-dir=") + PKG_PATH_MAX];
360    std::string apk_dir(input_file_name);
361    unsigned long dir_index = apk_dir.rfind('/');
362    bool has_base_dir = dir_index != std::string::npos;
363    if (has_base_dir) {
364        apk_dir = apk_dir.substr(0, dir_index);
365        sprintf(base_dir, "--classpath-dir=%s", apk_dir.c_str());
366    }
367
368
369    ALOGV("Running %s in=%s out=%s\n", DEX2OAT_BIN, relative_input_file_name, output_file_name);
370
371    const char* argv[9  // program name, mandatory arguments and the final NULL
372                     + (have_dex2oat_isa_variant ? 1 : 0)
373                     + (have_dex2oat_isa_features ? 1 : 0)
374                     + (have_dex2oat_Xms_flag ? 2 : 0)
375                     + (have_dex2oat_Xmx_flag ? 2 : 0)
376                     + (have_dex2oat_compiler_filter_flag ? 1 : 0)
377                     + (have_dex2oat_threads_flag ? 1 : 0)
378                     + (have_dex2oat_swap_fd ? 1 : 0)
379                     + (have_dex2oat_image_fd ? 1 : 0)
380                     + (have_dex2oat_relocation_skip_flag ? 2 : 0)
381                     + (generate_debug_info ? 1 : 0)
382                     + (debuggable ? 1 : 0)
383                     + (have_app_image_format ? 1 : 0)
384                     + dex2oat_flags_count
385                     + (profile_fd == -1 ? 0 : 1)
386                     + (shared_libraries != nullptr ? 4 : 0)
387                     + (has_base_dir ? 1 : 0)
388                     + (have_dex2oat_large_app_threshold ? 1 : 0)];
389    int i = 0;
390    argv[i++] = DEX2OAT_BIN;
391    argv[i++] = zip_fd_arg;
392    argv[i++] = zip_location_arg;
393    argv[i++] = input_vdex_fd_arg;
394    argv[i++] = output_vdex_fd_arg;
395    argv[i++] = oat_fd_arg;
396    argv[i++] = oat_location_arg;
397    argv[i++] = instruction_set_arg;
398    if (have_dex2oat_isa_variant) {
399        argv[i++] = instruction_set_variant_arg;
400    }
401    if (have_dex2oat_isa_features) {
402        argv[i++] = instruction_set_features_arg;
403    }
404    if (have_dex2oat_Xms_flag) {
405        argv[i++] = RUNTIME_ARG;
406        argv[i++] = dex2oat_Xms_arg;
407    }
408    if (have_dex2oat_Xmx_flag) {
409        argv[i++] = RUNTIME_ARG;
410        argv[i++] = dex2oat_Xmx_arg;
411    }
412    if (have_dex2oat_compiler_filter_flag) {
413        argv[i++] = dex2oat_compiler_filter_arg;
414    }
415    if (have_dex2oat_threads_flag) {
416        argv[i++] = dex2oat_threads_arg;
417    }
418    if (have_dex2oat_swap_fd) {
419        argv[i++] = dex2oat_swap_fd;
420    }
421    if (have_dex2oat_image_fd) {
422        argv[i++] = dex2oat_image_fd;
423    }
424    if (generate_debug_info) {
425        argv[i++] = "--generate-debug-info";
426    }
427    if (debuggable) {
428        argv[i++] = "--debuggable";
429    }
430    if (have_app_image_format) {
431        argv[i++] = image_format_arg;
432    }
433    if (have_dex2oat_large_app_threshold) {
434        argv[i++] = dex2oat_large_app_threshold_arg;
435    }
436    if (dex2oat_flags_count) {
437        i += split(dex2oat_flags, argv + i);
438    }
439    if (have_dex2oat_relocation_skip_flag) {
440        argv[i++] = RUNTIME_ARG;
441        argv[i++] = dex2oat_norelocation;
442    }
443    if (profile_fd != -1) {
444        argv[i++] = profile_arg;
445    }
446    if (shared_libraries != nullptr) {
447        argv[i++] = RUNTIME_ARG;
448        argv[i++] = "-classpath";
449        argv[i++] = RUNTIME_ARG;
450        argv[i++] = shared_libraries;
451    }
452    if (has_base_dir) {
453        argv[i++] = base_dir;
454    }
455    // Do not add after dex2oat_flags, they should override others for debugging.
456    argv[i] = NULL;
457
458    execv(DEX2OAT_BIN, (char * const *)argv);
459    ALOGE("execv(%s) failed: %s\n", DEX2OAT_BIN, strerror(errno));
460}
461
462/*
463 * Whether dexopt should use a swap file when compiling an APK.
464 *
465 * If kAlwaysProvideSwapFile, do this on all devices (dex2oat will make a more informed decision
466 * itself, anyways).
467 *
468 * Otherwise, read "dalvik.vm.dex2oat-swap". If the property exists, return whether it is "true".
469 *
470 * Otherwise, return true if this is a low-mem device.
471 *
472 * Otherwise, return default value.
473 */
474static bool kAlwaysProvideSwapFile = false;
475static bool kDefaultProvideSwapFile = true;
476
477static bool ShouldUseSwapFileForDexopt() {
478    if (kAlwaysProvideSwapFile) {
479        return true;
480    }
481
482    // Check the "override" property. If it exists, return value == "true".
483    char dex2oat_prop_buf[kPropertyValueMax];
484    if (get_property("dalvik.vm.dex2oat-swap", dex2oat_prop_buf, "") > 0) {
485        if (strcmp(dex2oat_prop_buf, "true") == 0) {
486            return true;
487        } else {
488            return false;
489        }
490    }
491
492    // Shortcut for default value. This is an implementation optimization for the process sketched
493    // above. If the default value is true, we can avoid to check whether this is a low-mem device,
494    // as low-mem is never returning false. The compiler will optimize this away if it can.
495    if (kDefaultProvideSwapFile) {
496        return true;
497    }
498
499    bool is_low_mem = property_get_bool("ro.config.low_ram", false);
500    if (is_low_mem) {
501        return true;
502    }
503
504    // Default value must be false here.
505    return kDefaultProvideSwapFile;
506}
507
508static void SetDex2OatScheduling(bool set_to_bg) {
509    if (set_to_bg) {
510        if (set_sched_policy(0, SP_BACKGROUND) < 0) {
511            ALOGE("set_sched_policy failed: %s\n", strerror(errno));
512            exit(70);
513        }
514        if (setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_BACKGROUND) < 0) {
515            ALOGE("setpriority failed: %s\n", strerror(errno));
516            exit(71);
517        }
518    }
519}
520
521static bool create_profile(int uid, const std::string& profile) {
522    unique_fd fd(TEMP_FAILURE_RETRY(open(profile.c_str(), O_CREAT | O_NOFOLLOW, 0600)));
523    if (fd.get() < 0) {
524        if (errno == EEXIST) {
525            return true;
526        } else {
527            PLOG(ERROR) << "Failed to create profile " << profile;
528            return false;
529        }
530    }
531    // Profiles should belong to the app; make sure of that by giving ownership to
532    // the app uid. If we cannot do that, there's no point in returning the fd
533    // since dex2oat/profman will fail with SElinux denials.
534    if (fchown(fd.get(), uid, uid) < 0) {
535        PLOG(ERROR) << "Could not chwon profile " << profile;
536        return false;
537    }
538    return true;
539}
540
541static unique_fd open_profile(int uid, const std::string& profile, bool read_write) {
542    // Check if we need to open the profile for a read-write operation. If so, we
543    // might need to create the profile since the file might not be there. Reference
544    // profiles are created on the fly so they might not exist beforehand.
545    if (read_write) {
546        if (!create_profile(uid, profile)) {
547            return invalid_unique_fd();
548        }
549    }
550    int flags = read_write ? O_RDWR : O_RDONLY;
551    // Do not follow symlinks when opening a profile:
552    //   - primary profiles should not contain symlinks in their paths
553    //   - secondary dex paths should have been already resolved and validated
554    flags |= O_NOFOLLOW;
555
556    unique_fd fd(TEMP_FAILURE_RETRY(open(profile.c_str(), flags)));
557    if (fd.get() < 0) {
558        if (errno != ENOENT) {
559            // Profiles might be missing for various reasons. For example, in a
560            // multi-user environment, the profile directory for one user can be created
561            // after we start a merge. In this case the current profile for that user
562            // will not be found.
563            // Also, the secondary dex profiles might be deleted by the app at any time,
564            // so we can't we need to prepare if they are missing.
565            PLOG(ERROR) << "Failed to open profile " << profile;
566        }
567        return invalid_unique_fd();
568    }
569
570    return fd;
571}
572
573static unique_fd open_current_profile(uid_t uid, userid_t user, const std::string& location,
574        bool is_secondary_dex) {
575    std::string profile = create_current_profile_path(user, location, is_secondary_dex);
576    return open_profile(uid, profile, /*read_write*/false);
577}
578
579static unique_fd open_reference_profile(uid_t uid, const std::string& location, bool read_write,
580        bool is_secondary_dex) {
581    std::string profile = create_reference_profile_path(location, is_secondary_dex);
582    return open_profile(uid, profile, read_write);
583}
584
585static void open_profile_files(uid_t uid, const std::string& location, bool is_secondary_dex,
586            /*out*/ std::vector<unique_fd>* profiles_fd, /*out*/ unique_fd* reference_profile_fd) {
587    // Open the reference profile in read-write mode as profman might need to save the merge.
588    *reference_profile_fd = open_reference_profile(uid, location, /*read_write*/ true,
589            is_secondary_dex);
590
591    // For secondary dex files, we don't really need the user but we use it for sanity checks.
592    // Note: the user owning the dex file should be the current user.
593    std::vector<userid_t> users;
594    if (is_secondary_dex){
595        users.push_back(multiuser_get_user_id(uid));
596    } else {
597        users = get_known_users(/*volume_uuid*/ nullptr);
598    }
599    for (auto user : users) {
600        unique_fd profile_fd = open_current_profile(uid, user, location, is_secondary_dex);
601        // Add to the lists only if both fds are valid.
602        if (profile_fd.get() >= 0) {
603            profiles_fd->push_back(std::move(profile_fd));
604        }
605    }
606}
607
608static void drop_capabilities(uid_t uid) {
609    if (setgid(uid) != 0) {
610        ALOGE("setgid(%d) failed in installd during dexopt\n", uid);
611        exit(64);
612    }
613    if (setuid(uid) != 0) {
614        ALOGE("setuid(%d) failed in installd during dexopt\n", uid);
615        exit(65);
616    }
617    // drop capabilities
618    struct __user_cap_header_struct capheader;
619    struct __user_cap_data_struct capdata[2];
620    memset(&capheader, 0, sizeof(capheader));
621    memset(&capdata, 0, sizeof(capdata));
622    capheader.version = _LINUX_CAPABILITY_VERSION_3;
623    if (capset(&capheader, &capdata[0]) < 0) {
624        ALOGE("capset failed: %s\n", strerror(errno));
625        exit(66);
626    }
627}
628
629static constexpr int PROFMAN_BIN_RETURN_CODE_COMPILE = 0;
630static constexpr int PROFMAN_BIN_RETURN_CODE_SKIP_COMPILATION = 1;
631static constexpr int PROFMAN_BIN_RETURN_CODE_BAD_PROFILES = 2;
632static constexpr int PROFMAN_BIN_RETURN_CODE_ERROR_IO = 3;
633static constexpr int PROFMAN_BIN_RETURN_CODE_ERROR_LOCKING = 4;
634
635static void run_profman_merge(const std::vector<unique_fd>& profiles_fd,
636        const unique_fd& reference_profile_fd) {
637    static const size_t MAX_INT_LEN = 32;
638    static const char* PROFMAN_BIN = "/system/bin/profman";
639
640    std::vector<std::string> profile_args(profiles_fd.size());
641    char profile_buf[strlen("--profile-file-fd=") + MAX_INT_LEN];
642    for (size_t k = 0; k < profiles_fd.size(); k++) {
643        sprintf(profile_buf, "--profile-file-fd=%d", profiles_fd[k].get());
644        profile_args[k].assign(profile_buf);
645    }
646    char reference_profile_arg[strlen("--reference-profile-file-fd=") + MAX_INT_LEN];
647    sprintf(reference_profile_arg, "--reference-profile-file-fd=%d", reference_profile_fd.get());
648
649    // program name, reference profile fd, the final NULL and the profile fds
650    const char* argv[3 + profiles_fd.size()];
651    int i = 0;
652    argv[i++] = PROFMAN_BIN;
653    argv[i++] = reference_profile_arg;
654    for (size_t k = 0; k < profile_args.size(); k++) {
655        argv[i++] = profile_args[k].c_str();
656    }
657    // Do not add after dex2oat_flags, they should override others for debugging.
658    argv[i] = NULL;
659
660    execv(PROFMAN_BIN, (char * const *)argv);
661    ALOGE("execv(%s) failed: %s\n", PROFMAN_BIN, strerror(errno));
662    exit(68);   /* only get here on exec failure */
663}
664
665// Decides if profile guided compilation is needed or not based on existing profiles.
666// The location is the package name for primary apks or the dex path for secondary dex files.
667// Returns true if there is enough information in the current profiles that makes it
668// worth to recompile the given location.
669// If the return value is true all the current profiles would have been merged into
670// the reference profiles accessible with open_reference_profile().
671static bool analyze_profiles(uid_t uid, const std::string& location, bool is_secondary_dex) {
672    std::vector<unique_fd> profiles_fd;
673    unique_fd reference_profile_fd;
674    open_profile_files(uid, location, is_secondary_dex, &profiles_fd, &reference_profile_fd);
675    if (profiles_fd.empty() || (reference_profile_fd.get() < 0)) {
676        // Skip profile guided compilation because no profiles were found.
677        // Or if the reference profile info couldn't be opened.
678        return false;
679    }
680
681    pid_t pid = fork();
682    if (pid == 0) {
683        /* child -- drop privileges before continuing */
684        drop_capabilities(uid);
685        run_profman_merge(profiles_fd, reference_profile_fd);
686        exit(68);   /* only get here on exec failure */
687    }
688    /* parent */
689    int return_code = wait_child(pid);
690    bool need_to_compile = false;
691    bool should_clear_current_profiles = false;
692    bool should_clear_reference_profile = false;
693    if (!WIFEXITED(return_code)) {
694        LOG(WARNING) << "profman failed for location " << location << ": " << return_code;
695    } else {
696        return_code = WEXITSTATUS(return_code);
697        switch (return_code) {
698            case PROFMAN_BIN_RETURN_CODE_COMPILE:
699                need_to_compile = true;
700                should_clear_current_profiles = true;
701                should_clear_reference_profile = false;
702                break;
703            case PROFMAN_BIN_RETURN_CODE_SKIP_COMPILATION:
704                need_to_compile = false;
705                should_clear_current_profiles = false;
706                should_clear_reference_profile = false;
707                break;
708            case PROFMAN_BIN_RETURN_CODE_BAD_PROFILES:
709                LOG(WARNING) << "Bad profiles for location " << location;
710                need_to_compile = false;
711                should_clear_current_profiles = true;
712                should_clear_reference_profile = true;
713                break;
714            case PROFMAN_BIN_RETURN_CODE_ERROR_IO:  // fall-through
715            case PROFMAN_BIN_RETURN_CODE_ERROR_LOCKING:
716                // Temporary IO problem (e.g. locking). Ignore but log a warning.
717                LOG(WARNING) << "IO error while reading profiles for location " << location;
718                need_to_compile = false;
719                should_clear_current_profiles = false;
720                should_clear_reference_profile = false;
721                break;
722           default:
723                // Unknown return code or error. Unlink profiles.
724                LOG(WARNING) << "Unknown error code while processing profiles for location "
725                        << location << ": " << return_code;
726                need_to_compile = false;
727                should_clear_current_profiles = true;
728                should_clear_reference_profile = true;
729                break;
730        }
731    }
732
733    if (should_clear_current_profiles) {
734        if (is_secondary_dex) {
735            // For secondary dex files, the owning user is the current user.
736            clear_current_profile(location, multiuser_get_user_id(uid), is_secondary_dex);
737        } else  {
738            clear_primary_current_profiles(location);
739        }
740    }
741    if (should_clear_reference_profile) {
742        clear_reference_profile(location, is_secondary_dex);
743    }
744    return need_to_compile;
745}
746
747// Decides if profile guided compilation is needed or not based on existing profiles.
748// The analysis is done for the primary apks of the given package.
749// Returns true if there is enough information in the current profiles that makes it
750// worth to recompile the package.
751// If the return value is true all the current profiles would have been merged into
752// the reference profiles accessible with open_reference_profile().
753bool analyze_primary_profiles(uid_t uid, const std::string& pkgname) {
754    return analyze_profiles(uid, pkgname, /*is_secondary_dex*/false);
755}
756
757static void run_profman_dump(const std::vector<unique_fd>& profile_fds,
758                             const unique_fd& reference_profile_fd,
759                             const std::vector<std::string>& dex_locations,
760                             const std::vector<unique_fd>& apk_fds,
761                             const unique_fd& output_fd) {
762    std::vector<std::string> profman_args;
763    static const char* PROFMAN_BIN = "/system/bin/profman";
764    profman_args.push_back(PROFMAN_BIN);
765    profman_args.push_back("--dump-only");
766    profman_args.push_back(StringPrintf("--dump-output-to-fd=%d", output_fd.get()));
767    if (reference_profile_fd != -1) {
768        profman_args.push_back(StringPrintf("--reference-profile-file-fd=%d",
769                                            reference_profile_fd.get()));
770    }
771    for (size_t i = 0; i < profile_fds.size(); i++) {
772        profman_args.push_back(StringPrintf("--profile-file-fd=%d", profile_fds[i].get()));
773    }
774    for (const std::string& dex_location : dex_locations) {
775        profman_args.push_back(StringPrintf("--dex-location=%s", dex_location.c_str()));
776    }
777    for (size_t i = 0; i < apk_fds.size(); i++) {
778        profman_args.push_back(StringPrintf("--apk-fd=%d", apk_fds[i].get()));
779    }
780    const char **argv = new const char*[profman_args.size() + 1];
781    size_t i = 0;
782    for (const std::string& profman_arg : profman_args) {
783        argv[i++] = profman_arg.c_str();
784    }
785    argv[i] = NULL;
786
787    execv(PROFMAN_BIN, (char * const *)argv);
788    ALOGE("execv(%s) failed: %s\n", PROFMAN_BIN, strerror(errno));
789    exit(68);   /* only get here on exec failure */
790}
791
792bool dump_profiles(int32_t uid, const std::string& pkgname, const char* code_paths) {
793    std::vector<unique_fd> profile_fds;
794    unique_fd reference_profile_fd;
795    std::string out_file_name = StringPrintf("/data/misc/profman/%s.txt", pkgname.c_str());
796
797    open_profile_files(uid, pkgname, /*is_secondary_dex*/false,
798            &profile_fds, &reference_profile_fd);
799
800    const bool has_reference_profile = (reference_profile_fd.get() != -1);
801    const bool has_profiles = !profile_fds.empty();
802
803    if (!has_reference_profile && !has_profiles) {
804        LOG(ERROR)  << "profman dump: no profiles to dump for " << pkgname;
805        return false;
806    }
807
808    unique_fd output_fd(open(out_file_name.c_str(),
809            O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW, 0644));
810    if (fchmod(output_fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
811        ALOGE("installd cannot chmod '%s' dump_profile\n", out_file_name.c_str());
812        return false;
813    }
814    std::vector<std::string> code_full_paths = base::Split(code_paths, ";");
815    std::vector<std::string> dex_locations;
816    std::vector<unique_fd> apk_fds;
817    for (const std::string& code_full_path : code_full_paths) {
818        const char* full_path = code_full_path.c_str();
819        unique_fd apk_fd(open(full_path, O_RDONLY | O_NOFOLLOW));
820        if (apk_fd == -1) {
821            ALOGE("installd cannot open '%s'\n", full_path);
822            return false;
823        }
824        dex_locations.push_back(get_location_from_path(full_path));
825        apk_fds.push_back(std::move(apk_fd));
826    }
827
828    pid_t pid = fork();
829    if (pid == 0) {
830        /* child -- drop privileges before continuing */
831        drop_capabilities(uid);
832        run_profman_dump(profile_fds, reference_profile_fd, dex_locations,
833                         apk_fds, output_fd);
834        exit(68);   /* only get here on exec failure */
835    }
836    /* parent */
837    int return_code = wait_child(pid);
838    if (!WIFEXITED(return_code)) {
839        LOG(WARNING) << "profman failed for package " << pkgname << ": "
840                << return_code;
841        return false;
842    }
843    return true;
844}
845
846static std::string replace_file_extension(const std::string& oat_path, const std::string& new_ext) {
847  // A standard dalvik-cache entry. Replace ".dex" with `new_ext`.
848  if (EndsWith(oat_path, ".dex")) {
849    std::string new_path = oat_path;
850    new_path.replace(new_path.length() - strlen(".dex"), strlen(".dex"), new_ext);
851    CHECK(EndsWith(new_path, new_ext.c_str()));
852    return new_path;
853  }
854
855  // An odex entry. Not that this may not be an extension, e.g., in the OTA
856  // case (where the base name will have an extension for the B artifact).
857  size_t odex_pos = oat_path.rfind(".odex");
858  if (odex_pos != std::string::npos) {
859    std::string new_path = oat_path;
860    new_path.replace(odex_pos, strlen(".odex"), new_ext);
861    CHECK_NE(new_path.find(new_ext), std::string::npos);
862    return new_path;
863  }
864
865  // Don't know how to handle this.
866  return "";
867}
868
869// Translate the given oat path to an art (app image) path. An empty string
870// denotes an error.
871static std::string create_image_filename(const std::string& oat_path) {
872    return replace_file_extension(oat_path, ".art");
873}
874
875// Translate the given oat path to a vdex path. An empty string denotes an error.
876static std::string create_vdex_filename(const std::string& oat_path) {
877    return replace_file_extension(oat_path, ".vdex");
878}
879
880static bool add_extension_to_file_name(char* file_name, const char* extension) {
881    if (strlen(file_name) + strlen(extension) + 1 > PKG_PATH_MAX) {
882        return false;
883    }
884    strcat(file_name, extension);
885    return true;
886}
887
888static int open_output_file(const char* file_name, bool recreate, int permissions) {
889    int flags = O_RDWR | O_CREAT;
890    if (recreate) {
891        if (unlink(file_name) < 0) {
892            if (errno != ENOENT) {
893                PLOG(ERROR) << "open_output_file: Couldn't unlink " << file_name;
894            }
895        }
896        flags |= O_EXCL;
897    }
898    return open(file_name, flags, permissions);
899}
900
901static bool set_permissions_and_ownership(
902        int fd, bool is_public, int uid, const char* path, bool is_secondary_dex) {
903    // Primary apks are owned by the system. Secondary dex files are owned by the app.
904    int owning_uid = is_secondary_dex ? uid : AID_SYSTEM;
905    if (fchmod(fd,
906               S_IRUSR|S_IWUSR|S_IRGRP |
907               (is_public ? S_IROTH : 0)) < 0) {
908        ALOGE("installd cannot chmod '%s' during dexopt\n", path);
909        return false;
910    } else if (fchown(fd, owning_uid, uid) < 0) {
911        ALOGE("installd cannot chown '%s' during dexopt\n", path);
912        return false;
913    }
914    return true;
915}
916
917static bool IsOutputDalvikCache(const char* oat_dir) {
918  // InstallerConnection.java (which invokes installd) transforms Java null arguments
919  // into '!'. Play it safe by handling it both.
920  // TODO: ensure we never get null.
921  // TODO: pass a flag instead of inferring if the output is dalvik cache.
922  return oat_dir == nullptr || oat_dir[0] == '!';
923}
924
925static bool create_oat_out_path(const char* apk_path, const char* instruction_set,
926            const char* oat_dir, bool is_secondary_dex, /*out*/ char* out_oat_path) {
927    // Early best-effort check whether we can fit the the path into our buffers.
928    // Note: the cache path will require an additional 5 bytes for ".swap", but we'll try to run
929    // without a swap file, if necessary. Reference profiles file also add an extra ".prof"
930    // extension to the cache path (5 bytes).
931    if (strlen(apk_path) >= (PKG_PATH_MAX - 8)) {
932        ALOGE("apk_path too long '%s'\n", apk_path);
933        return false;
934    }
935
936    if (!IsOutputDalvikCache(oat_dir)) {
937        // Oat dirs for secondary dex files are already validated.
938        if (!is_secondary_dex && validate_apk_path(oat_dir)) {
939            ALOGE("cannot validate apk path with oat_dir '%s'\n", oat_dir);
940            return false;
941        }
942        if (!calculate_oat_file_path(out_oat_path, oat_dir, apk_path, instruction_set)) {
943            return false;
944        }
945    } else {
946        if (!create_cache_path(out_oat_path, apk_path, instruction_set)) {
947            return false;
948        }
949    }
950    return true;
951}
952
953// Helper for fd management. This is similar to a unique_fd in that it closes the file descriptor
954// on destruction. It will also run the given cleanup (unless told not to) after closing.
955//
956// Usage example:
957//
958//   Dex2oatFileWrapper file(open(...),
959//                                                   [name]() {
960//                                                       unlink(name.c_str());
961//                                                   });
962//   // Note: care needs to be taken about name, as it needs to have a lifetime longer than the
963//            wrapper if captured as a reference.
964//
965//   if (file.get() == -1) {
966//       // Error opening...
967//   }
968//
969//   ...
970//   if (error) {
971//       // At this point, when the Dex2oatFileWrapper is destructed, the cleanup function will run
972//       // and delete the file (after the fd is closed).
973//       return -1;
974//   }
975//
976//   (Success case)
977//   file.SetCleanup(false);
978//   // At this point, when the Dex2oatFileWrapper is destructed, the cleanup function will not run
979//   // (leaving the file around; after the fd is closed).
980//
981class Dex2oatFileWrapper {
982 public:
983    Dex2oatFileWrapper() : value_(-1), cleanup_(), do_cleanup_(true), auto_close_(true) {
984    }
985
986    Dex2oatFileWrapper(int value, std::function<void ()> cleanup)
987            : value_(value), cleanup_(cleanup), do_cleanup_(true), auto_close_(true) {}
988
989    Dex2oatFileWrapper(Dex2oatFileWrapper&& other) {
990        value_ = other.value_;
991        cleanup_ = other.cleanup_;
992        do_cleanup_ = other.do_cleanup_;
993        auto_close_ = other.auto_close_;
994        other.release();
995    }
996
997    Dex2oatFileWrapper& operator=(Dex2oatFileWrapper&& other) {
998        value_ = other.value_;
999        cleanup_ = other.cleanup_;
1000        do_cleanup_ = other.do_cleanup_;
1001        auto_close_ = other.auto_close_;
1002        other.release();
1003        return *this;
1004    }
1005
1006    ~Dex2oatFileWrapper() {
1007        reset(-1);
1008    }
1009
1010    int get() {
1011        return value_;
1012    }
1013
1014    void SetCleanup(bool cleanup) {
1015        do_cleanup_ = cleanup;
1016    }
1017
1018    void reset(int new_value) {
1019        if (auto_close_ && value_ >= 0) {
1020            close(value_);
1021        }
1022        if (do_cleanup_ && cleanup_ != nullptr) {
1023            cleanup_();
1024        }
1025
1026        value_ = new_value;
1027    }
1028
1029    void reset(int new_value, std::function<void ()> new_cleanup) {
1030        if (auto_close_ && value_ >= 0) {
1031            close(value_);
1032        }
1033        if (do_cleanup_ && cleanup_ != nullptr) {
1034            cleanup_();
1035        }
1036
1037        value_ = new_value;
1038        cleanup_ = new_cleanup;
1039    }
1040
1041    void DisableAutoClose() {
1042        auto_close_ = false;
1043    }
1044
1045 private:
1046    void release() {
1047        value_ = -1;
1048        do_cleanup_ = false;
1049        cleanup_ = nullptr;
1050    }
1051    int value_;
1052    std::function<void ()> cleanup_;
1053    bool do_cleanup_;
1054    bool auto_close_;
1055};
1056
1057// (re)Creates the app image if needed.
1058Dex2oatFileWrapper maybe_open_app_image(const char* out_oat_path, bool profile_guided,
1059        bool is_public, int uid, bool is_secondary_dex) {
1060    // Use app images only if it is enabled (by a set image format) and we are compiling
1061    // profile-guided (so the app image doesn't conservatively contain all classes).
1062    // Note that we don't create an image for secondary dex files.
1063    if (is_secondary_dex || !profile_guided) {
1064        return Dex2oatFileWrapper();
1065    }
1066
1067    const std::string image_path = create_image_filename(out_oat_path);
1068    if (image_path.empty()) {
1069        // Happens when the out_oat_path has an unknown extension.
1070        return Dex2oatFileWrapper();
1071    }
1072    char app_image_format[kPropertyValueMax];
1073    bool have_app_image_format =
1074            get_property("dalvik.vm.appimageformat", app_image_format, NULL) > 0;
1075    if (!have_app_image_format) {
1076        return Dex2oatFileWrapper();
1077    }
1078    // Recreate is true since we do not want to modify a mapped image. If the app is
1079    // already running and we modify the image file, it can cause crashes (b/27493510).
1080    Dex2oatFileWrapper wrapper_fd(
1081            open_output_file(image_path.c_str(), true /*recreate*/, 0600 /*permissions*/),
1082            [image_path]() { unlink(image_path.c_str()); });
1083    if (wrapper_fd.get() < 0) {
1084        // Could not create application image file. Go on since we can compile without it.
1085        LOG(ERROR) << "installd could not create '" << image_path
1086                << "' for image file during dexopt";
1087         // If we have a valid image file path but no image fd, explicitly erase the image file.
1088        if (unlink(image_path.c_str()) < 0) {
1089            if (errno != ENOENT) {
1090                PLOG(ERROR) << "Couldn't unlink image file " << image_path;
1091            }
1092        }
1093    } else if (!set_permissions_and_ownership(
1094                wrapper_fd.get(), is_public, uid, image_path.c_str(), is_secondary_dex)) {
1095        ALOGE("installd cannot set owner '%s' for image during dexopt\n", image_path.c_str());
1096        wrapper_fd.reset(-1);
1097    }
1098
1099    return wrapper_fd;
1100}
1101
1102// Creates the dexopt swap file if necessary and return its fd.
1103// Returns -1 if there's no need for a swap or in case of errors.
1104unique_fd maybe_open_dexopt_swap_file(const char* out_oat_path) {
1105    if (!ShouldUseSwapFileForDexopt()) {
1106        return invalid_unique_fd();
1107    }
1108    // Make sure there really is enough space.
1109    char swap_file_name[PKG_PATH_MAX];
1110    strcpy(swap_file_name, out_oat_path);
1111    if (!add_extension_to_file_name(swap_file_name, ".swap")) {
1112        return invalid_unique_fd();
1113    }
1114    unique_fd swap_fd(open_output_file(
1115            swap_file_name, /*recreate*/true, /*permissions*/0600));
1116    if (swap_fd.get() < 0) {
1117        // Could not create swap file. Optimistically go on and hope that we can compile
1118        // without it.
1119        ALOGE("installd could not create '%s' for swap during dexopt\n", swap_file_name);
1120    } else {
1121        // Immediately unlink. We don't really want to hit flash.
1122        if (unlink(swap_file_name) < 0) {
1123            PLOG(ERROR) << "Couldn't unlink swap file " << swap_file_name;
1124        }
1125    }
1126    return swap_fd;
1127}
1128
1129// Opens the reference profiles if needed.
1130// Note that the reference profile might not exist so it's OK if the fd will be -1.
1131Dex2oatFileWrapper maybe_open_reference_profile(const std::string& pkgname,
1132        const std::string& dex_path, bool profile_guided, bool is_public, int uid,
1133        bool is_secondary_dex) {
1134    // Public apps should not be compiled with profile information ever. Same goes for the special
1135    // package '*' used for the system server.
1136    if (!profile_guided || is_public || (pkgname[0] == '*')) {
1137        return Dex2oatFileWrapper();
1138    }
1139
1140    // Open reference profile in read only mode as dex2oat does not get write permissions.
1141    const std::string location = is_secondary_dex ? dex_path : pkgname;
1142    unique_fd ufd = open_reference_profile(uid, location, /*read_write*/false, is_secondary_dex);
1143    const auto& cleanup = [location, is_secondary_dex]() {
1144        clear_reference_profile(location.c_str(), is_secondary_dex);
1145    };
1146    return Dex2oatFileWrapper(ufd.release(), cleanup);
1147}
1148
1149// Opens the vdex files and assigns the input fd to in_vdex_wrapper_fd and the output fd to
1150// out_vdex_wrapper_fd. Returns true for success or false in case of errors.
1151bool open_vdex_files(const char* apk_path, const char* out_oat_path, int dexopt_needed,
1152        const char* instruction_set, bool is_public, int uid, bool is_secondary_dex,
1153        Dex2oatFileWrapper* in_vdex_wrapper_fd,
1154        Dex2oatFileWrapper* out_vdex_wrapper_fd) {
1155    CHECK(in_vdex_wrapper_fd != nullptr);
1156    CHECK(out_vdex_wrapper_fd != nullptr);
1157    // Open the existing VDEX. We do this before creating the new output VDEX, which will
1158    // unlink the old one.
1159    char in_odex_path[PKG_PATH_MAX];
1160    int dexopt_action = abs(dexopt_needed);
1161    bool is_odex_location = dexopt_needed < 0;
1162    std::string in_vdex_path_str;
1163    if (dexopt_action != DEX2OAT_FROM_SCRATCH) {
1164        // Open the possibly existing vdex. If none exist, we pass -1 to dex2oat for input-vdex-fd.
1165        const char* path = nullptr;
1166        if (is_odex_location) {
1167            if (calculate_odex_file_path(in_odex_path, apk_path, instruction_set)) {
1168                path = in_odex_path;
1169            } else {
1170                ALOGE("installd cannot compute input vdex location for '%s'\n", apk_path);
1171                return false;
1172            }
1173        } else {
1174            path = out_oat_path;
1175        }
1176        in_vdex_path_str = create_vdex_filename(path);
1177        if (in_vdex_path_str.empty()) {
1178            ALOGE("installd cannot compute input vdex location for '%s'\n", path);
1179            return false;
1180        }
1181        if (dexopt_action == DEX2OAT_FOR_BOOT_IMAGE) {
1182            // When we dex2oat because of boot image change, we are going to update
1183            // in-place the vdex file.
1184            in_vdex_wrapper_fd->reset(open(in_vdex_path_str.c_str(), O_RDWR, 0));
1185        } else {
1186            in_vdex_wrapper_fd->reset(open(in_vdex_path_str.c_str(), O_RDONLY, 0));
1187        }
1188    }
1189
1190    // Infer the name of the output VDEX and create it.
1191    const std::string out_vdex_path_str = create_vdex_filename(out_oat_path);
1192    if (out_vdex_path_str.empty()) {
1193        return false;
1194    }
1195
1196    // If we are compiling because the boot image is out of date, we do not
1197    // need to recreate a vdex, and can use the same existing one.
1198    if (dexopt_action == DEX2OAT_FOR_BOOT_IMAGE &&
1199            in_vdex_wrapper_fd->get() != -1 &&
1200            in_vdex_path_str == out_vdex_path_str) {
1201        out_vdex_wrapper_fd->reset(in_vdex_wrapper_fd->get());
1202        // Disable auto close for the in wrapper fd (it will be done when destructing the out
1203        // wrapper).
1204        in_vdex_wrapper_fd->DisableAutoClose();
1205    } else {
1206        out_vdex_wrapper_fd->reset(
1207              open_output_file(out_vdex_path_str.c_str(), /*recreate*/true, /*permissions*/0644),
1208              [out_vdex_path_str]() { unlink(out_vdex_path_str.c_str()); });
1209        if (out_vdex_wrapper_fd->get() < 0) {
1210            ALOGE("installd cannot open vdex'%s' during dexopt\n", out_vdex_path_str.c_str());
1211            return false;
1212        }
1213    }
1214    if (!set_permissions_and_ownership(out_vdex_wrapper_fd->get(), is_public, uid,
1215            out_vdex_path_str.c_str(), is_secondary_dex)) {
1216        ALOGE("installd cannot set owner '%s' for vdex during dexopt\n", out_vdex_path_str.c_str());
1217        return false;
1218    }
1219
1220    // If we got here we successfully opened the vdex files.
1221    return true;
1222}
1223
1224// Opens the output oat file for the given apk.
1225// If successful it stores the output path into out_oat_path and returns true.
1226Dex2oatFileWrapper open_oat_out_file(const char* apk_path, const char* oat_dir,
1227        bool is_public, int uid, const char* instruction_set, bool is_secondary_dex,
1228        char* out_oat_path) {
1229    if (!create_oat_out_path(apk_path, instruction_set, oat_dir, is_secondary_dex, out_oat_path)) {
1230        return Dex2oatFileWrapper();
1231    }
1232    const std::string out_oat_path_str(out_oat_path);
1233    Dex2oatFileWrapper wrapper_fd(
1234            open_output_file(out_oat_path, /*recreate*/true, /*permissions*/0644),
1235            [out_oat_path_str]() { unlink(out_oat_path_str.c_str()); });
1236    if (wrapper_fd.get() < 0) {
1237        PLOG(ERROR) << "installd cannot open output during dexopt" <<  out_oat_path;
1238    } else if (!set_permissions_and_ownership(
1239                wrapper_fd.get(), is_public, uid, out_oat_path, is_secondary_dex)) {
1240        ALOGE("installd cannot set owner '%s' for output during dexopt\n", out_oat_path);
1241        wrapper_fd.reset(-1);
1242    }
1243    return wrapper_fd;
1244}
1245
1246// Updates the access times of out_oat_path based on those from apk_path.
1247void update_out_oat_access_times(const char* apk_path, const char* out_oat_path) {
1248    struct stat input_stat;
1249    memset(&input_stat, 0, sizeof(input_stat));
1250    if (stat(apk_path, &input_stat) != 0) {
1251        PLOG(ERROR) << "Could not stat " << apk_path << " during dexopt";
1252        return;
1253    }
1254
1255    struct utimbuf ut;
1256    ut.actime = input_stat.st_atime;
1257    ut.modtime = input_stat.st_mtime;
1258    if (utime(out_oat_path, &ut) != 0) {
1259        PLOG(WARNING) << "Could not update access times for " << apk_path << " during dexopt";
1260    }
1261}
1262
1263// Runs (execv) dexoptanalyzer on the given arguments.
1264// The analyzer will check if the dex_file needs to be (re)compiled to match the compiler_filter.
1265// If this is for a profile guided compilation, profile_was_updated will tell whether or not
1266// the profile has changed.
1267static void exec_dexoptanalyzer(const std::string& dex_file, const char* instruction_set,
1268        const char* compiler_filter, bool profile_was_updated) {
1269    static const char* DEXOPTANALYZER_BIN = "/system/bin/dexoptanalyzer";
1270    static const unsigned int MAX_INSTRUCTION_SET_LEN = 7;
1271
1272    if (strlen(instruction_set) >= MAX_INSTRUCTION_SET_LEN) {
1273        ALOGE("Instruction set %s longer than max length of %d",
1274              instruction_set, MAX_INSTRUCTION_SET_LEN);
1275        return;
1276    }
1277
1278    char dex_file_arg[strlen("--dex-file=") + PKG_PATH_MAX];
1279    char isa_arg[strlen("--isa=") + MAX_INSTRUCTION_SET_LEN];
1280    char compiler_filter_arg[strlen("--compiler-filter=") + kPropertyValueMax];
1281    const char* assume_profile_changed = "--assume-profile-changed";
1282
1283    sprintf(dex_file_arg, "--dex-file=%s", dex_file.c_str());
1284    sprintf(isa_arg, "--isa=%s", instruction_set);
1285    sprintf(compiler_filter_arg, "--compiler-filter=%s", compiler_filter);
1286
1287    // program name, dex file, isa, filter, the final NULL
1288    const char* argv[5 + (profile_was_updated ? 1 : 0)];
1289    int i = 0;
1290    argv[i++] = DEXOPTANALYZER_BIN;
1291    argv[i++] = dex_file_arg;
1292    argv[i++] = isa_arg;
1293    argv[i++] = compiler_filter_arg;
1294    if (profile_was_updated) {
1295        argv[i++] = assume_profile_changed;
1296    }
1297    argv[i] = NULL;
1298
1299    execv(DEXOPTANALYZER_BIN, (char * const *)argv);
1300    ALOGE("execv(%s) failed: %s\n", DEXOPTANALYZER_BIN, strerror(errno));
1301}
1302
1303// Prepares the oat dir for the secondary dex files.
1304static bool prepare_secondary_dex_oat_dir(const std::string& dex_path, int uid,
1305        const char* instruction_set, std::string* oat_dir_out) {
1306    unsigned long dirIndex = dex_path.rfind('/');
1307    if (dirIndex == std::string::npos) {
1308        LOG(ERROR ) << "Unexpected dir structure for secondary dex " << dex_path;
1309        return false;
1310    }
1311    std::string dex_dir = dex_path.substr(0, dirIndex);
1312
1313    // Create oat file output directory.
1314    mode_t oat_dir_mode = S_IRWXU | S_IRWXG | S_IXOTH;
1315    if (prepare_app_cache_dir(dex_dir, "oat", oat_dir_mode, uid, uid) != 0) {
1316        LOG(ERROR) << "Could not prepare oat dir for secondary dex: " << dex_path;
1317        return false;
1318    }
1319
1320    char oat_dir[PKG_PATH_MAX];
1321    snprintf(oat_dir, PKG_PATH_MAX, "%s/oat", dex_dir.c_str());
1322    oat_dir_out->assign(oat_dir);
1323
1324    // Create oat/isa output directory.
1325    if (prepare_app_cache_dir(*oat_dir_out, instruction_set, oat_dir_mode, uid, uid) != 0) {
1326        LOG(ERROR) << "Could not prepare oat/isa dir for secondary dex: " << dex_path;
1327        return false;
1328    }
1329
1330    return true;
1331}
1332
1333static int constexpr DEXOPTANALYZER_BIN_EXEC_ERROR = 200;
1334
1335// Verifies the result of dexoptanalyzer executed for the apk_path.
1336// If the result is valid returns true and sets dexopt_needed_out to a valid value.
1337// Returns false for errors or unexpected result values.
1338static bool process_dexoptanalyzer_result(const std::string& dex_path, int result,
1339            int* dexopt_needed_out) {
1340    // The result values are defined in dexoptanalyzer.
1341    switch (result) {
1342        case 0:  // no_dexopt_needed
1343            *dexopt_needed_out = NO_DEXOPT_NEEDED; return true;
1344        case 1:  // dex2oat_from_scratch
1345            *dexopt_needed_out = DEX2OAT_FROM_SCRATCH; return true;
1346        case 5:  // dex2oat_for_bootimage_odex
1347            *dexopt_needed_out = -DEX2OAT_FOR_BOOT_IMAGE; return true;
1348        case 6:  // dex2oat_for_filter_odex
1349            *dexopt_needed_out = -DEX2OAT_FOR_FILTER; return true;
1350        case 7:  // dex2oat_for_relocation_odex
1351            *dexopt_needed_out = -DEX2OAT_FOR_RELOCATION; return true;
1352        case 2:  // dex2oat_for_bootimage_oat
1353        case 3:  // dex2oat_for_filter_oat
1354        case 4:  // dex2oat_for_relocation_oat
1355            LOG(ERROR) << "Dexoptnalyzer return the status of an oat file."
1356                    << " Expected odex file status for secondary dex " << dex_path
1357                    << " : dexoptanalyzer result=" << result;
1358            return false;
1359        default:
1360            LOG(ERROR) << "Unexpected result for dexoptanalyzer " << dex_path
1361                    << " exec_dexoptanalyzer result=" << result;
1362            return false;
1363    }
1364}
1365
1366// Processes the dex_path as a secondary dex files and return true if the path dex file should
1367// be compiled. Returns false for errors (logged) or true if the secondary dex path was process
1368// successfully.
1369// When returning true, the output parameters will be:
1370//   - is_public_out: whether or not the oat file should not be made public
1371//   - dexopt_needed_out: valid OatFileAsssitant::DexOptNeeded
1372//   - oat_dir_out: the oat dir path where the oat file should be stored
1373//   - dex_path_out: the real path of the dex file
1374static bool process_secondary_dex_dexopt(const char* original_dex_path, const char* pkgname,
1375        int dexopt_flags, const char* volume_uuid, int uid, const char* instruction_set,
1376        const char* compiler_filter, bool* is_public_out, int* dexopt_needed_out,
1377        std::string* oat_dir_out, std::string* dex_path_out) {
1378    int storage_flag;
1379
1380    if ((dexopt_flags & DEXOPT_STORAGE_CE) != 0) {
1381        storage_flag = FLAG_STORAGE_CE;
1382        if ((dexopt_flags & DEXOPT_STORAGE_DE) != 0) {
1383            LOG(ERROR) << "Ambiguous secondary dex storage flag. Both, CE and DE, flags are set";
1384            return false;
1385        }
1386    } else if ((dexopt_flags & DEXOPT_STORAGE_DE) != 0) {
1387        storage_flag = FLAG_STORAGE_DE;
1388    } else {
1389        LOG(ERROR) << "Secondary dex storage flag must be set";
1390        return false;
1391    }
1392
1393    {
1394        // As opposed to the primary apk, secondary dex files might contain symlinks.
1395        // Resolve the path before passing it to the validate method to
1396        // make sure the verification is done on the real location.
1397        UniqueCPtr<char> dex_real_path_cstr(realpath(original_dex_path, nullptr));
1398        if (dex_real_path_cstr == nullptr) {
1399            PLOG(ERROR) << "Could not get the real path of the secondary dex file "
1400                    << original_dex_path;
1401            return false;
1402        } else {
1403            dex_path_out->assign(dex_real_path_cstr.get());
1404        }
1405    }
1406    const std::string& dex_path = *dex_path_out;
1407    if (!validate_secondary_dex_path(pkgname, dex_path, volume_uuid, uid, storage_flag)) {
1408        LOG(ERROR) << "Could not validate secondary dex path " << dex_path;
1409        return false;
1410    }
1411
1412    // Check if the path exist. If not, there's nothing to do.
1413    struct stat dex_path_stat;
1414    if (stat(dex_path.c_str(), &dex_path_stat) != 0) {
1415        if (errno == ENOENT) {
1416            // Secondary dex files might be deleted any time by the app.
1417            // Nothing to do if that's the case
1418            ALOGV("Secondary dex does not exist %s", dex_path.c_str());
1419            return NO_DEXOPT_NEEDED;
1420        } else {
1421            PLOG(ERROR) << "Could not access secondary dex " << dex_path;
1422        }
1423    }
1424
1425    // Check if we should make the oat file public.
1426    // Note that if the dex file is not public the compiled code cannot be made public.
1427    *is_public_out = ((dexopt_flags & DEXOPT_PUBLIC) != 0) &&
1428            ((dex_path_stat.st_mode & S_IROTH) != 0);
1429
1430    // Prepare the oat directories.
1431    if (!prepare_secondary_dex_oat_dir(dex_path, uid, instruction_set, oat_dir_out)) {
1432        return false;
1433    }
1434
1435    // Analyze profiles.
1436    bool profile_was_updated = analyze_profiles(uid, dex_path, /*is_secondary_dex*/true);
1437
1438    pid_t pid = fork();
1439    if (pid == 0) {
1440        // child -- drop privileges before continuing.
1441        drop_capabilities(uid);
1442        // Run dexoptanalyzer to get dexopt_needed code.
1443        exec_dexoptanalyzer(dex_path, instruction_set, compiler_filter, profile_was_updated);
1444        exit(DEXOPTANALYZER_BIN_EXEC_ERROR);
1445    }
1446
1447    /* parent */
1448
1449    int result = wait_child(pid);
1450    if (!WIFEXITED(result)) {
1451        LOG(ERROR) << "dexoptanalyzer failed for path " << dex_path << ": " << result;
1452        return false;
1453    }
1454    result = WEXITSTATUS(result);
1455    bool success = process_dexoptanalyzer_result(dex_path, result, dexopt_needed_out);
1456    // Run dexopt only if needed or forced.
1457    // Note that dexoptanalyzer is executed even if force compilation is enabled.
1458    // We ignore its valid dexopNeeded result, but still check (in process_dexoptanalyzer_result)
1459    // that we only get results for odex files (apk_dir/oat/isa/code.odex) and not
1460    // for oat files from dalvik-cache.
1461    if (success && ((dexopt_flags & DEXOPT_FORCE) != 0)) {
1462        *dexopt_needed_out = DEX2OAT_FROM_SCRATCH;
1463    }
1464
1465    return success;
1466}
1467
1468int dexopt(const char* dex_path, uid_t uid, const char* pkgname, const char* instruction_set,
1469        int dexopt_needed, const char* oat_dir, int dexopt_flags, const char* compiler_filter,
1470        const char* volume_uuid, const char* shared_libraries, const char* se_info) {
1471    CHECK(pkgname != nullptr);
1472    CHECK(pkgname[0] != 0);
1473    if ((dexopt_flags & ~DEXOPT_MASK) != 0) {
1474        LOG_FATAL("dexopt flags contains unknown fields\n");
1475    }
1476
1477    bool is_public = (dexopt_flags & DEXOPT_PUBLIC) != 0;
1478    bool vm_safe_mode = (dexopt_flags & DEXOPT_SAFEMODE) != 0;
1479    bool debuggable = (dexopt_flags & DEXOPT_DEBUGGABLE) != 0;
1480    bool boot_complete = (dexopt_flags & DEXOPT_BOOTCOMPLETE) != 0;
1481    bool profile_guided = (dexopt_flags & DEXOPT_PROFILE_GUIDED) != 0;
1482    bool is_secondary_dex = (dexopt_flags & DEXOPT_SECONDARY_DEX) != 0;
1483
1484    // Check if we're dealing with a secondary dex file and if we need to compile it.
1485    std::string oat_dir_str;
1486    std::string dex_real_path;
1487    if (is_secondary_dex) {
1488        if (process_secondary_dex_dexopt(dex_path, pkgname, dexopt_flags, volume_uuid, uid,
1489                instruction_set, compiler_filter, &is_public, &dexopt_needed, &oat_dir_str,
1490                &dex_real_path)) {
1491            oat_dir = oat_dir_str.c_str();
1492            dex_path = dex_real_path.c_str();
1493            if (dexopt_needed == NO_DEXOPT_NEEDED) {
1494                return 0;  // Nothing to do, report success.
1495            }
1496        } else {
1497            return -1;  // We had an error, logged in the process method.
1498        }
1499    } else {
1500        // Currently these flags are only use for secondary dex files.
1501        // Verify that they are not set for primary apks.
1502        CHECK((dexopt_flags & DEXOPT_STORAGE_CE) == 0);
1503        CHECK((dexopt_flags & DEXOPT_STORAGE_DE) == 0);
1504    }
1505
1506    // Open the input file.
1507    unique_fd input_fd(open(dex_path, O_RDONLY, 0));
1508    if (input_fd.get() < 0) {
1509        ALOGE("installd cannot open '%s' for input during dexopt\n", dex_path);
1510        return -1;
1511    }
1512
1513    // Create the output OAT file.
1514    char out_oat_path[PKG_PATH_MAX];
1515    Dex2oatFileWrapper out_oat_fd = open_oat_out_file(dex_path, oat_dir, is_public, uid,
1516            instruction_set, is_secondary_dex, out_oat_path);
1517    if (out_oat_fd.get() < 0) {
1518        return -1;
1519    }
1520
1521    // Open vdex files.
1522    Dex2oatFileWrapper in_vdex_fd;
1523    Dex2oatFileWrapper out_vdex_fd;
1524    if (!open_vdex_files(dex_path, out_oat_path, dexopt_needed, instruction_set, is_public, uid,
1525            is_secondary_dex, &in_vdex_fd, &out_vdex_fd)) {
1526        return -1;
1527    }
1528
1529    // Ensure that the oat dir and the compiler artifacts of secondary dex files have the correct
1530    // selinux context (we generate them on the fly during the dexopt invocation and they don't
1531    // fully inherit their parent context).
1532    // Note that for primary apk the oat files are created before, in a separate installd
1533    // call which also does the restorecon. TODO(calin): unify the paths.
1534    if (is_secondary_dex) {
1535        if (selinux_android_restorecon_pkgdir(oat_dir, se_info, uid,
1536                SELINUX_ANDROID_RESTORECON_RECURSE)) {
1537            LOG(ERROR) << "Failed to restorecon " << oat_dir;
1538            return -1;
1539        }
1540    }
1541
1542    // Create a swap file if necessary.
1543    unique_fd swap_fd = maybe_open_dexopt_swap_file(out_oat_path);
1544
1545    // Create the app image file if needed.
1546    Dex2oatFileWrapper image_fd =
1547            maybe_open_app_image(out_oat_path, profile_guided, is_public, uid, is_secondary_dex);
1548
1549    // Open the reference profile if needed.
1550    Dex2oatFileWrapper reference_profile_fd = maybe_open_reference_profile(
1551            pkgname, dex_path, profile_guided, is_public, uid, is_secondary_dex);
1552
1553    ALOGV("DexInv: --- BEGIN '%s' ---\n", dex_path);
1554
1555    pid_t pid = fork();
1556    if (pid == 0) {
1557        /* child -- drop privileges before continuing */
1558        drop_capabilities(uid);
1559
1560        SetDex2OatScheduling(boot_complete);
1561        if (flock(out_oat_fd.get(), LOCK_EX | LOCK_NB) != 0) {
1562            ALOGE("flock(%s) failed: %s\n", out_oat_path, strerror(errno));
1563            _exit(67);
1564        }
1565
1566        run_dex2oat(input_fd.get(),
1567                    out_oat_fd.get(),
1568                    in_vdex_fd.get(),
1569                    out_vdex_fd.get(),
1570                    image_fd.get(),
1571                    dex_path,
1572                    out_oat_path,
1573                    swap_fd.get(),
1574                    instruction_set,
1575                    compiler_filter,
1576                    vm_safe_mode,
1577                    debuggable,
1578                    boot_complete,
1579                    reference_profile_fd.get(),
1580                    shared_libraries);
1581        _exit(68);   /* only get here on exec failure */
1582    } else {
1583        int res = wait_child(pid);
1584        if (res == 0) {
1585            ALOGV("DexInv: --- END '%s' (success) ---\n", dex_path);
1586        } else {
1587            ALOGE("DexInv: --- END '%s' --- status=0x%04x, process failed\n", dex_path, res);
1588            return res;
1589        }
1590    }
1591
1592    update_out_oat_access_times(dex_path, out_oat_path);
1593
1594    // We've been successful, don't delete output.
1595    out_oat_fd.SetCleanup(false);
1596    out_vdex_fd.SetCleanup(false);
1597    image_fd.SetCleanup(false);
1598    reference_profile_fd.SetCleanup(false);
1599
1600    return 0;
1601}
1602
1603// Try to remove the given directory. Log an error if the directory exists
1604// and is empty but could not be removed.
1605static bool rmdir_if_empty(const char* dir) {
1606    if (rmdir(dir) == 0) {
1607        return true;
1608    }
1609    if (errno == ENOENT || errno == ENOTEMPTY) {
1610        return true;
1611    }
1612    PLOG(ERROR) << "Failed to remove dir: " << dir;
1613    return false;
1614}
1615
1616// Try to unlink the given file. Log an error if the file exists and could not
1617// be unlinked.
1618static bool unlink_if_exists(const std::string& file) {
1619    if (unlink(file.c_str()) == 0) {
1620        return true;
1621    }
1622    if (errno == ENOENT) {
1623        return true;
1624
1625    }
1626    PLOG(ERROR) << "Could not unlink: " << file;
1627    return false;
1628}
1629
1630// Create the oat file structure for the secondary dex 'dex_path' and assign
1631// the individual path component to the 'out_' parameters.
1632static bool create_secondary_dex_oat_layout(const std::string& dex_path, const std::string& isa,
1633        /*out*/char* out_oat_dir, /*out*/char* out_oat_isa_dir, /*out*/char* out_oat_path) {
1634    size_t dirIndex = dex_path.rfind('/');
1635    if (dirIndex == std::string::npos) {
1636        LOG(ERROR) << "Unexpected dir structure for dex file " << dex_path;
1637        return false;
1638    }
1639    // TODO(calin): we have similar computations in at lest 3 other places
1640    // (InstalldNativeService, otapropt and dexopt). Unify them and get rid of snprintf by
1641    // use string append.
1642    std::string apk_dir = dex_path.substr(0, dirIndex);
1643    snprintf(out_oat_dir, PKG_PATH_MAX, "%s/oat", apk_dir.c_str());
1644    snprintf(out_oat_isa_dir, PKG_PATH_MAX, "%s/%s", out_oat_dir, isa.c_str());
1645
1646    if (!create_oat_out_path(dex_path.c_str(), isa.c_str(), out_oat_dir,
1647            /*is_secondary_dex*/true, out_oat_path)) {
1648        LOG(ERROR) << "Could not create oat path for secondary dex " << dex_path;
1649        return false;
1650    }
1651    return true;
1652}
1653
1654// Reconcile the secondary dex 'dex_path' and its generated oat files.
1655// Return true if all the parameters are valid and the secondary dex file was
1656//   processed successfully (i.e. the dex_path either exists, or if not, its corresponding
1657//   oat/vdex/art files where deleted successfully). In this case, out_secondary_dex_exists
1658//   will be true if the secondary dex file still exists. If the secondary dex file does not exist,
1659//   the method cleans up any previously generated compiler artifacts (oat, vdex, art).
1660// Return false if there were errors during processing. In this case
1661//   out_secondary_dex_exists will be set to false.
1662bool reconcile_secondary_dex_file(const std::string& dex_path,
1663        const std::string& pkgname, int uid, const std::vector<std::string>& isas,
1664        const std::unique_ptr<std::string>& volume_uuid, int storage_flag,
1665        /*out*/bool* out_secondary_dex_exists) {
1666    // Set out to false to start with, just in case we have validation errors.
1667    *out_secondary_dex_exists = false;
1668    if (isas.size() == 0) {
1669        LOG(ERROR) << "reconcile_secondary_dex_file called with empty isas vector";
1670        return false;
1671    }
1672
1673    const char* volume_uuid_cstr = volume_uuid == nullptr ? nullptr : volume_uuid->c_str();
1674    if (!validate_secondary_dex_path(pkgname.c_str(), dex_path.c_str(), volume_uuid_cstr,
1675            uid, storage_flag)) {
1676        LOG(ERROR) << "Could not validate secondary dex path " << dex_path;
1677        return false;
1678    }
1679
1680    if (access(dex_path.c_str(), F_OK) == 0) {
1681        // The path exists, nothing to do. The odex files (if any) will be left untouched.
1682        *out_secondary_dex_exists = true;
1683        return true;
1684    } else if (errno != ENOENT) {
1685        PLOG(ERROR) << "Failed to check access to secondary dex " << dex_path;
1686        return false;
1687    }
1688
1689    // The secondary dex does not exist anymore. Clear any generated files.
1690    char oat_path[PKG_PATH_MAX];
1691    char oat_dir[PKG_PATH_MAX];
1692    char oat_isa_dir[PKG_PATH_MAX];
1693    bool result = true;
1694    for (size_t i = 0; i < isas.size(); i++) {
1695        if (!create_secondary_dex_oat_layout(dex_path, isas[i], oat_dir, oat_isa_dir, oat_path)) {
1696            LOG(ERROR) << "Could not create secondary odex layout: " << dex_path;
1697            result = false;
1698            continue;
1699        }
1700        result = unlink_if_exists(oat_path) && result;
1701        result = unlink_if_exists(create_vdex_filename(oat_path)) && result;
1702        result = unlink_if_exists(create_image_filename(oat_path)) && result;
1703
1704        // Try removing the directories as well, they might be empty.
1705        result = rmdir_if_empty(oat_isa_dir) && result;
1706        result = rmdir_if_empty(oat_dir) && result;
1707    }
1708
1709    return result;
1710}
1711
1712// Helper for move_ab, so that we can have common failure-case cleanup.
1713static bool unlink_and_rename(const char* from, const char* to) {
1714    // Check whether "from" exists, and if so whether it's regular. If it is, unlink. Otherwise,
1715    // return a failure.
1716    struct stat s;
1717    if (stat(to, &s) == 0) {
1718        if (!S_ISREG(s.st_mode)) {
1719            LOG(ERROR) << from << " is not a regular file to replace for A/B.";
1720            return false;
1721        }
1722        if (unlink(to) != 0) {
1723            LOG(ERROR) << "Could not unlink " << to << " to move A/B.";
1724            return false;
1725        }
1726    } else {
1727        // This may be a permission problem. We could investigate the error code, but we'll just
1728        // let the rename failure do the work for us.
1729    }
1730
1731    // Try to rename "to" to "from."
1732    if (rename(from, to) != 0) {
1733        PLOG(ERROR) << "Could not rename " << from << " to " << to;
1734        return false;
1735    }
1736    return true;
1737}
1738
1739// Move/rename a B artifact (from) to an A artifact (to).
1740static bool move_ab_path(const std::string& b_path, const std::string& a_path) {
1741    // Check whether B exists.
1742    {
1743        struct stat s;
1744        if (stat(b_path.c_str(), &s) != 0) {
1745            // Silently ignore for now. The service calling this isn't smart enough to understand
1746            // lack of artifacts at the moment.
1747            return false;
1748        }
1749        if (!S_ISREG(s.st_mode)) {
1750            LOG(ERROR) << "A/B artifact " << b_path << " is not a regular file.";
1751            // Try to unlink, but swallow errors.
1752            unlink(b_path.c_str());
1753            return false;
1754        }
1755    }
1756
1757    // Rename B to A.
1758    if (!unlink_and_rename(b_path.c_str(), a_path.c_str())) {
1759        // Delete the b_path so we don't try again (or fail earlier).
1760        if (unlink(b_path.c_str()) != 0) {
1761            PLOG(ERROR) << "Could not unlink " << b_path;
1762        }
1763
1764        return false;
1765    }
1766
1767    return true;
1768}
1769
1770bool move_ab(const char* apk_path, const char* instruction_set, const char* oat_dir) {
1771    // Get the current slot suffix. No suffix, no A/B.
1772    std::string slot_suffix;
1773    {
1774        char buf[kPropertyValueMax];
1775        if (get_property("ro.boot.slot_suffix", buf, nullptr) <= 0) {
1776            return false;
1777        }
1778        slot_suffix = buf;
1779
1780        if (!ValidateTargetSlotSuffix(slot_suffix)) {
1781            LOG(ERROR) << "Target slot suffix not legal: " << slot_suffix;
1782            return false;
1783        }
1784    }
1785
1786    // Validate other inputs.
1787    if (validate_apk_path(apk_path) != 0) {
1788        LOG(ERROR) << "Invalid apk_path: " << apk_path;
1789        return false;
1790    }
1791    if (validate_apk_path(oat_dir) != 0) {
1792        LOG(ERROR) << "Invalid oat_dir: " << oat_dir;
1793        return false;
1794    }
1795
1796    char a_path[PKG_PATH_MAX];
1797    if (!calculate_oat_file_path(a_path, oat_dir, apk_path, instruction_set)) {
1798        return false;
1799    }
1800    const std::string a_vdex_path = create_vdex_filename(a_path);
1801    const std::string a_image_path = create_image_filename(a_path);
1802
1803    // B path = A path + slot suffix.
1804    const std::string b_path = StringPrintf("%s.%s", a_path, slot_suffix.c_str());
1805    const std::string b_vdex_path = StringPrintf("%s.%s", a_vdex_path.c_str(), slot_suffix.c_str());
1806    const std::string b_image_path = StringPrintf("%s.%s",
1807                                                  a_image_path.c_str(),
1808                                                  slot_suffix.c_str());
1809
1810    bool success = true;
1811    if (move_ab_path(b_path, a_path)) {
1812        if (move_ab_path(b_vdex_path, a_vdex_path)) {
1813            // Note: we can live without an app image. As such, ignore failure to move the image file.
1814            //       If we decide to require the app image, or the app image being moved correctly,
1815            //       then change accordingly.
1816            constexpr bool kIgnoreAppImageFailure = true;
1817
1818            if (!a_image_path.empty()) {
1819                if (!move_ab_path(b_image_path, a_image_path)) {
1820                    unlink(a_image_path.c_str());
1821                    if (!kIgnoreAppImageFailure) {
1822                        success = false;
1823                    }
1824                }
1825            }
1826        } else {
1827            // Cleanup: delete B image, ignore errors.
1828            unlink(b_image_path.c_str());
1829            success = false;
1830        }
1831    } else {
1832        // Cleanup: delete B image, ignore errors.
1833        unlink(b_vdex_path.c_str());
1834        unlink(b_image_path.c_str());
1835        success = false;
1836    }
1837    return success;
1838}
1839
1840bool delete_odex(const char* apk_path, const char* instruction_set, const char* oat_dir) {
1841    // Delete the oat/odex file.
1842    char out_path[PKG_PATH_MAX];
1843    if (!create_oat_out_path(apk_path, instruction_set, oat_dir,
1844            /*is_secondary_dex*/false, out_path)) {
1845        return false;
1846    }
1847
1848    // In case of a permission failure report the issue. Otherwise just print a warning.
1849    auto unlink_and_check = [](const char* path) -> bool {
1850        int result = unlink(path);
1851        if (result != 0) {
1852            if (errno == EACCES || errno == EPERM) {
1853                PLOG(ERROR) << "Could not unlink " << path;
1854                return false;
1855            }
1856            PLOG(WARNING) << "Could not unlink " << path;
1857        }
1858        return true;
1859    };
1860
1861    // Delete the oat/odex file.
1862    bool return_value_oat = unlink_and_check(out_path);
1863
1864    // Derive and delete the app image.
1865    bool return_value_art = unlink_and_check(create_image_filename(out_path).c_str());
1866
1867    // Report success.
1868    return return_value_oat && return_value_art;
1869}
1870
1871}  // namespace installd
1872}  // namespace android
1873