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