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 <applypatch/applypatch.h>
     50 #include <bootloader_message/bootloader_message.h>
     51 #include <cutils/android_reboot.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 "mounts.h"
     61 #include "otafault/ota_io.h"
     62 #include "otautil/DirUtil.h"
     63 #include "otautil/error_code.h"
     64 #include "otautil/print_sha1.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     unique_fd fd(TEMP_FAILURE_RETRY(
    141         ota_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 (ota_fsync(fd) == -1) {
    156       PLOG(ERROR) << "fsync of \"" << dest_path << "\" failed";
    157       success = false;
    158     }
    159     if (ota_close(fd) == -1) {
    160       PLOG(ERROR) << "close of \"" << dest_path << "\" failed";
    161       success = false;
    162     }
    163 
    164     return StringValue(success ? "t" : "");
    165   } else {
    166     // The one-argument version returns the contents of the file as the result.
    167 
    168     std::vector<std::string> args;
    169     if (!ReadArgs(state, argv, &args)) {
    170       return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse %zu args", name,
    171                         argv.size());
    172     }
    173     const std::string& zip_path = args[0];
    174 
    175     ZipArchiveHandle za = static_cast<UpdaterInfo*>(state->cookie)->package_zip;
    176     ZipString zip_string_path(zip_path.c_str());
    177     ZipEntry entry;
    178     if (FindEntry(za, zip_string_path, &entry) != 0) {
    179       return ErrorAbort(state, kPackageExtractFileFailure, "%s(): no %s in package", name,
    180                         zip_path.c_str());
    181     }
    182 
    183     std::string buffer;
    184     buffer.resize(entry.uncompressed_length);
    185 
    186     int32_t ret =
    187         ExtractToMemory(za, &entry, reinterpret_cast<uint8_t*>(&buffer[0]), buffer.size());
    188     if (ret != 0) {
    189       return ErrorAbort(state, kPackageExtractFileFailure,
    190                         "%s: Failed to extract entry \"%s\" (%zu bytes) to memory: %s", name,
    191                         zip_path.c_str(), buffer.size(), ErrorCodeString(ret));
    192     }
    193 
    194     return new Value(VAL_BLOB, buffer);
    195   }
    196 }
    197 
    198 // apply_patch(src_file, tgt_file, tgt_sha1, tgt_size, patch1_sha1, patch1_blob, [...])
    199 //   Applies a binary patch to the src_file to produce the tgt_file. If the desired target is the
    200 //   same as the source, pass "-" for tgt_file. tgt_sha1 and tgt_size are the expected final SHA1
    201 //   hash and size of the target file. The remaining arguments must come in pairs: a SHA1 hash (a
    202 //   40-character hex string) and a blob. The blob is the patch to be applied when the source
    203 //   file's current contents have the given SHA1.
    204 //
    205 //   The patching is done in a safe manner that guarantees the target file either has the desired
    206 //   SHA1 hash and size, or it is untouched -- it will not be left in an unrecoverable intermediate
    207 //   state. If the process is interrupted during patching, the target file may be in an intermediate
    208 //   state; a copy exists in the cache partition so restarting the update can successfully update
    209 //   the file.
    210 Value* ApplyPatchFn(const char* name, State* state,
    211                     const std::vector<std::unique_ptr<Expr>>& argv) {
    212   if (argv.size() < 6 || (argv.size() % 2) == 1) {
    213     return ErrorAbort(state, kArgsParsingFailure,
    214                       "%s(): expected at least 6 args and an "
    215                       "even number, got %zu",
    216                       name, argv.size());
    217   }
    218 
    219   std::vector<std::string> args;
    220   if (!ReadArgs(state, argv, &args, 0, 4)) {
    221     return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name);
    222   }
    223   const std::string& source_filename = args[0];
    224   const std::string& target_filename = args[1];
    225   const std::string& target_sha1 = args[2];
    226   const std::string& target_size_str = args[3];
    227 
    228   size_t target_size;
    229   if (!android::base::ParseUint(target_size_str.c_str(), &target_size)) {
    230     return ErrorAbort(state, kArgsParsingFailure, "%s(): can't parse \"%s\" as byte count", name,
    231                       target_size_str.c_str());
    232   }
    233 
    234   int patchcount = (argv.size() - 4) / 2;
    235   std::vector<std::unique_ptr<Value>> arg_values;
    236   if (!ReadValueArgs(state, argv, &arg_values, 4, argv.size() - 4)) {
    237     return nullptr;
    238   }
    239 
    240   for (int i = 0; i < patchcount; ++i) {
    241     if (arg_values[i * 2]->type != VAL_STRING) {
    242       return ErrorAbort(state, kArgsParsingFailure, "%s(): sha-1 #%d is not string", name, i * 2);
    243     }
    244     if (arg_values[i * 2 + 1]->type != VAL_BLOB) {
    245       return ErrorAbort(state, kArgsParsingFailure, "%s(): patch #%d is not blob", name, i * 2 + 1);
    246     }
    247   }
    248 
    249   std::vector<std::string> patch_sha_str;
    250   std::vector<std::unique_ptr<Value>> patches;
    251   for (int i = 0; i < patchcount; ++i) {
    252     patch_sha_str.push_back(arg_values[i * 2]->data);
    253     patches.push_back(std::move(arg_values[i * 2 + 1]));
    254   }
    255 
    256   int result = applypatch(source_filename.c_str(), target_filename.c_str(), target_sha1.c_str(),
    257                           target_size, patch_sha_str, patches, nullptr);
    258 
    259   return StringValue(result == 0 ? "t" : "");
    260 }
    261 
    262 // apply_patch_check(filename, [sha1, ...])
    263 //   Returns true if the contents of filename or the temporary copy in the cache partition (if
    264 //   present) have a SHA-1 checksum equal to one of the given sha1 values. sha1 values are
    265 //   specified as 40 hex digits. This function differs from sha1_check(read_file(filename),
    266 //   sha1 [, ...]) in that it knows to check the cache partition copy, so apply_patch_check() will
    267 //   succeed even if the file was corrupted by an interrupted apply_patch() update.
    268 Value* ApplyPatchCheckFn(const char* name, State* state,
    269                          const std::vector<std::unique_ptr<Expr>>& argv) {
    270   if (argv.size() < 1) {
    271     return ErrorAbort(state, kArgsParsingFailure, "%s(): expected at least 1 arg, got %zu", name,
    272                       argv.size());
    273   }
    274 
    275   std::vector<std::string> args;
    276   if (!ReadArgs(state, argv, &args, 0, 1)) {
    277     return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name);
    278   }
    279   const std::string& filename = args[0];
    280 
    281   std::vector<std::string> sha1s;
    282   if (argv.size() > 1 && !ReadArgs(state, argv, &sha1s, 1, argv.size() - 1)) {
    283     return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name);
    284   }
    285   int result = applypatch_check(filename.c_str(), sha1s);
    286 
    287   return StringValue(result == 0 ? "t" : "");
    288 }
    289 
    290 // sha1_check(data)
    291 //    to return the sha1 of the data (given in the format returned by
    292 //    read_file).
    293 //
    294 // sha1_check(data, sha1_hex, [sha1_hex, ...])
    295 //    returns the sha1 of the file if it matches any of the hex
    296 //    strings passed, or "" if it does not equal any of them.
    297 //
    298 Value* Sha1CheckFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
    299   if (argv.size() < 1) {
    300     return ErrorAbort(state, kArgsParsingFailure, "%s() expects at least 1 arg", name);
    301   }
    302 
    303   std::vector<std::unique_ptr<Value>> args;
    304   if (!ReadValueArgs(state, argv, &args)) {
    305     return nullptr;
    306   }
    307 
    308   if (args[0]->type == VAL_INVALID) {
    309     return StringValue("");
    310   }
    311   uint8_t digest[SHA_DIGEST_LENGTH];
    312   SHA1(reinterpret_cast<const uint8_t*>(args[0]->data.c_str()), args[0]->data.size(), digest);
    313 
    314   if (argv.size() == 1) {
    315     return StringValue(print_sha1(digest));
    316   }
    317 
    318   for (size_t i = 1; i < argv.size(); ++i) {
    319     uint8_t arg_digest[SHA_DIGEST_LENGTH];
    320     if (args[i]->type != VAL_STRING) {
    321       LOG(ERROR) << name << "(): arg " << i << " is not a string; skipping";
    322     } else if (ParseSha1(args[i]->data.c_str(), arg_digest) != 0) {
    323       // Warn about bad args and skip them.
    324       LOG(ERROR) << name << "(): error parsing \"" << args[i]->data << "\" as sha-1; skipping";
    325     } else if (memcmp(digest, arg_digest, SHA_DIGEST_LENGTH) == 0) {
    326       // Found a match.
    327       return args[i].release();
    328     }
    329   }
    330 
    331   // Didn't match any of the hex strings; return false.
    332   return StringValue("");
    333 }
    334 
    335 // mount(fs_type, partition_type, location, mount_point)
    336 // mount(fs_type, partition_type, location, mount_point, mount_options)
    337 
    338 //    fs_type="ext4"   partition_type="EMMC"    location=device
    339 Value* MountFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
    340   if (argv.size() != 4 && argv.size() != 5) {
    341     return ErrorAbort(state, kArgsParsingFailure, "%s() expects 4-5 args, got %zu", name,
    342                       argv.size());
    343   }
    344 
    345   std::vector<std::string> args;
    346   if (!ReadArgs(state, argv, &args)) {
    347     return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name);
    348   }
    349   const std::string& fs_type = args[0];
    350   const std::string& partition_type = args[1];
    351   const std::string& location = args[2];
    352   const std::string& mount_point = args[3];
    353   std::string mount_options;
    354 
    355   if (argv.size() == 5) {
    356     mount_options = args[4];
    357   }
    358 
    359   if (fs_type.empty()) {
    360     return ErrorAbort(state, kArgsParsingFailure, "fs_type argument to %s() can't be empty", name);
    361   }
    362   if (partition_type.empty()) {
    363     return ErrorAbort(state, kArgsParsingFailure, "partition_type argument to %s() can't be empty",
    364                       name);
    365   }
    366   if (location.empty()) {
    367     return ErrorAbort(state, kArgsParsingFailure, "location argument to %s() can't be empty", name);
    368   }
    369   if (mount_point.empty()) {
    370     return ErrorAbort(state, kArgsParsingFailure, "mount_point argument to %s() can't be empty",
    371                       name);
    372   }
    373 
    374   {
    375     char* secontext = nullptr;
    376 
    377     if (sehandle) {
    378       selabel_lookup(sehandle, &secontext, mount_point.c_str(), 0755);
    379       setfscreatecon(secontext);
    380     }
    381 
    382     mkdir(mount_point.c_str(), 0755);
    383 
    384     if (secontext) {
    385       freecon(secontext);
    386       setfscreatecon(nullptr);
    387     }
    388   }
    389 
    390   if (mount(location.c_str(), mount_point.c_str(), fs_type.c_str(),
    391             MS_NOATIME | MS_NODEV | MS_NODIRATIME, mount_options.c_str()) < 0) {
    392     uiPrintf(state, "%s: Failed to mount %s at %s: %s", name, location.c_str(), mount_point.c_str(),
    393              strerror(errno));
    394     return StringValue("");
    395   }
    396 
    397   return StringValue(mount_point);
    398 }
    399 
    400 // is_mounted(mount_point)
    401 Value* IsMountedFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
    402   if (argv.size() != 1) {
    403     return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1 arg, got %zu", name, argv.size());
    404   }
    405 
    406   std::vector<std::string> args;
    407   if (!ReadArgs(state, argv, &args)) {
    408     return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name);
    409   }
    410   const std::string& mount_point = args[0];
    411   if (mount_point.empty()) {
    412     return ErrorAbort(state, kArgsParsingFailure,
    413                       "mount_point argument to unmount() can't be empty");
    414   }
    415 
    416   scan_mounted_volumes();
    417   MountedVolume* vol = find_mounted_volume_by_mount_point(mount_point.c_str());
    418   if (vol == nullptr) {
    419     return StringValue("");
    420   }
    421 
    422   return StringValue(mount_point);
    423 }
    424 
    425 Value* UnmountFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
    426   if (argv.size() != 1) {
    427     return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1 arg, got %zu", name, argv.size());
    428   }
    429   std::vector<std::string> args;
    430   if (!ReadArgs(state, argv, &args)) {
    431     return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name);
    432   }
    433   const std::string& mount_point = args[0];
    434   if (mount_point.empty()) {
    435     return ErrorAbort(state, kArgsParsingFailure,
    436                       "mount_point argument to unmount() can't be empty");
    437   }
    438 
    439   scan_mounted_volumes();
    440   MountedVolume* vol = find_mounted_volume_by_mount_point(mount_point.c_str());
    441   if (vol == nullptr) {
    442     uiPrintf(state, "Failed to unmount %s: No such volume", mount_point.c_str());
    443     return nullptr;
    444   } else {
    445     int ret = unmount_mounted_volume(vol);
    446     if (ret != 0) {
    447       uiPrintf(state, "Failed to unmount %s: %s", mount_point.c_str(), strerror(errno));
    448     }
    449   }
    450 
    451   return StringValue(mount_point);
    452 }
    453 
    454 static int exec_cmd(const char* path, char* const argv[]) {
    455   pid_t child;
    456   if ((child = vfork()) == 0) {
    457     execv(path, argv);
    458     _exit(EXIT_FAILURE);
    459   }
    460 
    461   int status;
    462   waitpid(child, &status, 0);
    463   if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
    464     LOG(ERROR) << path << " failed with status " << WEXITSTATUS(status);
    465   }
    466   return WEXITSTATUS(status);
    467 }
    468 
    469 // format(fs_type, partition_type, location, fs_size, mount_point)
    470 //
    471 //    fs_type="ext4"  partition_type="EMMC"  location=device  fs_size=<bytes> mount_point=<location>
    472 //    fs_type="f2fs"  partition_type="EMMC"  location=device  fs_size=<bytes> mount_point=<location>
    473 //    if fs_size == 0, then make fs uses the entire partition.
    474 //    if fs_size > 0, that is the size to use
    475 //    if fs_size < 0, then reserve that many bytes at the end of the partition (not for "f2fs")
    476 Value* FormatFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
    477   if (argv.size() != 5) {
    478     return ErrorAbort(state, kArgsParsingFailure, "%s() expects 5 args, got %zu", name,
    479                       argv.size());
    480   }
    481 
    482   std::vector<std::string> args;
    483   if (!ReadArgs(state, argv, &args)) {
    484     return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name);
    485   }
    486   const std::string& fs_type = args[0];
    487   const std::string& partition_type = args[1];
    488   const std::string& location = args[2];
    489   const std::string& fs_size = args[3];
    490   const std::string& mount_point = args[4];
    491 
    492   if (fs_type.empty()) {
    493     return ErrorAbort(state, kArgsParsingFailure, "fs_type argument to %s() can't be empty", name);
    494   }
    495   if (partition_type.empty()) {
    496     return ErrorAbort(state, kArgsParsingFailure, "partition_type argument to %s() can't be empty",
    497                       name);
    498   }
    499   if (location.empty()) {
    500     return ErrorAbort(state, kArgsParsingFailure, "location argument to %s() can't be empty", name);
    501   }
    502   if (mount_point.empty()) {
    503     return ErrorAbort(state, kArgsParsingFailure, "mount_point argument to %s() can't be empty",
    504                       name);
    505   }
    506 
    507   int64_t size;
    508   if (!android::base::ParseInt(fs_size, &size)) {
    509     return ErrorAbort(state, kArgsParsingFailure, "%s: failed to parse int in %s", name,
    510                       fs_size.c_str());
    511   }
    512 
    513   if (fs_type == "ext4") {
    514     const char* mke2fs_argv[] = { "/sbin/mke2fs_static", "-t",    "ext4", "-b", "4096",
    515                                   location.c_str(),      nullptr, nullptr };
    516     std::string size_str;
    517     if (size != 0) {
    518       size_str = std::to_string(size / 4096LL);
    519       mke2fs_argv[6] = size_str.c_str();
    520     }
    521 
    522     int status = exec_cmd(mke2fs_argv[0], const_cast<char**>(mke2fs_argv));
    523     if (status != 0) {
    524       LOG(ERROR) << name << ": mke2fs failed (" << status << ") on " << location;
    525       return StringValue("");
    526     }
    527 
    528     const char* e2fsdroid_argv[] = { "/sbin/e2fsdroid_static", "-e",   "-a", mount_point.c_str(),
    529                                      location.c_str(),         nullptr };
    530     status = exec_cmd(e2fsdroid_argv[0], const_cast<char**>(e2fsdroid_argv));
    531     if (status != 0) {
    532       LOG(ERROR) << name << ": e2fsdroid failed (" << status << ") on " << location;
    533       return StringValue("");
    534     }
    535     return StringValue(location);
    536   } else if (fs_type == "f2fs") {
    537     if (size < 0) {
    538       LOG(ERROR) << name << ": fs_size can't be negative for f2fs: " << fs_size;
    539       return StringValue("");
    540     }
    541     std::string num_sectors = std::to_string(size / 512);
    542 
    543     const char* f2fs_path = "/sbin/mkfs.f2fs";
    544     const char* f2fs_argv[] = { "mkfs.f2fs",
    545                                 "-d1",
    546                                 "-f",
    547                                 "-O", "encrypt",
    548                                 "-O", "quota",
    549                                 "-O", "verity",
    550                                 "-w", "512",
    551                                 location.c_str(),
    552                                 (size < 512) ? nullptr : num_sectors.c_str(),
    553                                 nullptr };
    554     int status = exec_cmd(f2fs_path, const_cast<char**>(f2fs_argv));
    555     if (status != 0) {
    556       LOG(ERROR) << name << ": mkfs.f2fs failed (" << status << ") on " << location;
    557       return StringValue("");
    558     }
    559 
    560     const char* sload_argv[] = { "/sbin/sload.f2fs", "-t", mount_point.c_str(), location.c_str(),
    561                                  nullptr };
    562     status = exec_cmd(sload_argv[0], const_cast<char**>(sload_argv));
    563     if (status != 0) {
    564       LOG(ERROR) << name << ": sload.f2fs failed (" << status << ") on " << location;
    565       return StringValue("");
    566     }
    567 
    568     return StringValue(location);
    569   } else {
    570     LOG(ERROR) << name << ": unsupported fs_type \"" << fs_type << "\" partition_type \""
    571                << partition_type << "\"";
    572   }
    573 
    574   return nullptr;
    575 }
    576 
    577 Value* ShowProgressFn(const char* name, State* state,
    578                       const std::vector<std::unique_ptr<Expr>>& argv) {
    579   if (argv.size() != 2) {
    580     return ErrorAbort(state, kArgsParsingFailure, "%s() expects 2 args, got %zu", name,
    581                       argv.size());
    582   }
    583 
    584   std::vector<std::string> args;
    585   if (!ReadArgs(state, argv, &args)) {
    586     return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name);
    587   }
    588   const std::string& frac_str = args[0];
    589   const std::string& sec_str = args[1];
    590 
    591   double frac;
    592   if (!android::base::ParseDouble(frac_str.c_str(), &frac)) {
    593     return ErrorAbort(state, kArgsParsingFailure, "%s: failed to parse double in %s", name,
    594                       frac_str.c_str());
    595   }
    596   int sec;
    597   if (!android::base::ParseInt(sec_str.c_str(), &sec)) {
    598     return ErrorAbort(state, kArgsParsingFailure, "%s: failed to parse int in %s", name,
    599                       sec_str.c_str());
    600   }
    601 
    602   UpdaterInfo* ui = static_cast<UpdaterInfo*>(state->cookie);
    603   fprintf(ui->cmd_pipe, "progress %f %d\n", frac, sec);
    604 
    605   return StringValue(frac_str);
    606 }
    607 
    608 Value* SetProgressFn(const char* name, State* state,
    609                      const std::vector<std::unique_ptr<Expr>>& argv) {
    610   if (argv.size() != 1) {
    611     return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1 arg, got %zu", name, argv.size());
    612   }
    613 
    614   std::vector<std::string> args;
    615   if (!ReadArgs(state, argv, &args)) {
    616     return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name);
    617   }
    618   const std::string& frac_str = args[0];
    619 
    620   double frac;
    621   if (!android::base::ParseDouble(frac_str.c_str(), &frac)) {
    622     return ErrorAbort(state, kArgsParsingFailure, "%s: failed to parse double in %s", name,
    623                       frac_str.c_str());
    624   }
    625 
    626   UpdaterInfo* ui = static_cast<UpdaterInfo*>(state->cookie);
    627   fprintf(ui->cmd_pipe, "set_progress %f\n", frac);
    628 
    629   return StringValue(frac_str);
    630 }
    631 
    632 Value* GetPropFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
    633   if (argv.size() != 1) {
    634     return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1 arg, got %zu", name, argv.size());
    635   }
    636   std::string key;
    637   if (!Evaluate(state, argv[0], &key)) {
    638     return nullptr;
    639   }
    640   std::string value = android::base::GetProperty(key, "");
    641 
    642   return StringValue(value);
    643 }
    644 
    645 // file_getprop(file, key)
    646 //
    647 //   interprets 'file' as a getprop-style file (key=value pairs, one
    648 //   per line. # comment lines, blank lines, lines without '=' ignored),
    649 //   and returns the value for 'key' (or "" if it isn't defined).
    650 Value* FileGetPropFn(const char* name, State* state,
    651                      const std::vector<std::unique_ptr<Expr>>& argv) {
    652   if (argv.size() != 2) {
    653     return ErrorAbort(state, kArgsParsingFailure, "%s() expects 2 args, got %zu", name,
    654                       argv.size());
    655   }
    656 
    657   std::vector<std::string> args;
    658   if (!ReadArgs(state, argv, &args)) {
    659     return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name);
    660   }
    661   const std::string& filename = args[0];
    662   const std::string& key = args[1];
    663 
    664   struct stat st;
    665   if (stat(filename.c_str(), &st) < 0) {
    666     return ErrorAbort(state, kFileGetPropFailure, "%s: failed to stat \"%s\": %s", name,
    667                       filename.c_str(), strerror(errno));
    668   }
    669 
    670   constexpr off_t MAX_FILE_GETPROP_SIZE = 65536;
    671   if (st.st_size > MAX_FILE_GETPROP_SIZE) {
    672     return ErrorAbort(state, kFileGetPropFailure, "%s too large for %s (max %lld)",
    673                       filename.c_str(), name, static_cast<long long>(MAX_FILE_GETPROP_SIZE));
    674   }
    675 
    676   std::string buffer(st.st_size, '\0');
    677   unique_file f(ota_fopen(filename.c_str(), "rb"));
    678   if (f == nullptr) {
    679     return ErrorAbort(state, kFileOpenFailure, "%s: failed to open %s: %s", name, filename.c_str(),
    680                       strerror(errno));
    681   }
    682 
    683   if (ota_fread(&buffer[0], 1, st.st_size, f.get()) != static_cast<size_t>(st.st_size)) {
    684     ErrorAbort(state, kFreadFailure, "%s: failed to read %zu bytes from %s", name,
    685                static_cast<size_t>(st.st_size), filename.c_str());
    686     return nullptr;
    687   }
    688 
    689   ota_fclose(f);
    690 
    691   std::vector<std::string> lines = android::base::Split(buffer, "\n");
    692   for (size_t i = 0; i < lines.size(); i++) {
    693     std::string line = android::base::Trim(lines[i]);
    694 
    695     // comment or blank line: skip to next line
    696     if (line.empty() || line[0] == '#') {
    697       continue;
    698     }
    699     size_t equal_pos = line.find('=');
    700     if (equal_pos == std::string::npos) {
    701       continue;
    702     }
    703 
    704     // trim whitespace between key and '='
    705     std::string str = android::base::Trim(line.substr(0, equal_pos));
    706 
    707     // not the key we're looking for
    708     if (key != str) continue;
    709 
    710     return StringValue(android::base::Trim(line.substr(equal_pos + 1)));
    711   }
    712 
    713   return StringValue("");
    714 }
    715 
    716 // apply_patch_space(bytes)
    717 Value* ApplyPatchSpaceFn(const char* name, State* state,
    718                          const std::vector<std::unique_ptr<Expr>>& argv) {
    719   if (argv.size() != 1) {
    720     return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1 args, got %zu", name,
    721                       argv.size());
    722   }
    723   std::vector<std::string> args;
    724   if (!ReadArgs(state, argv, &args)) {
    725     return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name);
    726   }
    727   const std::string& bytes_str = args[0];
    728 
    729   size_t bytes;
    730   if (!android::base::ParseUint(bytes_str.c_str(), &bytes)) {
    731     return ErrorAbort(state, kArgsParsingFailure, "%s(): can't parse \"%s\" as byte count", name,
    732                       bytes_str.c_str());
    733   }
    734 
    735   // Skip the cache size check if the update is a retry.
    736   if (state->is_retry || CacheSizeCheck(bytes) == 0) {
    737     return StringValue("t");
    738   }
    739   return StringValue("");
    740 }
    741 
    742 Value* WipeCacheFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
    743   if (!argv.empty()) {
    744     return ErrorAbort(state, kArgsParsingFailure, "%s() expects no args, got %zu", name,
    745                       argv.size());
    746   }
    747   fprintf(static_cast<UpdaterInfo*>(state->cookie)->cmd_pipe, "wipe_cache\n");
    748   return StringValue("t");
    749 }
    750 
    751 Value* RunProgramFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
    752   if (argv.size() < 1) {
    753     return ErrorAbort(state, kArgsParsingFailure, "%s() expects at least 1 arg", name);
    754   }
    755 
    756   std::vector<std::string> args;
    757   if (!ReadArgs(state, argv, &args)) {
    758     return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name);
    759   }
    760 
    761   char* args2[argv.size() + 1];
    762   for (size_t i = 0; i < argv.size(); i++) {
    763     args2[i] = &args[i][0];
    764   }
    765   args2[argv.size()] = nullptr;
    766 
    767   LOG(INFO) << "about to run program [" << args2[0] << "] with " << argv.size() << " args";
    768 
    769   pid_t child = fork();
    770   if (child == 0) {
    771     execv(args2[0], args2);
    772     PLOG(ERROR) << "run_program: execv failed";
    773     _exit(EXIT_FAILURE);
    774   }
    775 
    776   int status;
    777   waitpid(child, &status, 0);
    778   if (WIFEXITED(status)) {
    779     if (WEXITSTATUS(status) != 0) {
    780       LOG(ERROR) << "run_program: child exited with status " << WEXITSTATUS(status);
    781     }
    782   } else if (WIFSIGNALED(status)) {
    783     LOG(ERROR) << "run_program: child terminated by signal " << WTERMSIG(status);
    784   }
    785 
    786   return StringValue(std::to_string(status));
    787 }
    788 
    789 // Read a local file and return its contents (the Value* returned
    790 // is actually a FileContents*).
    791 Value* ReadFileFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
    792   if (argv.size() != 1) {
    793     return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1 arg, got %zu", name, argv.size());
    794   }
    795 
    796   std::vector<std::string> args;
    797   if (!ReadArgs(state, argv, &args)) {
    798     return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name);
    799   }
    800   const std::string& filename = args[0];
    801 
    802   Value* v = new Value(VAL_INVALID, "");
    803 
    804   FileContents fc;
    805   if (LoadFileContents(filename.c_str(), &fc) == 0) {
    806     v->type = VAL_BLOB;
    807     v->data = std::string(fc.data.begin(), fc.data.end());
    808   }
    809   return v;
    810 }
    811 
    812 // write_value(value, filename)
    813 //   Writes 'value' to 'filename'.
    814 //   Example: write_value("960000", "/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq")
    815 Value* WriteValueFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
    816   if (argv.size() != 2) {
    817     return ErrorAbort(state, kArgsParsingFailure, "%s() expects 2 args, got %zu", name,
    818                       argv.size());
    819   }
    820 
    821   std::vector<std::string> args;
    822   if (!ReadArgs(state, argv, &args)) {
    823     return ErrorAbort(state, kArgsParsingFailure, "%s(): Failed to parse the argument(s)", name);
    824   }
    825 
    826   const std::string& filename = args[1];
    827   if (filename.empty()) {
    828     return ErrorAbort(state, kArgsParsingFailure, "%s(): Filename cannot be empty", name);
    829   }
    830 
    831   const std::string& value = args[0];
    832   if (!android::base::WriteStringToFile(value, filename)) {
    833     PLOG(ERROR) << name << ": Failed to write to \"" << filename << "\"";
    834     return StringValue("");
    835   } else {
    836     return StringValue("t");
    837   }
    838 }
    839 
    840 // Immediately reboot the device.  Recovery is not finished normally,
    841 // so if you reboot into recovery it will re-start applying the
    842 // current package (because nothing has cleared the copy of the
    843 // arguments stored in the BCB).
    844 //
    845 // The argument is the partition name passed to the android reboot
    846 // property.  It can be "recovery" to boot from the recovery
    847 // partition, or "" (empty string) to boot from the regular boot
    848 // partition.
    849 Value* RebootNowFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
    850   if (argv.size() != 2) {
    851     return ErrorAbort(state, kArgsParsingFailure, "%s() expects 2 args, got %zu", name,
    852                       argv.size());
    853   }
    854 
    855   std::vector<std::string> args;
    856   if (!ReadArgs(state, argv, &args)) {
    857     return ErrorAbort(state, kArgsParsingFailure, "%s(): Failed to parse the argument(s)", name);
    858   }
    859   const std::string& filename = args[0];
    860   const std::string& property = args[1];
    861 
    862   // Zero out the 'command' field of the bootloader message. Leave the rest intact.
    863   bootloader_message boot;
    864   std::string err;
    865   if (!read_bootloader_message_from(&boot, filename, &err)) {
    866     LOG(ERROR) << name << "(): Failed to read from \"" << filename << "\": " << err;
    867     return StringValue("");
    868   }
    869   memset(boot.command, 0, sizeof(boot.command));
    870   if (!write_bootloader_message_to(boot, filename, &err)) {
    871     LOG(ERROR) << name << "(): Failed to write to \"" << filename << "\": " << err;
    872     return StringValue("");
    873   }
    874 
    875   std::string reboot_cmd = "reboot," + property;
    876   if (android::base::GetBoolProperty("ro.boot.quiescent", false)) {
    877     reboot_cmd += ",quiescent";
    878   }
    879   android::base::SetProperty(ANDROID_RB_PROPERTY, reboot_cmd);
    880 
    881   sleep(5);
    882   return ErrorAbort(state, kRebootFailure, "%s() failed to reboot", name);
    883 }
    884 
    885 // Store a string value somewhere that future invocations of recovery
    886 // can access it.  This value is called the "stage" and can be used to
    887 // drive packages that need to do reboots in the middle of
    888 // installation and keep track of where they are in the multi-stage
    889 // install.
    890 //
    891 // The first argument is the block device for the misc partition
    892 // ("/misc" in the fstab), which is where this value is stored.  The
    893 // second argument is the string to store; it should not exceed 31
    894 // bytes.
    895 Value* SetStageFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
    896   if (argv.size() != 2) {
    897     return ErrorAbort(state, kArgsParsingFailure, "%s() expects 2 args, got %zu", name,
    898                       argv.size());
    899   }
    900 
    901   std::vector<std::string> args;
    902   if (!ReadArgs(state, argv, &args)) {
    903     return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name);
    904   }
    905   const std::string& filename = args[0];
    906   const std::string& stagestr = args[1];
    907 
    908   // Store this value in the misc partition, immediately after the
    909   // bootloader message that the main recovery uses to save its
    910   // arguments in case of the device restarting midway through
    911   // package installation.
    912   bootloader_message boot;
    913   std::string err;
    914   if (!read_bootloader_message_from(&boot, filename, &err)) {
    915     LOG(ERROR) << name << "(): Failed to read from \"" << filename << "\": " << err;
    916     return StringValue("");
    917   }
    918   strlcpy(boot.stage, stagestr.c_str(), sizeof(boot.stage));
    919   if (!write_bootloader_message_to(boot, filename, &err)) {
    920     LOG(ERROR) << name << "(): Failed to write to \"" << filename << "\": " << err;
    921     return StringValue("");
    922   }
    923 
    924   return StringValue(filename);
    925 }
    926 
    927 // Return the value most recently saved with SetStageFn.  The argument
    928 // is the block device for the misc partition.
    929 Value* GetStageFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
    930   if (argv.size() != 1) {
    931     return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1 arg, got %zu", name, argv.size());
    932   }
    933 
    934   std::vector<std::string> args;
    935   if (!ReadArgs(state, argv, &args)) {
    936     return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name);
    937   }
    938   const std::string& filename = args[0];
    939 
    940   bootloader_message boot;
    941   std::string err;
    942   if (!read_bootloader_message_from(&boot, filename, &err)) {
    943     LOG(ERROR) << name << "(): Failed to read from \"" << filename << "\": " << err;
    944     return StringValue("");
    945   }
    946 
    947   return StringValue(boot.stage);
    948 }
    949 
    950 Value* WipeBlockDeviceFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
    951   if (argv.size() != 2) {
    952     return ErrorAbort(state, kArgsParsingFailure, "%s() expects 2 args, got %zu", name,
    953                       argv.size());
    954   }
    955 
    956   std::vector<std::string> args;
    957   if (!ReadArgs(state, argv, &args)) {
    958     return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name);
    959   }
    960   const std::string& filename = args[0];
    961   const std::string& len_str = args[1];
    962 
    963   size_t len;
    964   if (!android::base::ParseUint(len_str.c_str(), &len)) {
    965     return nullptr;
    966   }
    967   unique_fd fd(ota_open(filename.c_str(), O_WRONLY, 0644));
    968   // The wipe_block_device function in ext4_utils returns 0 on success and 1
    969   // for failure.
    970   int status = wipe_block_device(fd, len);
    971   return StringValue((status == 0) ? "t" : "");
    972 }
    973 
    974 Value* EnableRebootFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
    975   if (!argv.empty()) {
    976     return ErrorAbort(state, kArgsParsingFailure, "%s() expects no args, got %zu", name,
    977                       argv.size());
    978   }
    979   UpdaterInfo* ui = static_cast<UpdaterInfo*>(state->cookie);
    980   fprintf(ui->cmd_pipe, "enable_reboot\n");
    981   return StringValue("t");
    982 }
    983 
    984 Value* Tune2FsFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) {
    985   if (argv.empty()) {
    986     return ErrorAbort(state, kArgsParsingFailure, "%s() expects args, got %zu", name, argv.size());
    987   }
    988 
    989   std::vector<std::string> args;
    990   if (!ReadArgs(state, argv, &args)) {
    991     return ErrorAbort(state, kArgsParsingFailure, "%s() could not read args", name);
    992   }
    993 
    994   char* args2[argv.size() + 1];
    995   // Tune2fs expects the program name as its args[0]
    996   args2[0] = const_cast<char*>(name);
    997   if (args2[0] == nullptr) {
    998     return nullptr;
    999   }
   1000   for (size_t i = 0; i < argv.size(); ++i) {
   1001     args2[i + 1] = &args[i][0];
   1002   }
   1003 
   1004   // tune2fs changes the file system parameters on an ext2 file system; it
   1005   // returns 0 on success.
   1006   int result = tune2fs_main(argv.size() + 1, args2);
   1007   if (result != 0) {
   1008     return ErrorAbort(state, kTune2FsFailure, "%s() returned error code %d", name, result);
   1009   }
   1010   return StringValue("t");
   1011 }
   1012 
   1013 void RegisterInstallFunctions() {
   1014   RegisterFunction("mount", MountFn);
   1015   RegisterFunction("is_mounted", IsMountedFn);
   1016   RegisterFunction("unmount", UnmountFn);
   1017   RegisterFunction("format", FormatFn);
   1018   RegisterFunction("show_progress", ShowProgressFn);
   1019   RegisterFunction("set_progress", SetProgressFn);
   1020   RegisterFunction("package_extract_file", PackageExtractFileFn);
   1021 
   1022   RegisterFunction("getprop", GetPropFn);
   1023   RegisterFunction("file_getprop", FileGetPropFn);
   1024 
   1025   RegisterFunction("apply_patch", ApplyPatchFn);
   1026   RegisterFunction("apply_patch_check", ApplyPatchCheckFn);
   1027   RegisterFunction("apply_patch_space", ApplyPatchSpaceFn);
   1028 
   1029   RegisterFunction("wipe_block_device", WipeBlockDeviceFn);
   1030 
   1031   RegisterFunction("read_file", ReadFileFn);
   1032   RegisterFunction("sha1_check", Sha1CheckFn);
   1033   RegisterFunction("write_value", WriteValueFn);
   1034 
   1035   RegisterFunction("wipe_cache", WipeCacheFn);
   1036 
   1037   RegisterFunction("ui_print", UIPrintFn);
   1038 
   1039   RegisterFunction("run_program", RunProgramFn);
   1040 
   1041   RegisterFunction("reboot_now", RebootNowFn);
   1042   RegisterFunction("get_stage", GetStageFn);
   1043   RegisterFunction("set_stage", SetStageFn);
   1044 
   1045   RegisterFunction("enable_reboot", EnableRebootFn);
   1046   RegisterFunction("tune2fs", Tune2FsFn);
   1047 }
   1048