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