Home | History | Annotate | Download | only in updater
      1 /*
      2  * Copyright (C) 2009 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 "updater/install.h"
     18 
     19 #include <ctype.h>
     20 #include <errno.h>
     21 #include <fcntl.h>
     22 #include <ftw.h>
     23 #include <inttypes.h>
     24 #include <stdarg.h>
     25 #include <stdio.h>
     26 #include <stdlib.h>
     27 #include <string.h>
     28 #include <sys/capability.h>
     29 #include <sys/mount.h>
     30 #include <sys/stat.h>
     31 #include <sys/types.h>
     32 #include <sys/wait.h>
     33 #include <sys/xattr.h>
     34 #include <time.h>
     35 #include <unistd.h>
     36 #include <utime.h>
     37 
     38 #include <memory>
     39 #include <string>
     40 #include <vector>
     41 
     42 #include <android-base/file.h>
     43 #include <android-base/logging.h>
     44 #include <android-base/parsedouble.h>
     45 #include <android-base/parseint.h>
     46 #include <android-base/properties.h>
     47 #include <android-base/stringprintf.h>
     48 #include <android-base/strings.h>
     49 #include <android-base/unique_fd.h>
     50 #include <applypatch/applypatch.h>
     51 #include <bootloader_message/bootloader_message.h>
     52 #include <ext4_utils/wipe.h>
     53 #include <openssl/sha.h>
     54 #include <selinux/label.h>
     55 #include <selinux/selinux.h>
     56 #include <tune2fs.h>
     57 #include <ziparchive/zip_archive.h>
     58 
     59 #include "edify/expr.h"
     60 #include "otautil/dirutil.h"
     61 #include "otautil/error_code.h"
     62 #include "otautil/mounts.h"
     63 #include "otautil/print_sha1.h"
     64 #include "otautil/sysutil.h"
     65 #include "updater/updater.h"
     66 
     67 // Send over the buffer to recovery though the command pipe.
     68 static void uiPrint(State* state, const std::string& buffer) {
     69   UpdaterInfo* ui = static_cast<UpdaterInfo*>(state->cookie);
     70 
     71   // "line1\nline2\n" will be split into 3 tokens: "line1", "line2" and "".
     72   // So skip sending empty strings to UI.
     73   std::vector<std::string> lines = android::base::Split(buffer, "\n");
     74   for (auto& line : lines) {
     75     if (!line.empty()) {
     76       fprintf(ui->cmd_pipe, "ui_print %s\n", line.c_str());
     77     }
     78   }
     79 
     80   // On the updater side, we need to dump the contents to stderr (which has
     81   // been redirected to the log file). Because the recovery will only print
     82   // the contents to screen when processing pipe command ui_print.
     83   LOG(INFO) << buffer;
     84 }
     85 
     86 void uiPrintf(State* _Nonnull state, const char* _Nonnull format, ...) {
     87   std::string error_msg;
     88 
     89   va_list ap;
     90   va_start(ap, format);
     91   android::base::StringAppendV(&error_msg, format, ap);
     92   va_end(ap);
     93 
     94   uiPrint(state, error_msg);
     95 }
     96 
     97 // This is the updater side handler for ui_print() in edify script. Contents will be sent over to
     98 // the recovery side for on-screen display.
     99 Value* UIPrintFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
    100   std::vector<std::string> args;
    101   if (!ReadArgs(state, argv, &args)) {
    102     return ErrorAbort(state, kArgsParsingFailure, "%s(): Failed to parse the argument(s)", name);
    103   }
    104 
    105   std::string buffer = android::base::Join(args, "");
    106   uiPrint(state, buffer);
    107   return StringValue(buffer);
    108 }
    109 
    110 // package_extract_file(package_file[, dest_file])
    111 //   Extracts a single package_file from the update package and writes it to dest_file,
    112 //   overwriting existing files if necessary. Without the dest_file argument, returns the
    113 //   contents of the package file as a binary blob.
    114 Value* PackageExtractFileFn(const char* name, State* state,
    115                             const std::vector<std::unique_ptr<Expr>>& argv) {
    116   if (argv.size() < 1 || argv.size() > 2) {
    117     return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1 or 2 args, got %zu", name,
    118                       argv.size());
    119   }
    120 
    121   if (argv.size() == 2) {
    122     // The two-argument version extracts to a file.
    123 
    124     std::vector<std::string> args;
    125     if (!ReadArgs(state, argv, &args)) {
    126       return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse %zu args", name,
    127                         argv.size());
    128     }
    129     const std::string& zip_path = args[0];
    130     const std::string& dest_path = args[1];
    131 
    132     ZipArchiveHandle za = static_cast<UpdaterInfo*>(state->cookie)->package_zip;
    133     ZipString zip_string_path(zip_path.c_str());
    134     ZipEntry entry;
    135     if (FindEntry(za, zip_string_path, &entry) != 0) {
    136       LOG(ERROR) << name << ": no " << zip_path << " in package";
    137       return StringValue("");
    138     }
    139 
    140     android::base::unique_fd fd(TEMP_FAILURE_RETRY(
    141         open(dest_path.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)));
    142     if (fd == -1) {
    143       PLOG(ERROR) << name << ": can't open " << dest_path << " for write";
    144       return StringValue("");
    145     }
    146 
    147     bool success = true;
    148     int32_t ret = ExtractEntryToFile(za, &entry, fd);
    149     if (ret != 0) {
    150       LOG(ERROR) << name << ": Failed to extract entry \"" << zip_path << "\" ("
    151                  << entry.uncompressed_length << " bytes) to \"" << dest_path
    152                  << "\": " << ErrorCodeString(ret);
    153       success = false;
    154     }
    155     if (fsync(fd) == -1) {
    156       PLOG(ERROR) << "fsync of \"" << dest_path << "\" failed";
    157       success = false;
    158     }
    159 
    160     if (close(fd.release()) != 0) {
    161       PLOG(ERROR) << "close of \"" << dest_path << "\" failed";
    162       success = false;
    163     }
    164 
    165     return StringValue(success ? "t" : "");
    166   } else {
    167     // The one-argument version returns the contents of the file as the result.
    168 
    169     std::vector<std::string> args;
    170     if (!ReadArgs(state, argv, &args)) {
    171       return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse %zu args", name,
    172                         argv.size());
    173     }
    174     const std::string& zip_path = args[0];
    175 
    176     ZipArchiveHandle za = static_cast<UpdaterInfo*>(state->cookie)->package_zip;
    177     ZipString zip_string_path(zip_path.c_str());
    178     ZipEntry entry;
    179     if (FindEntry(za, zip_string_path, &entry) != 0) {
    180       return ErrorAbort(state, kPackageExtractFileFailure, "%s(): no %s in package", name,
    181                         zip_path.c_str());
    182     }
    183 
    184     std::string buffer;
    185     buffer.resize(entry.uncompressed_length);
    186 
    187     int32_t ret =
    188         ExtractToMemory(za, &entry, reinterpret_cast<uint8_t*>(&buffer[0]), buffer.size());
    189     if (ret != 0) {
    190       return ErrorAbort(state, kPackageExtractFileFailure,
    191                         "%s: Failed to extract entry \"%s\" (%zu bytes) to memory: %s", name,
    192                         zip_path.c_str(), buffer.size(), ErrorCodeString(ret));
    193     }
    194 
    195     return new Value(Value::Type::BLOB, buffer);
    196   }
    197 }
    198 
    199 // patch_partition_check(target_partition, source_partition)
    200 //   Checks if the target and source partitions have the desired checksums to be patched. It returns
    201 //   directly, if the target partition already has the expected checksum. Otherwise it in turn
    202 //   checks the integrity of the source partition and the backup file on /cache.
    203 //
    204 // For example, patch_partition_check(
    205 //     "EMMC:/dev/block/boot:12342568:8aaacf187a6929d0e9c3e9e46ea7ff495b43424d",
    206 //     "EMMC:/dev/block/boot:12363048:06b0b16299dcefc94900efed01e0763ff644ffa4")
    207 Value* PatchPartitionCheckFn(const char* name, State* state,
    208                              const std::vector<std::unique_ptr<Expr>>& argv) {
    209   if (argv.size() != 2) {
    210     return ErrorAbort(state, kArgsParsingFailure,
    211                       "%s(): Invalid number of args (expected 2, got %zu)", name, argv.size());
    212   }
    213 
    214   std::vector<std::string> args;
    215   if (!ReadArgs(state, argv, &args, 0, 2)) {
    216     return ErrorAbort(state, kArgsParsingFailure, "%s(): Failed to parse the argument(s)", name);
    217   }
    218 
    219   std::string err;
    220   auto target = Partition::Parse(args[0], &err);
    221   if (!target) {
    222     return ErrorAbort(state, kArgsParsingFailure, "%s(): Failed to parse target \"%s\": %s", name,
    223                       args[0].c_str(), err.c_str());
    224   }
    225 
    226   auto source = Partition::Parse(args[1], &err);
    227   if (!source) {
    228     return ErrorAbort(state, kArgsParsingFailure, "%s(): Failed to parse source \"%s\": %s", name,
    229                       args[1].c_str(), err.c_str());
    230   }
    231 
    232   bool result = PatchPartitionCheck(target, source);
    233   return StringValue(result ? "t" : "");
    234 }
    235 
    236 // patch_partition(target, source, patch)
    237 //   Applies the given patch to the source partition, and writes the result to the target partition.
    238 //
    239 // For example, patch_partition(
    240 //     "EMMC:/dev/block/boot:12342568:8aaacf187a6929d0e9c3e9e46ea7ff495b43424d",
    241 //     "EMMC:/dev/block/boot:12363048:06b0b16299dcefc94900efed01e0763ff644ffa4",
    242 //     package_extract_file("boot.img.p"))
    243 Value* PatchPartitionFn(const char* name, State* state,
    244                         const std::vector<std::unique_ptr<Expr>>& argv) {
    245   if (argv.size() != 3) {
    246     return ErrorAbort(state, kArgsParsingFailure,
    247                       "%s(): Invalid number of args (expected 3, got %zu)", name, argv.size());
    248   }
    249 
    250   std::vector<std::string> args;
    251   if (!ReadArgs(state, argv, &args, 0, 2)) {
    252     return ErrorAbort(state, kArgsParsingFailure, "%s(): Failed to parse the argument(s)", name);
    253   }
    254 
    255   std::string err;
    256   auto target = Partition::Parse(args[0], &err);
    257   if (!target) {
    258     return ErrorAbort(state, kArgsParsingFailure, "%s(): Failed to parse target \"%s\": %s", name,
    259                       args[0].c_str(), err.c_str());
    260   }
    261 
    262   auto source = Partition::Parse(args[1], &err);
    263   if (!source) {
    264     return ErrorAbort(state, kArgsParsingFailure, "%s(): Failed to parse source \"%s\": %s", name,
    265                       args[1].c_str(), err.c_str());
    266   }
    267 
    268   std::vector<std::unique_ptr<Value>> values;
    269   if (!ReadValueArgs(state, argv, &values, 2, 1) || values[0]->type != Value::Type::BLOB) {
    270     return ErrorAbort(state, kArgsParsingFailure, "%s(): Invalid patch arg", name);
    271   }
    272 
    273   bool result = PatchPartition(target, source, *values[0], nullptr);
    274   return StringValue(result ? "t" : "");
    275 }
    276 
    277 // mount(fs_type, partition_type, location, mount_point)
    278 // mount(fs_type, partition_type, location, mount_point, mount_options)
    279 
    280 //    fs_type="ext4"   partition_type="EMMC"    location=device
    281 Value* MountFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
    282   if (argv.size() != 4 && argv.size() != 5) {
    283     return ErrorAbort(state, kArgsParsingFailure, "%s() expects 4-5 args, got %zu", name,
    284                       argv.size());
    285   }
    286 
    287   std::vector<std::string> args;
    288   if (!ReadArgs(state, argv, &args)) {
    289     return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name);
    290   }
    291   const std::string& fs_type = args[0];
    292   const std::string& partition_type = args[1];
    293   const std::string& location = args[2];
    294   const std::string& mount_point = args[3];
    295   std::string mount_options;
    296 
    297   if (argv.size() == 5) {
    298     mount_options = args[4];
    299   }
    300 
    301   if (fs_type.empty()) {
    302     return ErrorAbort(state, kArgsParsingFailure, "fs_type argument to %s() can't be empty", name);
    303   }
    304   if (partition_type.empty()) {
    305     return ErrorAbort(state, kArgsParsingFailure, "partition_type argument to %s() can't be empty",
    306                       name);
    307   }
    308   if (location.empty()) {
    309     return ErrorAbort(state, kArgsParsingFailure, "location argument to %s() can't be empty", name);
    310   }
    311   if (mount_point.empty()) {
    312     return ErrorAbort(state, kArgsParsingFailure, "mount_point argument to %s() can't be empty",
    313                       name);
    314   }
    315 
    316   {
    317     char* secontext = nullptr;
    318 
    319     if (sehandle) {
    320       selabel_lookup(sehandle, &secontext, mount_point.c_str(), 0755);
    321       setfscreatecon(secontext);
    322     }
    323 
    324     mkdir(mount_point.c_str(), 0755);
    325 
    326     if (secontext) {
    327       freecon(secontext);
    328       setfscreatecon(nullptr);
    329     }
    330   }
    331 
    332   if (mount(location.c_str(), mount_point.c_str(), fs_type.c_str(),
    333             MS_NOATIME | MS_NODEV | MS_NODIRATIME, mount_options.c_str()) < 0) {
    334     uiPrintf(state, "%s: Failed to mount %s at %s: %s", name, location.c_str(), mount_point.c_str(),
    335              strerror(errno));
    336     return StringValue("");
    337   }
    338 
    339   return StringValue(mount_point);
    340 }
    341 
    342 // is_mounted(mount_point)
    343 Value* IsMountedFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
    344   if (argv.size() != 1) {
    345     return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1 arg, got %zu", name, argv.size());
    346   }
    347 
    348   std::vector<std::string> args;
    349   if (!ReadArgs(state, argv, &args)) {
    350     return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name);
    351   }
    352   const std::string& mount_point = args[0];
    353   if (mount_point.empty()) {
    354     return ErrorAbort(state, kArgsParsingFailure,
    355                       "mount_point argument to unmount() can't be empty");
    356   }
    357 
    358   scan_mounted_volumes();
    359   MountedVolume* vol = find_mounted_volume_by_mount_point(mount_point.c_str());
    360   if (vol == nullptr) {
    361     return StringValue("");
    362   }
    363 
    364   return StringValue(mount_point);
    365 }
    366 
    367 Value* UnmountFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
    368   if (argv.size() != 1) {
    369     return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1 arg, got %zu", name, argv.size());
    370   }
    371   std::vector<std::string> args;
    372   if (!ReadArgs(state, argv, &args)) {
    373     return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name);
    374   }
    375   const std::string& mount_point = args[0];
    376   if (mount_point.empty()) {
    377     return ErrorAbort(state, kArgsParsingFailure,
    378                       "mount_point argument to unmount() can't be empty");
    379   }
    380 
    381   scan_mounted_volumes();
    382   MountedVolume* vol = find_mounted_volume_by_mount_point(mount_point.c_str());
    383   if (vol == nullptr) {
    384     uiPrintf(state, "Failed to unmount %s: No such volume", mount_point.c_str());
    385     return nullptr;
    386   } else {
    387     int ret = unmount_mounted_volume(vol);
    388     if (ret != 0) {
    389       uiPrintf(state, "Failed to unmount %s: %s", mount_point.c_str(), strerror(errno));
    390     }
    391   }
    392 
    393   return StringValue(mount_point);
    394 }
    395 
    396 static int exec_cmd(const std::vector<std::string>& args) {
    397   CHECK(!args.empty());
    398   auto argv = StringVectorToNullTerminatedArray(args);
    399 
    400   pid_t child;
    401   if ((child = vfork()) == 0) {
    402     execv(argv[0], argv.data());
    403     _exit(EXIT_FAILURE);
    404   }
    405 
    406   int status;
    407   waitpid(child, &status, 0);
    408   if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
    409     LOG(ERROR) << args[0] << " failed with status " << WEXITSTATUS(status);
    410   }
    411   return WEXITSTATUS(status);
    412 }
    413 
    414 // format(fs_type, partition_type, location, fs_size, mount_point)
    415 //
    416 //    fs_type="ext4"  partition_type="EMMC"  location=device  fs_size=<bytes> mount_point=<location>
    417 //    fs_type="f2fs"  partition_type="EMMC"  location=device  fs_size=<bytes> mount_point=<location>
    418 //    if fs_size == 0, then make fs uses the entire partition.
    419 //    if fs_size > 0, that is the size to use
    420 //    if fs_size < 0, then reserve that many bytes at the end of the partition (not for "f2fs")
    421 Value* FormatFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
    422   if (argv.size() != 5) {
    423     return ErrorAbort(state, kArgsParsingFailure, "%s() expects 5 args, got %zu", name,
    424                       argv.size());
    425   }
    426 
    427   std::vector<std::string> args;
    428   if (!ReadArgs(state, argv, &args)) {
    429     return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name);
    430   }
    431   const std::string& fs_type = args[0];
    432   const std::string& partition_type = args[1];
    433   const std::string& location = args[2];
    434   const std::string& fs_size = args[3];
    435   const std::string& mount_point = args[4];
    436 
    437   if (fs_type.empty()) {
    438     return ErrorAbort(state, kArgsParsingFailure, "fs_type argument to %s() can't be empty", name);
    439   }
    440   if (partition_type.empty()) {
    441     return ErrorAbort(state, kArgsParsingFailure, "partition_type argument to %s() can't be empty",
    442                       name);
    443   }
    444   if (location.empty()) {
    445     return ErrorAbort(state, kArgsParsingFailure, "location argument to %s() can't be empty", name);
    446   }
    447   if (mount_point.empty()) {
    448     return ErrorAbort(state, kArgsParsingFailure, "mount_point argument to %s() can't be empty",
    449                       name);
    450   }
    451 
    452   int64_t size;
    453   if (!android::base::ParseInt(fs_size, &size)) {
    454     return ErrorAbort(state, kArgsParsingFailure, "%s: failed to parse int in %s", name,
    455                       fs_size.c_str());
    456   }
    457 
    458   if (fs_type == "ext4") {
    459     std::vector<std::string> mke2fs_args = {
    460       "/system/bin/mke2fs", "-t", "ext4", "-b", "4096", location
    461     };
    462     if (size != 0) {
    463       mke2fs_args.push_back(std::to_string(size / 4096LL));
    464     }
    465 
    466     if (auto status = exec_cmd(mke2fs_args); status != 0) {
    467       LOG(ERROR) << name << ": mke2fs failed (" << status << ") on " << location;
    468       return StringValue("");
    469     }
    470 
    471     if (auto status = exec_cmd({ "/system/bin/e2fsdroid", "-e", "-a", mount_point, location });
    472         status != 0) {
    473       LOG(ERROR) << name << ": e2fsdroid failed (" << status << ") on " << location;
    474       return StringValue("");
    475     }
    476     return StringValue(location);
    477   }
    478 
    479   if (fs_type == "f2fs") {
    480     if (size < 0) {
    481       LOG(ERROR) << name << ": fs_size can't be negative for f2fs: " << fs_size;
    482       return StringValue("");
    483     }
    484     std::vector<std::string> f2fs_args = {
    485       "/system/bin/make_f2fs", "-g", "android", "-w", "512", location
    486     };
    487     if (size >= 512) {
    488       f2fs_args.push_back(std::to_string(size / 512));
    489     }
    490     if (auto status = exec_cmd(f2fs_args); status != 0) {
    491       LOG(ERROR) << name << ": make_f2fs failed (" << status << ") on " << location;
    492       return StringValue("");
    493     }
    494 
    495     if (auto status = exec_cmd({ "/system/bin/sload_f2fs", "-t", mount_point, location });
    496         status != 0) {
    497       LOG(ERROR) << name << ": sload_f2fs failed (" << status << ") on " << location;
    498       return StringValue("");
    499     }
    500 
    501     return StringValue(location);
    502   }
    503 
    504   LOG(ERROR) << name << ": unsupported fs_type \"" << fs_type << "\" partition_type \""
    505              << partition_type << "\"";
    506   return nullptr;
    507 }
    508 
    509 Value* ShowProgressFn(const char* name, State* state,
    510                       const std::vector<std::unique_ptr<Expr>>& argv) {
    511   if (argv.size() != 2) {
    512     return ErrorAbort(state, kArgsParsingFailure, "%s() expects 2 args, got %zu", name,
    513                       argv.size());
    514   }
    515 
    516   std::vector<std::string> args;
    517   if (!ReadArgs(state, argv, &args)) {
    518     return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name);
    519   }
    520   const std::string& frac_str = args[0];
    521   const std::string& sec_str = args[1];
    522 
    523   double frac;
    524   if (!android::base::ParseDouble(frac_str.c_str(), &frac)) {
    525     return ErrorAbort(state, kArgsParsingFailure, "%s: failed to parse double in %s", name,
    526                       frac_str.c_str());
    527   }
    528   int sec;
    529   if (!android::base::ParseInt(sec_str.c_str(), &sec)) {
    530     return ErrorAbort(state, kArgsParsingFailure, "%s: failed to parse int in %s", name,
    531                       sec_str.c_str());
    532   }
    533 
    534   UpdaterInfo* ui = static_cast<UpdaterInfo*>(state->cookie);
    535   fprintf(ui->cmd_pipe, "progress %f %d\n", frac, sec);
    536 
    537   return StringValue(frac_str);
    538 }
    539 
    540 Value* SetProgressFn(const char* name, State* state,
    541                      const std::vector<std::unique_ptr<Expr>>& argv) {
    542   if (argv.size() != 1) {
    543     return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1 arg, got %zu", name, argv.size());
    544   }
    545 
    546   std::vector<std::string> args;
    547   if (!ReadArgs(state, argv, &args)) {
    548     return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name);
    549   }
    550   const std::string& frac_str = args[0];
    551 
    552   double frac;
    553   if (!android::base::ParseDouble(frac_str.c_str(), &frac)) {
    554     return ErrorAbort(state, kArgsParsingFailure, "%s: failed to parse double in %s", name,
    555                       frac_str.c_str());
    556   }
    557 
    558   UpdaterInfo* ui = static_cast<UpdaterInfo*>(state->cookie);
    559   fprintf(ui->cmd_pipe, "set_progress %f\n", frac);
    560 
    561   return StringValue(frac_str);
    562 }
    563 
    564 Value* GetPropFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
    565   if (argv.size() != 1) {
    566     return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1 arg, got %zu", name, argv.size());
    567   }
    568   std::string key;
    569   if (!Evaluate(state, argv[0], &key)) {
    570     return nullptr;
    571   }
    572   std::string value = android::base::GetProperty(key, "");
    573 
    574   return StringValue(value);
    575 }
    576 
    577 // file_getprop(file, key)
    578 //
    579 //   interprets 'file' as a getprop-style file (key=value pairs, one
    580 //   per line. # comment lines, blank lines, lines without '=' ignored),
    581 //   and returns the value for 'key' (or "" if it isn't defined).
    582 Value* FileGetPropFn(const char* name, State* state,
    583                      const std::vector<std::unique_ptr<Expr>>& argv) {
    584   if (argv.size() != 2) {
    585     return ErrorAbort(state, kArgsParsingFailure, "%s() expects 2 args, got %zu", name,
    586                       argv.size());
    587   }
    588 
    589   std::vector<std::string> args;
    590   if (!ReadArgs(state, argv, &args)) {
    591     return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name);
    592   }
    593   const std::string& filename = args[0];
    594   const std::string& key = args[1];
    595 
    596   std::string buffer;
    597   if (!android::base::ReadFileToString(filename, &buffer)) {
    598     ErrorAbort(state, kFreadFailure, "%s: failed to read %s", name, filename.c_str());
    599     return nullptr;
    600   }
    601 
    602   std::vector<std::string> lines = android::base::Split(buffer, "\n");
    603   for (size_t i = 0; i < lines.size(); i++) {
    604     std::string line = android::base::Trim(lines[i]);
    605 
    606     // comment or blank line: skip to next line
    607     if (line.empty() || line[0] == '#') {
    608       continue;
    609     }
    610     size_t equal_pos = line.find('=');
    611     if (equal_pos == std::string::npos) {
    612       continue;
    613     }
    614 
    615     // trim whitespace between key and '='
    616     std::string str = android::base::Trim(line.substr(0, equal_pos));
    617 
    618     // not the key we're looking for
    619     if (key != str) continue;
    620 
    621     return StringValue(android::base::Trim(line.substr(equal_pos + 1)));
    622   }
    623 
    624   return StringValue("");
    625 }
    626 
    627 // apply_patch_space(bytes)
    628 Value* ApplyPatchSpaceFn(const char* name, State* state,
    629                          const std::vector<std::unique_ptr<Expr>>& argv) {
    630   if (argv.size() != 1) {
    631     return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1 args, got %zu", name,
    632                       argv.size());
    633   }
    634   std::vector<std::string> args;
    635   if (!ReadArgs(state, argv, &args)) {
    636     return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name);
    637   }
    638   const std::string& bytes_str = args[0];
    639 
    640   size_t bytes;
    641   if (!android::base::ParseUint(bytes_str.c_str(), &bytes)) {
    642     return ErrorAbort(state, kArgsParsingFailure, "%s(): can't parse \"%s\" as byte count", name,
    643                       bytes_str.c_str());
    644   }
    645 
    646   // Skip the cache size check if the update is a retry.
    647   if (state->is_retry || CheckAndFreeSpaceOnCache(bytes)) {
    648     return StringValue("t");
    649   }
    650   return StringValue("");
    651 }
    652 
    653 Value* WipeCacheFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
    654   if (!argv.empty()) {
    655     return ErrorAbort(state, kArgsParsingFailure, "%s() expects no args, got %zu", name,
    656                       argv.size());
    657   }
    658   fprintf(static_cast<UpdaterInfo*>(state->cookie)->cmd_pipe, "wipe_cache\n");
    659   return StringValue("t");
    660 }
    661 
    662 Value* RunProgramFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
    663   if (argv.size() < 1) {
    664     return ErrorAbort(state, kArgsParsingFailure, "%s() expects at least 1 arg", name);
    665   }
    666 
    667   std::vector<std::string> args;
    668   if (!ReadArgs(state, argv, &args)) {
    669     return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name);
    670   }
    671 
    672   auto exec_args = StringVectorToNullTerminatedArray(args);
    673   LOG(INFO) << "about to run program [" << exec_args[0] << "] with " << argv.size() << " args";
    674 
    675   pid_t child = fork();
    676   if (child == 0) {
    677     execv(exec_args[0], exec_args.data());
    678     PLOG(ERROR) << "run_program: execv failed";
    679     _exit(EXIT_FAILURE);
    680   }
    681 
    682   int status;
    683   waitpid(child, &status, 0);
    684   if (WIFEXITED(status)) {
    685     if (WEXITSTATUS(status) != 0) {
    686       LOG(ERROR) << "run_program: child exited with status " << WEXITSTATUS(status);
    687     }
    688   } else if (WIFSIGNALED(status)) {
    689     LOG(ERROR) << "run_program: child terminated by signal " << WTERMSIG(status);
    690   }
    691 
    692   return StringValue(std::to_string(status));
    693 }
    694 
    695 // read_file(filename)
    696 //   Reads a local file 'filename' and returns its contents as a string Value.
    697 Value* ReadFileFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
    698   if (argv.size() != 1) {
    699     return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1 arg, got %zu", name, argv.size());
    700   }
    701 
    702   std::vector<std::string> args;
    703   if (!ReadArgs(state, argv, &args)) {
    704     return ErrorAbort(state, kArgsParsingFailure, "%s(): Failed to parse the argument(s)", name);
    705   }
    706   const std::string& filename = args[0];
    707 
    708   std::string contents;
    709   if (android::base::ReadFileToString(filename, &contents)) {
    710     return new Value(Value::Type::STRING, std::move(contents));
    711   }
    712 
    713   // Leave it to caller to handle the failure.
    714   PLOG(ERROR) << name << ": Failed to read " << filename;
    715   return StringValue("");
    716 }
    717 
    718 // write_value(value, filename)
    719 //   Writes 'value' to 'filename'.
    720 //   Example: write_value("960000", "/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq")
    721 Value* WriteValueFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
    722   if (argv.size() != 2) {
    723     return ErrorAbort(state, kArgsParsingFailure, "%s() expects 2 args, got %zu", name,
    724                       argv.size());
    725   }
    726 
    727   std::vector<std::string> args;
    728   if (!ReadArgs(state, argv, &args)) {
    729     return ErrorAbort(state, kArgsParsingFailure, "%s(): Failed to parse the argument(s)", name);
    730   }
    731 
    732   const std::string& filename = args[1];
    733   if (filename.empty()) {
    734     return ErrorAbort(state, kArgsParsingFailure, "%s(): Filename cannot be empty", name);
    735   }
    736 
    737   const std::string& value = args[0];
    738   if (!android::base::WriteStringToFile(value, filename)) {
    739     PLOG(ERROR) << name << ": Failed to write to \"" << filename << "\"";
    740     return StringValue("");
    741   } else {
    742     return StringValue("t");
    743   }
    744 }
    745 
    746 // Immediately reboot the device.  Recovery is not finished normally,
    747 // so if you reboot into recovery it will re-start applying the
    748 // current package (because nothing has cleared the copy of the
    749 // arguments stored in the BCB).
    750 //
    751 // The argument is the partition name passed to the android reboot
    752 // property.  It can be "recovery" to boot from the recovery
    753 // partition, or "" (empty string) to boot from the regular boot
    754 // partition.
    755 Value* RebootNowFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
    756   if (argv.size() != 2) {
    757     return ErrorAbort(state, kArgsParsingFailure, "%s() expects 2 args, got %zu", name,
    758                       argv.size());
    759   }
    760 
    761   std::vector<std::string> args;
    762   if (!ReadArgs(state, argv, &args)) {
    763     return ErrorAbort(state, kArgsParsingFailure, "%s(): Failed to parse the argument(s)", name);
    764   }
    765   const std::string& filename = args[0];
    766   const std::string& property = args[1];
    767 
    768   // Zero out the 'command' field of the bootloader message. Leave the rest intact.
    769   bootloader_message boot;
    770   std::string err;
    771   if (!read_bootloader_message_from(&boot, filename, &err)) {
    772     LOG(ERROR) << name << "(): Failed to read from \"" << filename << "\": " << err;
    773     return StringValue("");
    774   }
    775   memset(boot.command, 0, sizeof(boot.command));
    776   if (!write_bootloader_message_to(boot, filename, &err)) {
    777     LOG(ERROR) << name << "(): Failed to write to \"" << filename << "\": " << err;
    778     return StringValue("");
    779   }
    780 
    781   reboot("reboot," + property);
    782 
    783   sleep(5);
    784   return ErrorAbort(state, kRebootFailure, "%s() failed to reboot", name);
    785 }
    786 
    787 // Store a string value somewhere that future invocations of recovery
    788 // can access it.  This value is called the "stage" and can be used to
    789 // drive packages that need to do reboots in the middle of
    790 // installation and keep track of where they are in the multi-stage
    791 // install.
    792 //
    793 // The first argument is the block device for the misc partition
    794 // ("/misc" in the fstab), which is where this value is stored.  The
    795 // second argument is the string to store; it should not exceed 31
    796 // bytes.
    797 Value* SetStageFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
    798   if (argv.size() != 2) {
    799     return ErrorAbort(state, kArgsParsingFailure, "%s() expects 2 args, got %zu", name,
    800                       argv.size());
    801   }
    802 
    803   std::vector<std::string> args;
    804   if (!ReadArgs(state, argv, &args)) {
    805     return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name);
    806   }
    807   const std::string& filename = args[0];
    808   const std::string& stagestr = args[1];
    809 
    810   // Store this value in the misc partition, immediately after the
    811   // bootloader message that the main recovery uses to save its
    812   // arguments in case of the device restarting midway through
    813   // package installation.
    814   bootloader_message boot;
    815   std::string err;
    816   if (!read_bootloader_message_from(&boot, filename, &err)) {
    817     LOG(ERROR) << name << "(): Failed to read from \"" << filename << "\": " << err;
    818     return StringValue("");
    819   }
    820   strlcpy(boot.stage, stagestr.c_str(), sizeof(boot.stage));
    821   if (!write_bootloader_message_to(boot, filename, &err)) {
    822     LOG(ERROR) << name << "(): Failed to write to \"" << filename << "\": " << err;
    823     return StringValue("");
    824   }
    825 
    826   return StringValue(filename);
    827 }
    828 
    829 // Return the value most recently saved with SetStageFn.  The argument
    830 // is the block device for the misc partition.
    831 Value* GetStageFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
    832   if (argv.size() != 1) {
    833     return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1 arg, got %zu", name, argv.size());
    834   }
    835 
    836   std::vector<std::string> args;
    837   if (!ReadArgs(state, argv, &args)) {
    838     return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name);
    839   }
    840   const std::string& filename = args[0];
    841 
    842   bootloader_message boot;
    843   std::string err;
    844   if (!read_bootloader_message_from(&boot, filename, &err)) {
    845     LOG(ERROR) << name << "(): Failed to read from \"" << filename << "\": " << err;
    846     return StringValue("");
    847   }
    848 
    849   return StringValue(boot.stage);
    850 }
    851 
    852 Value* WipeBlockDeviceFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
    853   if (argv.size() != 2) {
    854     return ErrorAbort(state, kArgsParsingFailure, "%s() expects 2 args, got %zu", name,
    855                       argv.size());
    856   }
    857 
    858   std::vector<std::string> args;
    859   if (!ReadArgs(state, argv, &args)) {
    860     return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name);
    861   }
    862   const std::string& filename = args[0];
    863   const std::string& len_str = args[1];
    864 
    865   size_t len;
    866   if (!android::base::ParseUint(len_str.c_str(), &len)) {
    867     return nullptr;
    868   }
    869   android::base::unique_fd fd(open(filename.c_str(), O_WRONLY));
    870   if (fd == -1) {
    871     PLOG(ERROR) << "Failed to open " << filename;
    872     return StringValue("");
    873   }
    874 
    875   // The wipe_block_device function in ext4_utils returns 0 on success and 1
    876   // for failure.
    877   int status = wipe_block_device(fd, len);
    878   return StringValue((status == 0) ? "t" : "");
    879 }
    880 
    881 Value* EnableRebootFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
    882   if (!argv.empty()) {
    883     return ErrorAbort(state, kArgsParsingFailure, "%s() expects no args, got %zu", name,
    884                       argv.size());
    885   }
    886   UpdaterInfo* ui = static_cast<UpdaterInfo*>(state->cookie);
    887   fprintf(ui->cmd_pipe, "enable_reboot\n");
    888   return StringValue("t");
    889 }
    890 
    891 Value* Tune2FsFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
    892   if (argv.empty()) {
    893     return ErrorAbort(state, kArgsParsingFailure, "%s() expects args, got %zu", name, argv.size());
    894   }
    895 
    896   std::vector<std::string> args;
    897   if (!ReadArgs(state, argv, &args)) {
    898     return ErrorAbort(state, kArgsParsingFailure, "%s() could not read args", name);
    899   }
    900 
    901   // tune2fs expects the program name as its first arg.
    902   args.insert(args.begin(), "tune2fs");
    903   auto tune2fs_args = StringVectorToNullTerminatedArray(args);
    904 
    905   // tune2fs changes the filesystem parameters on an ext2 filesystem; it returns 0 on success.
    906   if (auto result = tune2fs_main(tune2fs_args.size() - 1, tune2fs_args.data()); result != 0) {
    907     return ErrorAbort(state, kTune2FsFailure, "%s() returned error code %d", name, result);
    908   }
    909   return StringValue("t");
    910 }
    911 
    912 void RegisterInstallFunctions() {
    913   RegisterFunction("mount", MountFn);
    914   RegisterFunction("is_mounted", IsMountedFn);
    915   RegisterFunction("unmount", UnmountFn);
    916   RegisterFunction("format", FormatFn);
    917   RegisterFunction("show_progress", ShowProgressFn);
    918   RegisterFunction("set_progress", SetProgressFn);
    919   RegisterFunction("package_extract_file", PackageExtractFileFn);
    920 
    921   RegisterFunction("getprop", GetPropFn);
    922   RegisterFunction("file_getprop", FileGetPropFn);
    923 
    924   RegisterFunction("apply_patch_space", ApplyPatchSpaceFn);
    925   RegisterFunction("patch_partition", PatchPartitionFn);
    926   RegisterFunction("patch_partition_check", PatchPartitionCheckFn);
    927 
    928   RegisterFunction("wipe_block_device", WipeBlockDeviceFn);
    929 
    930   RegisterFunction("read_file", ReadFileFn);
    931   RegisterFunction("write_value", WriteValueFn);
    932 
    933   RegisterFunction("wipe_cache", WipeCacheFn);
    934 
    935   RegisterFunction("ui_print", UIPrintFn);
    936 
    937   RegisterFunction("run_program", RunProgramFn);
    938 
    939   RegisterFunction("reboot_now", RebootNowFn);
    940   RegisterFunction("get_stage", GetStageFn);
    941   RegisterFunction("set_stage", SetStageFn);
    942 
    943   RegisterFunction("enable_reboot", EnableRebootFn);
    944   RegisterFunction("tune2fs", Tune2FsFn);
    945 }
    946