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