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