Home | History | Annotate | Download | only in installd
      1 /*
      2  ** Copyright 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 
     17 #include <algorithm>
     18 #include <inttypes.h>
     19 #include <limits>
     20 #include <random>
     21 #include <regex>
     22 #include <selinux/android.h>
     23 #include <selinux/avc.h>
     24 #include <stdlib.h>
     25 #include <string.h>
     26 #include <sys/capability.h>
     27 #include <sys/prctl.h>
     28 #include <sys/stat.h>
     29 #include <sys/wait.h>
     30 
     31 #include <android-base/logging.h>
     32 #include <android-base/macros.h>
     33 #include <android-base/stringprintf.h>
     34 #include <android-base/strings.h>
     35 #include <cutils/fs.h>
     36 #include <cutils/properties.h>
     37 #include <dex2oat_return_codes.h>
     38 #include <log/log.h>
     39 #include <private/android_filesystem_config.h>
     40 
     41 #include "dexopt.h"
     42 #include "file_parsing.h"
     43 #include "globals.h"
     44 #include "installd_constants.h"
     45 #include "installd_deps.h"  // Need to fill in requirements of commands.
     46 #include "otapreopt_utils.h"
     47 #include "system_properties.h"
     48 #include "utils.h"
     49 
     50 #ifndef LOG_TAG
     51 #define LOG_TAG "otapreopt"
     52 #endif
     53 
     54 #define BUFFER_MAX    1024  /* input buffer for commands */
     55 #define TOKEN_MAX     16    /* max number of arguments in buffer */
     56 #define REPLY_MAX     256   /* largest reply allowed */
     57 
     58 using android::base::EndsWith;
     59 using android::base::Join;
     60 using android::base::Split;
     61 using android::base::StartsWith;
     62 using android::base::StringPrintf;
     63 
     64 namespace android {
     65 namespace installd {
     66 
     67 // Check expected values for dexopt flags. If you need to change this:
     68 //
     69 //   RUN AN A/B OTA TO MAKE SURE THINGS STILL WORK!
     70 //
     71 // You most likely need to increase the protocol version and all that entails!
     72 
     73 static_assert(DEXOPT_PUBLIC         == 1 << 1, "DEXOPT_PUBLIC unexpected.");
     74 static_assert(DEXOPT_DEBUGGABLE     == 1 << 2, "DEXOPT_DEBUGGABLE unexpected.");
     75 static_assert(DEXOPT_BOOTCOMPLETE   == 1 << 3, "DEXOPT_BOOTCOMPLETE unexpected.");
     76 static_assert(DEXOPT_PROFILE_GUIDED == 1 << 4, "DEXOPT_PROFILE_GUIDED unexpected.");
     77 static_assert(DEXOPT_SECONDARY_DEX  == 1 << 5, "DEXOPT_SECONDARY_DEX unexpected.");
     78 static_assert(DEXOPT_FORCE          == 1 << 6, "DEXOPT_FORCE unexpected.");
     79 static_assert(DEXOPT_STORAGE_CE     == 1 << 7, "DEXOPT_STORAGE_CE unexpected.");
     80 static_assert(DEXOPT_STORAGE_DE     == 1 << 8, "DEXOPT_STORAGE_DE unexpected.");
     81 
     82 static_assert(DEXOPT_MASK           == 0x1fe, "DEXOPT_MASK unexpected.");
     83 
     84 
     85 
     86 template<typename T>
     87 static constexpr T RoundDown(T x, typename std::decay<T>::type n) {
     88     return DCHECK_CONSTEXPR(IsPowerOfTwo(n), , T(0))(x & -n);
     89 }
     90 
     91 template<typename T>
     92 static constexpr T RoundUp(T x, typename std::remove_reference<T>::type n) {
     93     return RoundDown(x + n - 1, n);
     94 }
     95 
     96 class OTAPreoptService {
     97  public:
     98     // Main driver. Performs the following steps.
     99     //
    100     // 1) Parse options (read system properties etc from B partition).
    101     //
    102     // 2) Read in package data.
    103     //
    104     // 3) Prepare environment variables.
    105     //
    106     // 4) Prepare(compile) boot image, if necessary.
    107     //
    108     // 5) Run update.
    109     int Main(int argc, char** argv) {
    110         if (!ReadArguments(argc, argv)) {
    111             LOG(ERROR) << "Failed reading command line.";
    112             return 1;
    113         }
    114 
    115         if (!ReadSystemProperties()) {
    116             LOG(ERROR)<< "Failed reading system properties.";
    117             return 2;
    118         }
    119 
    120         if (!ReadEnvironment()) {
    121             LOG(ERROR) << "Failed reading environment properties.";
    122             return 3;
    123         }
    124 
    125         if (!CheckAndInitializeInstalldGlobals()) {
    126             LOG(ERROR) << "Failed initializing globals.";
    127             return 4;
    128         }
    129 
    130         PrepareEnvironment();
    131 
    132         if (!PrepareBootImage(/* force */ false)) {
    133             LOG(ERROR) << "Failed preparing boot image.";
    134             return 5;
    135         }
    136 
    137         int dexopt_retcode = RunPreopt();
    138 
    139         return dexopt_retcode;
    140     }
    141 
    142     int GetProperty(const char* key, char* value, const char* default_value) const {
    143         const std::string* prop_value = system_properties_.GetProperty(key);
    144         if (prop_value == nullptr) {
    145             if (default_value == nullptr) {
    146                 return 0;
    147             }
    148             // Copy in the default value.
    149             strncpy(value, default_value, kPropertyValueMax - 1);
    150             value[kPropertyValueMax - 1] = 0;
    151             return strlen(default_value);// TODO: Need to truncate?
    152         }
    153         size_t size = std::min(kPropertyValueMax - 1, prop_value->length());
    154         strncpy(value, prop_value->data(), size);
    155         value[size] = 0;
    156         return static_cast<int>(size);
    157     }
    158 
    159     std::string GetOTADataDirectory() const {
    160         return StringPrintf("%s/%s", GetOtaDirectoryPrefix().c_str(), target_slot_.c_str());
    161     }
    162 
    163     const std::string& GetTargetSlot() const {
    164         return target_slot_;
    165     }
    166 
    167 private:
    168 
    169     struct Parameters {
    170         const char *apk_path;
    171         uid_t uid;
    172         const char *pkgName;
    173         const char *instruction_set;
    174         int dexopt_needed;
    175         const char* oat_dir;
    176         int dexopt_flags;
    177         const char* compiler_filter;
    178         const char* volume_uuid;
    179         const char* shared_libraries;
    180         const char* se_info;
    181         bool downgrade;
    182     };
    183 
    184     bool ReadSystemProperties() {
    185         static constexpr const char* kPropertyFiles[] = {
    186                 "/default.prop", "/system/build.prop"
    187         };
    188 
    189         for (size_t i = 0; i < arraysize(kPropertyFiles); ++i) {
    190             if (!system_properties_.Load(kPropertyFiles[i])) {
    191                 return false;
    192             }
    193         }
    194 
    195         return true;
    196     }
    197 
    198     bool ReadEnvironment() {
    199         // Parse the environment variables from init.environ.rc, which have the form
    200         //   export NAME VALUE
    201         // For simplicity, don't respect string quotation. The values we are interested in can be
    202         // encoded without them.
    203         std::regex export_regex("\\s*export\\s+(\\S+)\\s+(\\S+)");
    204         bool parse_result = ParseFile("/init.environ.rc", [&](const std::string& line) {
    205             std::smatch export_match;
    206             if (!std::regex_match(line, export_match, export_regex)) {
    207                 return true;
    208             }
    209 
    210             if (export_match.size() != 3) {
    211                 return true;
    212             }
    213 
    214             std::string name = export_match[1].str();
    215             std::string value = export_match[2].str();
    216 
    217             system_properties_.SetProperty(name, value);
    218 
    219             return true;
    220         });
    221         if (!parse_result) {
    222             return false;
    223         }
    224 
    225         if (system_properties_.GetProperty(kAndroidDataPathPropertyName) == nullptr) {
    226             return false;
    227         }
    228         android_data_ = *system_properties_.GetProperty(kAndroidDataPathPropertyName);
    229 
    230         if (system_properties_.GetProperty(kAndroidRootPathPropertyName) == nullptr) {
    231             return false;
    232         }
    233         android_root_ = *system_properties_.GetProperty(kAndroidRootPathPropertyName);
    234 
    235         if (system_properties_.GetProperty(kBootClassPathPropertyName) == nullptr) {
    236             return false;
    237         }
    238         boot_classpath_ = *system_properties_.GetProperty(kBootClassPathPropertyName);
    239 
    240         if (system_properties_.GetProperty(ASEC_MOUNTPOINT_ENV_NAME) == nullptr) {
    241             return false;
    242         }
    243         asec_mountpoint_ = *system_properties_.GetProperty(ASEC_MOUNTPOINT_ENV_NAME);
    244 
    245         return true;
    246     }
    247 
    248     const std::string& GetAndroidData() const {
    249         return android_data_;
    250     }
    251 
    252     const std::string& GetAndroidRoot() const {
    253         return android_root_;
    254     }
    255 
    256     const std::string GetOtaDirectoryPrefix() const {
    257         return GetAndroidData() + "/ota";
    258     }
    259 
    260     bool CheckAndInitializeInstalldGlobals() {
    261         // init_globals_from_data_and_root requires "ASEC_MOUNTPOINT" in the environment. We
    262         // do not use any datapath that includes this, but we'll still have to set it.
    263         CHECK(system_properties_.GetProperty(ASEC_MOUNTPOINT_ENV_NAME) != nullptr);
    264         int result = setenv(ASEC_MOUNTPOINT_ENV_NAME, asec_mountpoint_.c_str(), 0);
    265         if (result != 0) {
    266             LOG(ERROR) << "Could not set ASEC_MOUNTPOINT environment variable";
    267             return false;
    268         }
    269 
    270         if (!init_globals_from_data_and_root(GetAndroidData().c_str(), GetAndroidRoot().c_str())) {
    271             LOG(ERROR) << "Could not initialize globals; exiting.";
    272             return false;
    273         }
    274 
    275         // This is different from the normal installd. We only do the base
    276         // directory, the rest will be created on demand when each app is compiled.
    277         if (access(GetOtaDirectoryPrefix().c_str(), R_OK) < 0) {
    278             LOG(ERROR) << "Could not access " << GetOtaDirectoryPrefix();
    279             return false;
    280         }
    281 
    282         return true;
    283     }
    284 
    285     bool ParseBool(const char* in) {
    286         if (strcmp(in, "true") == 0) {
    287             return true;
    288         }
    289         return false;
    290     }
    291 
    292     bool ParseUInt(const char* in, uint32_t* out) {
    293         char* end;
    294         long long int result = strtoll(in, &end, 0);
    295         if (in == end || *end != '\0') {
    296             return false;
    297         }
    298         if (result < std::numeric_limits<uint32_t>::min() ||
    299                 std::numeric_limits<uint32_t>::max() < result) {
    300             return false;
    301         }
    302         *out = static_cast<uint32_t>(result);
    303         return true;
    304     }
    305 
    306     bool ReadArguments(int argc, char** argv) {
    307         // Expected command line:
    308         //   target-slot [version] dexopt {DEXOPT_PARAMETERS}
    309 
    310         const char* target_slot_arg = argv[1];
    311         if (target_slot_arg == nullptr) {
    312             LOG(ERROR) << "Missing parameters";
    313             return false;
    314         }
    315         // Sanitize value. Only allow (a-zA-Z0-9_)+.
    316         target_slot_ = target_slot_arg;
    317         if (!ValidateTargetSlotSuffix(target_slot_)) {
    318             LOG(ERROR) << "Target slot suffix not legal: " << target_slot_;
    319             return false;
    320         }
    321 
    322         // Check for version or "dexopt" next.
    323         if (argv[2] == nullptr) {
    324             LOG(ERROR) << "Missing parameters";
    325             return false;
    326         }
    327 
    328         if (std::string("dexopt").compare(argv[2]) == 0) {
    329             // This is version 1 (N) or pre-versioning version 2.
    330             constexpr int kV2ArgCount =   1   // "otapreopt"
    331                                         + 1   // slot
    332                                         + 1   // "dexopt"
    333                                         + 1   // apk_path
    334                                         + 1   // uid
    335                                         + 1   // pkg
    336                                         + 1   // isa
    337                                         + 1   // dexopt_needed
    338                                         + 1   // oat_dir
    339                                         + 1   // dexopt_flags
    340                                         + 1   // filter
    341                                         + 1   // volume
    342                                         + 1   // libs
    343                                         + 1;  // seinfo
    344             if (argc == kV2ArgCount) {
    345                 return ReadArgumentsV2(argc, argv, false);
    346             } else {
    347                 return ReadArgumentsV1(argc, argv);
    348             }
    349         }
    350 
    351         uint32_t version;
    352         if (!ParseUInt(argv[2], &version)) {
    353             LOG(ERROR) << "Could not parse version: " << argv[2];
    354             return false;
    355         }
    356 
    357         switch (version) {
    358             case 2:
    359                 return ReadArgumentsV2(argc, argv, true);
    360             case 3:
    361                 return ReadArgumentsV3(argc, argv);
    362 
    363             default:
    364                 LOG(ERROR) << "Unsupported version " << version;
    365                 return false;
    366         }
    367     }
    368 
    369     bool ReadArgumentsV2(int argc ATTRIBUTE_UNUSED, char** argv, bool versioned) {
    370         size_t dexopt_index = versioned ? 3 : 2;
    371 
    372         // Check for "dexopt".
    373         if (argv[dexopt_index] == nullptr) {
    374             LOG(ERROR) << "Missing parameters";
    375             return false;
    376         }
    377         if (std::string("dexopt").compare(argv[dexopt_index]) != 0) {
    378             LOG(ERROR) << "Expected \"dexopt\"";
    379             return false;
    380         }
    381 
    382         size_t param_index = 0;
    383         for (;; ++param_index) {
    384             const char* param = argv[dexopt_index + 1 + param_index];
    385             if (param == nullptr) {
    386                 break;
    387             }
    388 
    389             switch (param_index) {
    390                 case 0:
    391                     package_parameters_.apk_path = param;
    392                     break;
    393 
    394                 case 1:
    395                     package_parameters_.uid = atoi(param);
    396                     break;
    397 
    398                 case 2:
    399                     package_parameters_.pkgName = param;
    400                     break;
    401 
    402                 case 3:
    403                     package_parameters_.instruction_set = param;
    404                     break;
    405 
    406                 case 4:
    407                     package_parameters_.dexopt_needed = atoi(param);
    408                     break;
    409 
    410                 case 5:
    411                     package_parameters_.oat_dir = param;
    412                     break;
    413 
    414                 case 6:
    415                     package_parameters_.dexopt_flags = atoi(param);
    416                     break;
    417 
    418                 case 7:
    419                     package_parameters_.compiler_filter = param;
    420                     break;
    421 
    422                 case 8:
    423                     package_parameters_.volume_uuid = ParseNull(param);
    424                     break;
    425 
    426                 case 9:
    427                     package_parameters_.shared_libraries = ParseNull(param);
    428                     break;
    429 
    430                 case 10:
    431                     package_parameters_.se_info = ParseNull(param);
    432                     break;
    433 
    434                 default:
    435                     LOG(ERROR) << "Too many arguments, got " << param;
    436                     return false;
    437             }
    438         }
    439 
    440         // Set downgrade to false. It is only relevant when downgrading compiler
    441         // filter, which is not the case during ota.
    442         package_parameters_.downgrade = false;
    443 
    444         if (param_index != 11) {
    445             LOG(ERROR) << "Not enough parameters";
    446             return false;
    447         }
    448 
    449         return true;
    450     }
    451 
    452     bool ReadArgumentsV3(int argc ATTRIBUTE_UNUSED, char** argv) {
    453         size_t dexopt_index = 3;
    454 
    455         // Check for "dexopt".
    456         if (argv[dexopt_index] == nullptr) {
    457             LOG(ERROR) << "Missing parameters";
    458             return false;
    459         }
    460         if (std::string("dexopt").compare(argv[dexopt_index]) != 0) {
    461             LOG(ERROR) << "Expected \"dexopt\"";
    462             return false;
    463         }
    464 
    465         size_t param_index = 0;
    466         for (;; ++param_index) {
    467             const char* param = argv[dexopt_index + 1 + param_index];
    468             if (param == nullptr) {
    469                 break;
    470             }
    471 
    472             switch (param_index) {
    473                 case 0:
    474                     package_parameters_.apk_path = param;
    475                     break;
    476 
    477                 case 1:
    478                     package_parameters_.uid = atoi(param);
    479                     break;
    480 
    481                 case 2:
    482                     package_parameters_.pkgName = param;
    483                     break;
    484 
    485                 case 3:
    486                     package_parameters_.instruction_set = param;
    487                     break;
    488 
    489                 case 4:
    490                     package_parameters_.dexopt_needed = atoi(param);
    491                     break;
    492 
    493                 case 5:
    494                     package_parameters_.oat_dir = param;
    495                     break;
    496 
    497                 case 6:
    498                     package_parameters_.dexopt_flags = atoi(param);
    499                     break;
    500 
    501                 case 7:
    502                     package_parameters_.compiler_filter = param;
    503                     break;
    504 
    505                 case 8:
    506                     package_parameters_.volume_uuid = ParseNull(param);
    507                     break;
    508 
    509                 case 9:
    510                     package_parameters_.shared_libraries = ParseNull(param);
    511                     break;
    512 
    513                 case 10:
    514                     package_parameters_.se_info = ParseNull(param);
    515                     break;
    516 
    517                 case 11:
    518                     package_parameters_.downgrade = ParseBool(param);
    519                     break;
    520 
    521                 default:
    522                     LOG(ERROR) << "Too many arguments, got " << param;
    523                     return false;
    524             }
    525         }
    526 
    527         if (param_index != 12) {
    528             LOG(ERROR) << "Not enough parameters";
    529             return false;
    530         }
    531 
    532         return true;
    533     }
    534 
    535     static int ReplaceMask(int input, int old_mask, int new_mask) {
    536         return (input & old_mask) != 0 ? new_mask : 0;
    537     }
    538 
    539     bool ReadArgumentsV1(int argc ATTRIBUTE_UNUSED, char** argv) {
    540         // Check for "dexopt".
    541         if (argv[2] == nullptr) {
    542             LOG(ERROR) << "Missing parameters";
    543             return false;
    544         }
    545         if (std::string("dexopt").compare(argv[2]) != 0) {
    546             LOG(ERROR) << "Expected \"dexopt\"";
    547             return false;
    548         }
    549 
    550         size_t param_index = 0;
    551         for (;; ++param_index) {
    552             const char* param = argv[3 + param_index];
    553             if (param == nullptr) {
    554                 break;
    555             }
    556 
    557             switch (param_index) {
    558                 case 0:
    559                     package_parameters_.apk_path = param;
    560                     break;
    561 
    562                 case 1:
    563                     package_parameters_.uid = atoi(param);
    564                     break;
    565 
    566                 case 2:
    567                     package_parameters_.pkgName = param;
    568                     break;
    569 
    570                 case 3:
    571                     package_parameters_.instruction_set = param;
    572                     break;
    573 
    574                 case 4: {
    575                     // Version 1 had:
    576                     //   DEXOPT_DEX2OAT_NEEDED       = 1
    577                     //   DEXOPT_PATCHOAT_NEEDED      = 2
    578                     //   DEXOPT_SELF_PATCHOAT_NEEDED = 3
    579                     // We will simply use DEX2OAT_FROM_SCRATCH.
    580                     package_parameters_.dexopt_needed = DEX2OAT_FROM_SCRATCH;
    581                     break;
    582                 }
    583 
    584                 case 5:
    585                     package_parameters_.oat_dir = param;
    586                     break;
    587 
    588                 case 6: {
    589                     // Version 1 had:
    590                     constexpr int OLD_DEXOPT_PUBLIC         = 1 << 1;
    591                     // Note: DEXOPT_SAFEMODE has been removed.
    592                     // constexpr int OLD_DEXOPT_SAFEMODE       = 1 << 2;
    593                     constexpr int OLD_DEXOPT_DEBUGGABLE     = 1 << 3;
    594                     constexpr int OLD_DEXOPT_BOOTCOMPLETE   = 1 << 4;
    595                     constexpr int OLD_DEXOPT_PROFILE_GUIDED = 1 << 5;
    596                     constexpr int OLD_DEXOPT_OTA            = 1 << 6;
    597                     int input = atoi(param);
    598                     package_parameters_.dexopt_flags =
    599                             ReplaceMask(input, OLD_DEXOPT_PUBLIC, DEXOPT_PUBLIC) |
    600                             ReplaceMask(input, OLD_DEXOPT_DEBUGGABLE, DEXOPT_DEBUGGABLE) |
    601                             ReplaceMask(input, OLD_DEXOPT_BOOTCOMPLETE, DEXOPT_BOOTCOMPLETE) |
    602                             ReplaceMask(input, OLD_DEXOPT_PROFILE_GUIDED, DEXOPT_PROFILE_GUIDED) |
    603                             ReplaceMask(input, OLD_DEXOPT_OTA, 0);
    604                     break;
    605                 }
    606 
    607                 case 7:
    608                     package_parameters_.compiler_filter = param;
    609                     break;
    610 
    611                 case 8:
    612                     package_parameters_.volume_uuid = ParseNull(param);
    613                     break;
    614 
    615                 case 9:
    616                     package_parameters_.shared_libraries = ParseNull(param);
    617                     break;
    618 
    619                 default:
    620                     LOG(ERROR) << "Too many arguments, got " << param;
    621                     return false;
    622             }
    623         }
    624 
    625         if (param_index != 10) {
    626             LOG(ERROR) << "Not enough parameters";
    627             return false;
    628         }
    629 
    630         // Set se_info to null. It is only relevant for secondary dex files, which we won't
    631         // receive from a v1 A side.
    632         package_parameters_.se_info = nullptr;
    633 
    634         // Set downgrade to false. It is only relevant when downgrading compiler
    635         // filter, which is not the case during ota.
    636         package_parameters_.downgrade = false;
    637 
    638         return true;
    639     }
    640 
    641     void PrepareEnvironment() {
    642         environ_.push_back(StringPrintf("BOOTCLASSPATH=%s", boot_classpath_.c_str()));
    643         environ_.push_back(StringPrintf("ANDROID_DATA=%s", GetOTADataDirectory().c_str()));
    644         environ_.push_back(StringPrintf("ANDROID_ROOT=%s", android_root_.c_str()));
    645 
    646         for (const std::string& e : environ_) {
    647             putenv(const_cast<char*>(e.c_str()));
    648         }
    649     }
    650 
    651     // Ensure that we have the right boot image. The first time any app is
    652     // compiled, we'll try to generate it.
    653     bool PrepareBootImage(bool force) const {
    654         if (package_parameters_.instruction_set == nullptr) {
    655             LOG(ERROR) << "Instruction set missing.";
    656             return false;
    657         }
    658         const char* isa = package_parameters_.instruction_set;
    659 
    660         // Check whether the file exists where expected.
    661         std::string dalvik_cache = GetOTADataDirectory() + "/" + DALVIK_CACHE;
    662         std::string isa_path = dalvik_cache + "/" + isa;
    663         std::string art_path = isa_path + "/system@framework (at) boot.art";
    664         std::string oat_path = isa_path + "/system@framework (at) boot.oat";
    665         bool cleared = false;
    666         if (access(art_path.c_str(), F_OK) == 0 && access(oat_path.c_str(), F_OK) == 0) {
    667             // Files exist, assume everything is alright if not forced. Otherwise clean up.
    668             if (!force) {
    669                 return true;
    670             }
    671             ClearDirectory(isa_path);
    672             cleared = true;
    673         }
    674 
    675         // Reset umask in otapreopt, so that we control the the access for the files we create.
    676         umask(0);
    677 
    678         // Create the directories, if necessary.
    679         if (access(dalvik_cache.c_str(), F_OK) != 0) {
    680             if (!CreatePath(dalvik_cache)) {
    681                 PLOG(ERROR) << "Could not create dalvik-cache dir " << dalvik_cache;
    682                 return false;
    683             }
    684         }
    685         if (access(isa_path.c_str(), F_OK) != 0) {
    686             if (!CreatePath(isa_path)) {
    687                 PLOG(ERROR) << "Could not create dalvik-cache isa dir";
    688                 return false;
    689             }
    690         }
    691 
    692         // Prepare to create.
    693         if (!cleared) {
    694             ClearDirectory(isa_path);
    695         }
    696 
    697         std::string preopted_boot_art_path = StringPrintf("/system/framework/%s/boot.art", isa);
    698         if (access(preopted_boot_art_path.c_str(), F_OK) == 0) {
    699           return PatchoatBootImage(art_path, isa);
    700         } else {
    701           // No preopted boot image. Try to compile.
    702           return Dex2oatBootImage(boot_classpath_, art_path, oat_path, isa);
    703         }
    704     }
    705 
    706     static bool CreatePath(const std::string& path) {
    707         // Create the given path. Use string processing instead of dirname, as dirname's need for
    708         // a writable char buffer is painful.
    709 
    710         // First, try to use the full path.
    711         if (mkdir(path.c_str(), 0711) == 0) {
    712             return true;
    713         }
    714         if (errno != ENOENT) {
    715             PLOG(ERROR) << "Could not create path " << path;
    716             return false;
    717         }
    718 
    719         // Now find the parent and try that first.
    720         size_t last_slash = path.find_last_of('/');
    721         if (last_slash == std::string::npos || last_slash == 0) {
    722             PLOG(ERROR) << "Could not create " << path;
    723             return false;
    724         }
    725 
    726         if (!CreatePath(path.substr(0, last_slash))) {
    727             return false;
    728         }
    729 
    730         if (mkdir(path.c_str(), 0711) == 0) {
    731             return true;
    732         }
    733         PLOG(ERROR) << "Could not create " << path;
    734         return false;
    735     }
    736 
    737     static void ClearDirectory(const std::string& dir) {
    738         DIR* c_dir = opendir(dir.c_str());
    739         if (c_dir == nullptr) {
    740             PLOG(WARNING) << "Unable to open " << dir << " to delete it's contents";
    741             return;
    742         }
    743 
    744         for (struct dirent* de = readdir(c_dir); de != nullptr; de = readdir(c_dir)) {
    745             const char* name = de->d_name;
    746             if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
    747                 continue;
    748             }
    749             // We only want to delete regular files and symbolic links.
    750             std::string file = StringPrintf("%s/%s", dir.c_str(), name);
    751             if (de->d_type != DT_REG && de->d_type != DT_LNK) {
    752                 LOG(WARNING) << "Unexpected file "
    753                              << file
    754                              << " of type "
    755                              << std::hex
    756                              << de->d_type
    757                              << " encountered.";
    758             } else {
    759                 // Try to unlink the file.
    760                 if (unlink(file.c_str()) != 0) {
    761                     PLOG(ERROR) << "Unable to unlink " << file;
    762                 }
    763             }
    764         }
    765         CHECK_EQ(0, closedir(c_dir)) << "Unable to close directory.";
    766     }
    767 
    768     bool PatchoatBootImage(const std::string& art_path, const char* isa) const {
    769         // This needs to be kept in sync with ART, see art/runtime/gc/space/image_space.cc.
    770 
    771         std::vector<std::string> cmd;
    772         cmd.push_back("/system/bin/patchoat");
    773 
    774         cmd.push_back("--input-image-location=/system/framework/boot.art");
    775         cmd.push_back(StringPrintf("--output-image-file=%s", art_path.c_str()));
    776 
    777         cmd.push_back(StringPrintf("--instruction-set=%s", isa));
    778 
    779         int32_t base_offset = ChooseRelocationOffsetDelta(ART_BASE_ADDRESS_MIN_DELTA,
    780                                                           ART_BASE_ADDRESS_MAX_DELTA);
    781         cmd.push_back(StringPrintf("--base-offset-delta=%d", base_offset));
    782 
    783         std::string error_msg;
    784         bool result = Exec(cmd, &error_msg);
    785         if (!result) {
    786             LOG(ERROR) << "Could not generate boot image: " << error_msg;
    787         }
    788         return result;
    789     }
    790 
    791     bool Dex2oatBootImage(const std::string& boot_cp,
    792                           const std::string& art_path,
    793                           const std::string& oat_path,
    794                           const char* isa) const {
    795         // This needs to be kept in sync with ART, see art/runtime/gc/space/image_space.cc.
    796         std::vector<std::string> cmd;
    797         cmd.push_back("/system/bin/dex2oat");
    798         cmd.push_back(StringPrintf("--image=%s", art_path.c_str()));
    799         for (const std::string& boot_part : Split(boot_cp, ":")) {
    800             cmd.push_back(StringPrintf("--dex-file=%s", boot_part.c_str()));
    801         }
    802         cmd.push_back(StringPrintf("--oat-file=%s", oat_path.c_str()));
    803 
    804         int32_t base_offset = ChooseRelocationOffsetDelta(ART_BASE_ADDRESS_MIN_DELTA,
    805                 ART_BASE_ADDRESS_MAX_DELTA);
    806         cmd.push_back(StringPrintf("--base=0x%x", ART_BASE_ADDRESS + base_offset));
    807 
    808         cmd.push_back(StringPrintf("--instruction-set=%s", isa));
    809 
    810         // These things are pushed by AndroidRuntime, see frameworks/base/core/jni/AndroidRuntime.cpp.
    811         AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-Xms",
    812                 "-Xms",
    813                 true,
    814                 cmd);
    815         AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-Xmx",
    816                 "-Xmx",
    817                 true,
    818                 cmd);
    819         AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-filter",
    820                 "--compiler-filter=",
    821                 false,
    822                 cmd);
    823         cmd.push_back("--image-classes=/system/etc/preloaded-classes");
    824         // TODO: Compiled-classes.
    825         const std::string* extra_opts =
    826                 system_properties_.GetProperty("dalvik.vm.image-dex2oat-flags");
    827         if (extra_opts != nullptr) {
    828             std::vector<std::string> extra_vals = Split(*extra_opts, " ");
    829             cmd.insert(cmd.end(), extra_vals.begin(), extra_vals.end());
    830         }
    831         // TODO: Should we lower this? It's usually set close to max, because
    832         //       normally there's not much else going on at boot.
    833         AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-threads",
    834                 "-j",
    835                 false,
    836                 cmd);
    837         AddCompilerOptionFromSystemProperty(
    838                 StringPrintf("dalvik.vm.isa.%s.variant", isa).c_str(),
    839                 "--instruction-set-variant=",
    840                 false,
    841                 cmd);
    842         AddCompilerOptionFromSystemProperty(
    843                 StringPrintf("dalvik.vm.isa.%s.features", isa).c_str(),
    844                 "--instruction-set-features=",
    845                 false,
    846                 cmd);
    847 
    848         std::string error_msg;
    849         bool result = Exec(cmd, &error_msg);
    850         if (!result) {
    851             LOG(ERROR) << "Could not generate boot image: " << error_msg;
    852         }
    853         return result;
    854     }
    855 
    856     static const char* ParseNull(const char* arg) {
    857         return (strcmp(arg, "!") == 0) ? nullptr : arg;
    858     }
    859 
    860     bool ShouldSkipPreopt() const {
    861         // There's one thing we have to be careful about: we may/will be asked to compile an app
    862         // living in the system image. This may be a valid request - if the app wasn't compiled,
    863         // e.g., if the system image wasn't large enough to include preopted files. However, the
    864         // data we have is from the old system, so the driver (the OTA service) can't actually
    865         // know. Thus, we will get requests for apps that have preopted components. To avoid
    866         // duplication (we'd generate files that are not used and are *not* cleaned up), do two
    867         // simple checks:
    868         //
    869         // 1) Does the apk_path start with the value of ANDROID_ROOT? (~in the system image)
    870         //    (For simplicity, assume the value of ANDROID_ROOT does not contain a symlink.)
    871         //
    872         // 2) If you replace the name in the apk_path with "oat," does the path exist?
    873         //    (=have a subdirectory for preopted files)
    874         //
    875         // If the answer to both is yes, skip the dexopt.
    876         //
    877         // Note: while one may think it's OK to call dexopt and it will fail (because APKs should
    878         //       be stripped), that's not true for APKs signed outside the build system (so the
    879         //       jar content must be exactly the same).
    880 
    881         //       (This is ugly as it's the only thing where we need to understand the contents
    882         //        of package_parameters_, but it beats postponing the decision or using the call-
    883         //        backs to do weird things.)
    884         const char* apk_path = package_parameters_.apk_path;
    885         CHECK(apk_path != nullptr);
    886         if (StartsWith(apk_path, android_root_.c_str())) {
    887             const char* last_slash = strrchr(apk_path, '/');
    888             if (last_slash != nullptr) {
    889                 std::string path(apk_path, last_slash - apk_path + 1);
    890                 CHECK(EndsWith(path, "/"));
    891                 path = path + "oat";
    892                 if (access(path.c_str(), F_OK) == 0) {
    893                     return true;
    894                 }
    895             }
    896         }
    897 
    898         // Another issue is unavailability of files in the new system. If the partition
    899         // layout changes, otapreopt_chroot may not know about this. Then files from that
    900         // partition will not be available and fail to build. This is problematic, as
    901         // this tool will wipe the OTA artifact cache and try again (for robustness after
    902         // a failed OTA with remaining cache artifacts).
    903         if (access(apk_path, F_OK) != 0) {
    904             LOG(WARNING) << "Skipping preopt of non-existing package " << apk_path;
    905             return true;
    906         }
    907 
    908         return false;
    909     }
    910 
    911     // Run dexopt with the parameters of package_parameters_.
    912     int Dexopt() {
    913         return dexopt(package_parameters_.apk_path,
    914                       package_parameters_.uid,
    915                       package_parameters_.pkgName,
    916                       package_parameters_.instruction_set,
    917                       package_parameters_.dexopt_needed,
    918                       package_parameters_.oat_dir,
    919                       package_parameters_.dexopt_flags,
    920                       package_parameters_.compiler_filter,
    921                       package_parameters_.volume_uuid,
    922                       package_parameters_.shared_libraries,
    923                       package_parameters_.se_info,
    924                       package_parameters_.downgrade);
    925     }
    926 
    927     int RunPreopt() {
    928         if (ShouldSkipPreopt()) {
    929             return 0;
    930         }
    931 
    932         int dexopt_result = Dexopt();
    933         if (dexopt_result == 0) {
    934             return 0;
    935         }
    936 
    937         // If the dexopt failed, we may have a stale boot image from a previous OTA run.
    938         // Then regenerate and retry.
    939         if (WEXITSTATUS(dexopt_result) ==
    940                 static_cast<int>(art::dex2oat::ReturnCode::kCreateRuntime)) {
    941             if (!PrepareBootImage(/* force */ true)) {
    942                 LOG(ERROR) << "Forced boot image creating failed. Original error return was "
    943                         << dexopt_result;
    944                 return dexopt_result;
    945             }
    946 
    947             int dexopt_result_boot_image_retry = Dexopt();
    948             if (dexopt_result_boot_image_retry == 0) {
    949                 return 0;
    950             }
    951         }
    952 
    953         // If this was a profile-guided run, we may have profile version issues. Try to downgrade,
    954         // if possible.
    955         if ((package_parameters_.dexopt_flags & DEXOPT_PROFILE_GUIDED) == 0) {
    956             return dexopt_result;
    957         }
    958 
    959         LOG(WARNING) << "Downgrading compiler filter in an attempt to progress compilation";
    960         package_parameters_.dexopt_flags &= ~DEXOPT_PROFILE_GUIDED;
    961         return Dexopt();
    962     }
    963 
    964     ////////////////////////////////////
    965     // Helpers, mostly taken from ART //
    966     ////////////////////////////////////
    967 
    968     // Wrapper on fork/execv to run a command in a subprocess.
    969     static bool Exec(const std::vector<std::string>& arg_vector, std::string* error_msg) {
    970         const std::string command_line = Join(arg_vector, ' ');
    971 
    972         CHECK_GE(arg_vector.size(), 1U) << command_line;
    973 
    974         // Convert the args to char pointers.
    975         const char* program = arg_vector[0].c_str();
    976         std::vector<char*> args;
    977         for (size_t i = 0; i < arg_vector.size(); ++i) {
    978             const std::string& arg = arg_vector[i];
    979             char* arg_str = const_cast<char*>(arg.c_str());
    980             CHECK(arg_str != nullptr) << i;
    981             args.push_back(arg_str);
    982         }
    983         args.push_back(nullptr);
    984 
    985         // Fork and exec.
    986         pid_t pid = fork();
    987         if (pid == 0) {
    988             // No allocation allowed between fork and exec.
    989 
    990             // Change process groups, so we don't get reaped by ProcessManager.
    991             setpgid(0, 0);
    992 
    993             execv(program, &args[0]);
    994 
    995             PLOG(ERROR) << "Failed to execv(" << command_line << ")";
    996             // _exit to avoid atexit handlers in child.
    997             _exit(1);
    998         } else {
    999             if (pid == -1) {
   1000                 *error_msg = StringPrintf("Failed to execv(%s) because fork failed: %s",
   1001                         command_line.c_str(), strerror(errno));
   1002                 return false;
   1003             }
   1004 
   1005             // wait for subprocess to finish
   1006             int status;
   1007             pid_t got_pid = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0));
   1008             if (got_pid != pid) {
   1009                 *error_msg = StringPrintf("Failed after fork for execv(%s) because waitpid failed: "
   1010                         "wanted %d, got %d: %s",
   1011                         command_line.c_str(), pid, got_pid, strerror(errno));
   1012                 return false;
   1013             }
   1014             if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
   1015                 *error_msg = StringPrintf("Failed execv(%s) because non-0 exit status",
   1016                         command_line.c_str());
   1017                 return false;
   1018             }
   1019         }
   1020         return true;
   1021     }
   1022 
   1023     // Choose a random relocation offset. Taken from art/runtime/gc/image_space.cc.
   1024     static int32_t ChooseRelocationOffsetDelta(int32_t min_delta, int32_t max_delta) {
   1025         constexpr size_t kPageSize = PAGE_SIZE;
   1026         CHECK_EQ(min_delta % kPageSize, 0u);
   1027         CHECK_EQ(max_delta % kPageSize, 0u);
   1028         CHECK_LT(min_delta, max_delta);
   1029 
   1030         std::default_random_engine generator;
   1031         generator.seed(GetSeed());
   1032         std::uniform_int_distribution<int32_t> distribution(min_delta, max_delta);
   1033         int32_t r = distribution(generator);
   1034         if (r % 2 == 0) {
   1035             r = RoundUp(r, kPageSize);
   1036         } else {
   1037             r = RoundDown(r, kPageSize);
   1038         }
   1039         CHECK_LE(min_delta, r);
   1040         CHECK_GE(max_delta, r);
   1041         CHECK_EQ(r % kPageSize, 0u);
   1042         return r;
   1043     }
   1044 
   1045     static uint64_t GetSeed() {
   1046 #ifdef __BIONIC__
   1047         // Bionic exposes arc4random, use it.
   1048         uint64_t random_data;
   1049         arc4random_buf(&random_data, sizeof(random_data));
   1050         return random_data;
   1051 #else
   1052 #error "This is only supposed to run with bionic. Otherwise, implement..."
   1053 #endif
   1054     }
   1055 
   1056     void AddCompilerOptionFromSystemProperty(const char* system_property,
   1057             const char* prefix,
   1058             bool runtime,
   1059             std::vector<std::string>& out) const {
   1060         const std::string* value = system_properties_.GetProperty(system_property);
   1061         if (value != nullptr) {
   1062             if (runtime) {
   1063                 out.push_back("--runtime-arg");
   1064             }
   1065             if (prefix != nullptr) {
   1066                 out.push_back(StringPrintf("%s%s", prefix, value->c_str()));
   1067             } else {
   1068                 out.push_back(*value);
   1069             }
   1070         }
   1071     }
   1072 
   1073     static constexpr const char* kBootClassPathPropertyName = "BOOTCLASSPATH";
   1074     static constexpr const char* kAndroidRootPathPropertyName = "ANDROID_ROOT";
   1075     static constexpr const char* kAndroidDataPathPropertyName = "ANDROID_DATA";
   1076     // The index of the instruction-set string inside the package parameters. Needed for
   1077     // some special-casing that requires knowledge of the instruction-set.
   1078     static constexpr size_t kISAIndex = 3;
   1079 
   1080     // Stores the system properties read out of the B partition. We need to use these properties
   1081     // to compile, instead of the A properties we could get from init/get_property.
   1082     SystemProperties system_properties_;
   1083 
   1084     // Some select properties that are always needed.
   1085     std::string target_slot_;
   1086     std::string android_root_;
   1087     std::string android_data_;
   1088     std::string boot_classpath_;
   1089     std::string asec_mountpoint_;
   1090 
   1091     Parameters package_parameters_;
   1092 
   1093     // Store environment values we need to set.
   1094     std::vector<std::string> environ_;
   1095 };
   1096 
   1097 OTAPreoptService gOps;
   1098 
   1099 ////////////////////////
   1100 // Plug-in functions. //
   1101 ////////////////////////
   1102 
   1103 int get_property(const char *key, char *value, const char *default_value) {
   1104     return gOps.GetProperty(key, value, default_value);
   1105 }
   1106 
   1107 // Compute the output path of
   1108 bool calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir,
   1109                              const char *apk_path,
   1110                              const char *instruction_set) {
   1111     const char *file_name_start;
   1112     const char *file_name_end;
   1113 
   1114     file_name_start = strrchr(apk_path, '/');
   1115     if (file_name_start == nullptr) {
   1116         ALOGE("apk_path '%s' has no '/'s in it\n", apk_path);
   1117         return false;
   1118     }
   1119     file_name_end = strrchr(file_name_start, '.');
   1120     if (file_name_end == nullptr) {
   1121         ALOGE("apk_path '%s' has no extension\n", apk_path);
   1122         return false;
   1123     }
   1124 
   1125     // Calculate file_name
   1126     file_name_start++;  // Move past '/', is valid as file_name_end is valid.
   1127     size_t file_name_len = file_name_end - file_name_start;
   1128     std::string file_name(file_name_start, file_name_len);
   1129 
   1130     // <apk_parent_dir>/oat/<isa>/<file_name>.odex.b
   1131     snprintf(path,
   1132              PKG_PATH_MAX,
   1133              "%s/%s/%s.odex.%s",
   1134              oat_dir,
   1135              instruction_set,
   1136              file_name.c_str(),
   1137              gOps.GetTargetSlot().c_str());
   1138     return true;
   1139 }
   1140 
   1141 /*
   1142  * Computes the odex file for the given apk_path and instruction_set.
   1143  * /system/framework/whatever.jar -> /system/framework/oat/<isa>/whatever.odex
   1144  *
   1145  * Returns false if it failed to determine the odex file path.
   1146  */
   1147 bool calculate_odex_file_path(char path[PKG_PATH_MAX], const char *apk_path,
   1148                               const char *instruction_set) {
   1149     const char *path_end = strrchr(apk_path, '/');
   1150     if (path_end == nullptr) {
   1151         ALOGE("apk_path '%s' has no '/'s in it?!\n", apk_path);
   1152         return false;
   1153     }
   1154     std::string path_component(apk_path, path_end - apk_path);
   1155 
   1156     const char *name_begin = path_end + 1;
   1157     const char *extension_start = strrchr(name_begin, '.');
   1158     if (extension_start == nullptr) {
   1159         ALOGE("apk_path '%s' has no extension.\n", apk_path);
   1160         return false;
   1161     }
   1162     std::string name_component(name_begin, extension_start - name_begin);
   1163 
   1164     std::string new_path = StringPrintf("%s/oat/%s/%s.odex.%s",
   1165                                         path_component.c_str(),
   1166                                         instruction_set,
   1167                                         name_component.c_str(),
   1168                                         gOps.GetTargetSlot().c_str());
   1169     if (new_path.length() >= PKG_PATH_MAX) {
   1170         LOG(ERROR) << "apk_path of " << apk_path << " is too long: " << new_path;
   1171         return false;
   1172     }
   1173     strcpy(path, new_path.c_str());
   1174     return true;
   1175 }
   1176 
   1177 bool create_cache_path(char path[PKG_PATH_MAX],
   1178                        const char *src,
   1179                        const char *instruction_set) {
   1180     size_t srclen = strlen(src);
   1181 
   1182         /* demand that we are an absolute path */
   1183     if ((src == 0) || (src[0] != '/') || strstr(src,"..")) {
   1184         return false;
   1185     }
   1186 
   1187     if (srclen > PKG_PATH_MAX) {        // XXX: PKG_NAME_MAX?
   1188         return false;
   1189     }
   1190 
   1191     std::string from_src = std::string(src + 1);
   1192     std::replace(from_src.begin(), from_src.end(), '/', '@');
   1193 
   1194     std::string assembled_path = StringPrintf("%s/%s/%s/%s%s",
   1195                                               gOps.GetOTADataDirectory().c_str(),
   1196                                               DALVIK_CACHE,
   1197                                               instruction_set,
   1198                                               from_src.c_str(),
   1199                                               DALVIK_CACHE_POSTFIX);
   1200 
   1201     if (assembled_path.length() + 1 > PKG_PATH_MAX) {
   1202         return false;
   1203     }
   1204     strcpy(path, assembled_path.c_str());
   1205 
   1206     return true;
   1207 }
   1208 
   1209 static int log_callback(int type, const char *fmt, ...) {
   1210     va_list ap;
   1211     int priority;
   1212 
   1213     switch (type) {
   1214         case SELINUX_WARNING:
   1215             priority = ANDROID_LOG_WARN;
   1216             break;
   1217         case SELINUX_INFO:
   1218             priority = ANDROID_LOG_INFO;
   1219             break;
   1220         default:
   1221             priority = ANDROID_LOG_ERROR;
   1222             break;
   1223     }
   1224     va_start(ap, fmt);
   1225     LOG_PRI_VA(priority, "SELinux", fmt, ap);
   1226     va_end(ap);
   1227     return 0;
   1228 }
   1229 
   1230 static int otapreopt_main(const int argc, char *argv[]) {
   1231     int selinux_enabled = (is_selinux_enabled() > 0);
   1232 
   1233     setenv("ANDROID_LOG_TAGS", "*:v", 1);
   1234     android::base::InitLogging(argv);
   1235 
   1236     if (argc < 2) {
   1237         ALOGE("Expecting parameters");
   1238         exit(1);
   1239     }
   1240 
   1241     union selinux_callback cb;
   1242     cb.func_log = log_callback;
   1243     selinux_set_callback(SELINUX_CB_LOG, cb);
   1244 
   1245     if (selinux_enabled && selinux_status_open(true) < 0) {
   1246         ALOGE("Could not open selinux status; exiting.\n");
   1247         exit(1);
   1248     }
   1249 
   1250     int ret = android::installd::gOps.Main(argc, argv);
   1251 
   1252     return ret;
   1253 }
   1254 
   1255 }  // namespace installd
   1256 }  // namespace android
   1257 
   1258 int main(const int argc, char *argv[]) {
   1259     return android::installd::otapreopt_main(argc, argv);
   1260 }
   1261