1/*
2 * Copyright (C) 2008 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 "builtins.h"
18
19#include <dirent.h>
20#include <errno.h>
21#include <fcntl.h>
22#include <mntent.h>
23#include <net/if.h>
24#include <signal.h>
25#include <sched.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <sys/socket.h>
30#include <sys/mount.h>
31#include <sys/resource.h>
32#include <sys/syscall.h>
33#include <sys/time.h>
34#include <sys/types.h>
35#include <sys/stat.h>
36#include <sys/wait.h>
37#include <unistd.h>
38#include <linux/loop.h>
39#include <ext4_crypt.h>
40#include <ext4_crypt_init_extensions.h>
41
42#include <selinux/selinux.h>
43#include <selinux/label.h>
44
45#include <fs_mgr.h>
46#include <android-base/file.h>
47#include <android-base/parseint.h>
48#include <android-base/stringprintf.h>
49#include <bootloader_message/bootloader_message.h>
50#include <cutils/partition_utils.h>
51#include <cutils/android_reboot.h>
52#include <logwrap/logwrap.h>
53#include <private/android_filesystem_config.h>
54
55#include "action.h"
56#include "bootchart.h"
57#include "devices.h"
58#include "init.h"
59#include "init_parser.h"
60#include "log.h"
61#include "property_service.h"
62#include "service.h"
63#include "signal_handler.h"
64#include "util.h"
65
66#define chmod DO_NOT_USE_CHMOD_USE_FCHMODAT_SYMLINK_NOFOLLOW
67#define UNMOUNT_CHECK_MS 5000
68#define UNMOUNT_CHECK_TIMES 10
69
70static const int kTerminateServiceDelayMicroSeconds = 50000;
71
72static int insmod(const char *filename, const char *options) {
73    int fd = open(filename, O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
74    if (fd == -1) {
75        ERROR("insmod: open(\"%s\") failed: %s", filename, strerror(errno));
76        return -1;
77    }
78    int rc = syscall(__NR_finit_module, fd, options, 0);
79    if (rc == -1) {
80        ERROR("finit_module for \"%s\" failed: %s", filename, strerror(errno));
81    }
82    close(fd);
83    return rc;
84}
85
86static int __ifupdown(const char *interface, int up) {
87    struct ifreq ifr;
88    int s, ret;
89
90    strlcpy(ifr.ifr_name, interface, IFNAMSIZ);
91
92    s = socket(AF_INET, SOCK_DGRAM, 0);
93    if (s < 0)
94        return -1;
95
96    ret = ioctl(s, SIOCGIFFLAGS, &ifr);
97    if (ret < 0) {
98        goto done;
99    }
100
101    if (up)
102        ifr.ifr_flags |= IFF_UP;
103    else
104        ifr.ifr_flags &= ~IFF_UP;
105
106    ret = ioctl(s, SIOCSIFFLAGS, &ifr);
107
108done:
109    close(s);
110    return ret;
111}
112
113// Turn off backlight while we are performing power down cleanup activities.
114static void turnOffBacklight() {
115    static const char off[] = "0";
116
117    android::base::WriteStringToFile(off, "/sys/class/leds/lcd-backlight/brightness");
118
119    static const char backlightDir[] = "/sys/class/backlight";
120    std::unique_ptr<DIR, int(*)(DIR*)> dir(opendir(backlightDir), closedir);
121    if (!dir) {
122        return;
123    }
124
125    struct dirent *dp;
126    while ((dp = readdir(dir.get())) != NULL) {
127        if (((dp->d_type != DT_DIR) && (dp->d_type != DT_LNK)) ||
128                (dp->d_name[0] == '.')) {
129            continue;
130        }
131
132        std::string fileName = android::base::StringPrintf("%s/%s/brightness",
133                                                           backlightDir,
134                                                           dp->d_name);
135        android::base::WriteStringToFile(off, fileName);
136    }
137}
138
139static int wipe_data_via_recovery(const std::string& reason) {
140    const std::vector<std::string> options = {"--wipe_data", std::string() + "--reason=" + reason};
141    std::string err;
142    if (!write_bootloader_message(options, &err)) {
143        ERROR("failed to set bootloader message: %s", err.c_str());
144        return -1;
145    }
146    android_reboot(ANDROID_RB_RESTART2, 0, "recovery");
147    while (1) { pause(); }  // never reached
148}
149
150static void unmount_and_fsck(const struct mntent *entry) {
151    if (strcmp(entry->mnt_type, "f2fs") && strcmp(entry->mnt_type, "ext4"))
152        return;
153
154    /* First, lazily unmount the directory. This unmount request finishes when
155     * all processes that open a file or directory in |entry->mnt_dir| exit.
156     */
157    TEMP_FAILURE_RETRY(umount2(entry->mnt_dir, MNT_DETACH));
158
159    /* Next, kill all processes except init, kthreadd, and kthreadd's
160     * children to finish the lazy unmount. Killing all processes here is okay
161     * because this callback function is only called right before reboot().
162     * It might be cleaner to selectively kill processes that actually use
163     * |entry->mnt_dir| rather than killing all, probably by reusing a function
164     * like killProcessesWithOpenFiles() in vold/, but the selinux policy does
165     * not allow init to scan /proc/<pid> files which the utility function
166     * heavily relies on. The policy does not allow the process to execute
167     * killall/pkill binaries either. Note that some processes might
168     * automatically restart after kill(), but that is not really a problem
169     * because |entry->mnt_dir| is no longer visible to such new processes.
170     */
171    ServiceManager::GetInstance().ForEachService([] (Service* s) { s->Stop(); });
172    TEMP_FAILURE_RETRY(kill(-1, SIGKILL));
173
174    // Restart Watchdogd to allow us to complete umounting and fsck
175    Service *svc = ServiceManager::GetInstance().FindServiceByName("watchdogd");
176    if (svc) {
177        do {
178            sched_yield(); // do not be so eager, let cleanup have priority
179            ServiceManager::GetInstance().ReapAnyOutstandingChildren();
180        } while (svc->flags() & SVC_RUNNING); // Paranoid Cargo
181        svc->Start();
182    }
183
184    turnOffBacklight();
185
186    int count = 0;
187    while (count++ < UNMOUNT_CHECK_TIMES) {
188        int fd = TEMP_FAILURE_RETRY(open(entry->mnt_fsname, O_RDONLY | O_EXCL));
189        if (fd >= 0) {
190            /* |entry->mnt_dir| has sucessfully been unmounted. */
191            close(fd);
192            break;
193        } else if (errno == EBUSY) {
194            /* Some processes using |entry->mnt_dir| are still alive. Wait for a
195             * while then retry.
196             */
197            TEMP_FAILURE_RETRY(
198                usleep(UNMOUNT_CHECK_MS * 1000 / UNMOUNT_CHECK_TIMES));
199            continue;
200        } else {
201            /* Cannot open the device. Give up. */
202            return;
203        }
204    }
205
206    // NB: With watchdog still running, there is no cap on the time it takes
207    // to complete the fsck, from the users perspective the device graphics
208    // and responses are locked-up and they may choose to hold the power
209    // button in frustration if it drags out.
210
211    int st;
212    if (!strcmp(entry->mnt_type, "f2fs")) {
213        const char *f2fs_argv[] = {
214            "/system/bin/fsck.f2fs", "-f", entry->mnt_fsname,
215        };
216        android_fork_execvp_ext(ARRAY_SIZE(f2fs_argv), (char **)f2fs_argv,
217                                &st, true, LOG_KLOG, true, NULL, NULL, 0);
218    } else if (!strcmp(entry->mnt_type, "ext4")) {
219        const char *ext4_argv[] = {
220            "/system/bin/e2fsck", "-f", "-y", entry->mnt_fsname,
221        };
222        android_fork_execvp_ext(ARRAY_SIZE(ext4_argv), (char **)ext4_argv,
223                                &st, true, LOG_KLOG, true, NULL, NULL, 0);
224    }
225}
226
227static int do_class_start(const std::vector<std::string>& args) {
228        /* Starting a class does not start services
229         * which are explicitly disabled.  They must
230         * be started individually.
231         */
232    ServiceManager::GetInstance().
233        ForEachServiceInClass(args[1], [] (Service* s) { s->StartIfNotDisabled(); });
234    return 0;
235}
236
237static int do_class_stop(const std::vector<std::string>& args) {
238    ServiceManager::GetInstance().
239        ForEachServiceInClass(args[1], [] (Service* s) { s->Stop(); });
240    return 0;
241}
242
243static int do_class_reset(const std::vector<std::string>& args) {
244    ServiceManager::GetInstance().
245        ForEachServiceInClass(args[1], [] (Service* s) { s->Reset(); });
246    return 0;
247}
248
249static int do_domainname(const std::vector<std::string>& args) {
250    return write_file("/proc/sys/kernel/domainname", args[1].c_str());
251}
252
253static int do_enable(const std::vector<std::string>& args) {
254    Service* svc = ServiceManager::GetInstance().FindServiceByName(args[1]);
255    if (!svc) {
256        return -1;
257    }
258    return svc->Enable();
259}
260
261static int do_exec(const std::vector<std::string>& args) {
262    Service* svc = ServiceManager::GetInstance().MakeExecOneshotService(args);
263    if (!svc) {
264        return -1;
265    }
266    if (!svc->Start()) {
267        return -1;
268    }
269    waiting_for_exec = true;
270    return 0;
271}
272
273static int do_export(const std::vector<std::string>& args) {
274    return add_environment(args[1].c_str(), args[2].c_str());
275}
276
277static int do_hostname(const std::vector<std::string>& args) {
278    return write_file("/proc/sys/kernel/hostname", args[1].c_str());
279}
280
281static int do_ifup(const std::vector<std::string>& args) {
282    return __ifupdown(args[1].c_str(), 1);
283}
284
285static int do_insmod(const std::vector<std::string>& args) {
286    std::string options;
287
288    if (args.size() > 2) {
289        options += args[2];
290        for (std::size_t i = 3; i < args.size(); ++i) {
291            options += ' ';
292            options += args[i];
293        }
294    }
295
296    return insmod(args[1].c_str(), options.c_str());
297}
298
299static int do_mkdir(const std::vector<std::string>& args) {
300    mode_t mode = 0755;
301    int ret;
302
303    /* mkdir <path> [mode] [owner] [group] */
304
305    if (args.size() >= 3) {
306        mode = std::stoul(args[2], 0, 8);
307    }
308
309    ret = make_dir(args[1].c_str(), mode);
310    /* chmod in case the directory already exists */
311    if (ret == -1 && errno == EEXIST) {
312        ret = fchmodat(AT_FDCWD, args[1].c_str(), mode, AT_SYMLINK_NOFOLLOW);
313    }
314    if (ret == -1) {
315        return -errno;
316    }
317
318    if (args.size() >= 4) {
319        uid_t uid = decode_uid(args[3].c_str());
320        gid_t gid = -1;
321
322        if (args.size() == 5) {
323            gid = decode_uid(args[4].c_str());
324        }
325
326        if (lchown(args[1].c_str(), uid, gid) == -1) {
327            return -errno;
328        }
329
330        /* chown may have cleared S_ISUID and S_ISGID, chmod again */
331        if (mode & (S_ISUID | S_ISGID)) {
332            ret = fchmodat(AT_FDCWD, args[1].c_str(), mode, AT_SYMLINK_NOFOLLOW);
333            if (ret == -1) {
334                return -errno;
335            }
336        }
337    }
338
339    if (e4crypt_is_native()) {
340        if (e4crypt_set_directory_policy(args[1].c_str())) {
341            wipe_data_via_recovery(std::string() + "set_policy_failed:" + args[1]);
342            return -1;
343        }
344    }
345    return 0;
346}
347
348/* umount <path> */
349static int do_umount(const std::vector<std::string>& args) {
350  return umount(args[1].c_str());
351}
352
353static struct {
354    const char *name;
355    unsigned flag;
356} mount_flags[] = {
357    { "noatime",    MS_NOATIME },
358    { "noexec",     MS_NOEXEC },
359    { "nosuid",     MS_NOSUID },
360    { "nodev",      MS_NODEV },
361    { "nodiratime", MS_NODIRATIME },
362    { "ro",         MS_RDONLY },
363    { "rw",         0 },
364    { "remount",    MS_REMOUNT },
365    { "bind",       MS_BIND },
366    { "rec",        MS_REC },
367    { "unbindable", MS_UNBINDABLE },
368    { "private",    MS_PRIVATE },
369    { "slave",      MS_SLAVE },
370    { "shared",     MS_SHARED },
371    { "defaults",   0 },
372    { 0,            0 },
373};
374
375#define DATA_MNT_POINT "/data"
376
377/* mount <type> <device> <path> <flags ...> <options> */
378static int do_mount(const std::vector<std::string>& args) {
379    char tmp[64];
380    const char *source, *target, *system;
381    const char *options = NULL;
382    unsigned flags = 0;
383    std::size_t na = 0;
384    int n, i;
385    int wait = 0;
386
387    for (na = 4; na < args.size(); na++) {
388        for (i = 0; mount_flags[i].name; i++) {
389            if (!args[na].compare(mount_flags[i].name)) {
390                flags |= mount_flags[i].flag;
391                break;
392            }
393        }
394
395        if (!mount_flags[i].name) {
396            if (!args[na].compare("wait"))
397                wait = 1;
398            /* if our last argument isn't a flag, wolf it up as an option string */
399            else if (na + 1 == args.size())
400                options = args[na].c_str();
401        }
402    }
403
404    system = args[1].c_str();
405    source = args[2].c_str();
406    target = args[3].c_str();
407
408    if (!strncmp(source, "mtd@", 4)) {
409        n = mtd_name_to_number(source + 4);
410        if (n < 0) {
411            return -1;
412        }
413
414        snprintf(tmp, sizeof(tmp), "/dev/block/mtdblock%d", n);
415
416        if (wait)
417            wait_for_file(tmp, COMMAND_RETRY_TIMEOUT);
418        if (mount(tmp, target, system, flags, options) < 0) {
419            return -1;
420        }
421
422        goto exit_success;
423    } else if (!strncmp(source, "loop@", 5)) {
424        int mode, loop, fd;
425        struct loop_info info;
426
427        mode = (flags & MS_RDONLY) ? O_RDONLY : O_RDWR;
428        fd = open(source + 5, mode | O_CLOEXEC);
429        if (fd < 0) {
430            return -1;
431        }
432
433        for (n = 0; ; n++) {
434            snprintf(tmp, sizeof(tmp), "/dev/block/loop%d", n);
435            loop = open(tmp, mode | O_CLOEXEC);
436            if (loop < 0) {
437                close(fd);
438                return -1;
439            }
440
441            /* if it is a blank loop device */
442            if (ioctl(loop, LOOP_GET_STATUS, &info) < 0 && errno == ENXIO) {
443                /* if it becomes our loop device */
444                if (ioctl(loop, LOOP_SET_FD, fd) >= 0) {
445                    close(fd);
446
447                    if (mount(tmp, target, system, flags, options) < 0) {
448                        ioctl(loop, LOOP_CLR_FD, 0);
449                        close(loop);
450                        return -1;
451                    }
452
453                    close(loop);
454                    goto exit_success;
455                }
456            }
457
458            close(loop);
459        }
460
461        close(fd);
462        ERROR("out of loopback devices");
463        return -1;
464    } else {
465        if (wait)
466            wait_for_file(source, COMMAND_RETRY_TIMEOUT);
467        if (mount(source, target, system, flags, options) < 0) {
468            return -1;
469        }
470
471    }
472
473exit_success:
474    return 0;
475
476}
477
478/* Imports .rc files from the specified paths. Default ones are applied if none is given.
479 *
480 * start_index: index of the first path in the args list
481 */
482static void import_late(const std::vector<std::string>& args, size_t start_index, size_t end_index) {
483    Parser& parser = Parser::GetInstance();
484    if (end_index <= start_index) {
485        // Use the default set if no path is given
486        static const std::vector<std::string> init_directories = {
487            "/system/etc/init",
488            "/vendor/etc/init",
489            "/odm/etc/init"
490        };
491
492        for (const auto& dir : init_directories) {
493            parser.ParseConfig(dir);
494        }
495    } else {
496        for (size_t i = start_index; i < end_index; ++i) {
497            parser.ParseConfig(args[i]);
498        }
499    }
500}
501
502/* mount_fstab
503 *
504 *  Call fs_mgr_mount_all() to mount the given fstab
505 */
506static int mount_fstab(const char* fstabfile, int mount_mode) {
507    pid_t pid;
508    int ret = -1;
509    int child_ret = -1;
510    int status;
511    struct fstab *fstab;
512
513    /*
514     * Call fs_mgr_mount_all() to mount all filesystems.  We fork(2) and
515     * do the call in the child to provide protection to the main init
516     * process if anything goes wrong (crash or memory leak), and wait for
517     * the child to finish in the parent.
518     */
519    pid = fork();
520    if (pid > 0) {
521        /* Parent.  Wait for the child to return */
522        int wp_ret = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0));
523        if (wp_ret < 0) {
524            /* Unexpected error code. We will continue anyway. */
525            NOTICE("waitpid failed rc=%d: %s\n", wp_ret, strerror(errno));
526        }
527
528        if (WIFEXITED(status)) {
529            ret = WEXITSTATUS(status);
530        } else {
531            ret = -1;
532        }
533    } else if (pid == 0) {
534        /* child, call fs_mgr_mount_all() */
535        klog_set_level(6);  /* So we can see what fs_mgr_mount_all() does */
536        fstab = fs_mgr_read_fstab(fstabfile);
537        child_ret = fs_mgr_mount_all(fstab, mount_mode);
538        fs_mgr_free_fstab(fstab);
539        if (child_ret == -1) {
540            ERROR("fs_mgr_mount_all returned an error\n");
541        }
542        _exit(child_ret);
543    } else {
544        /* fork failed, return an error */
545        return -1;
546    }
547    return ret;
548}
549
550/* Queue event based on fs_mgr return code.
551 *
552 * code: return code of fs_mgr_mount_all
553 *
554 * This function might request a reboot, in which case it will
555 * not return.
556 *
557 * return code is processed based on input code
558 */
559static int queue_fs_event(int code) {
560    int ret = code;
561    if (code == FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION) {
562        ActionManager::GetInstance().QueueEventTrigger("encrypt");
563    } else if (code == FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED) {
564        property_set("ro.crypto.state", "encrypted");
565        property_set("ro.crypto.type", "block");
566        ActionManager::GetInstance().QueueEventTrigger("defaultcrypto");
567    } else if (code == FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) {
568        property_set("ro.crypto.state", "unencrypted");
569        ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
570    } else if (code == FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) {
571        property_set("ro.crypto.state", "unsupported");
572        ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
573    } else if (code == FS_MGR_MNTALL_DEV_NEEDS_RECOVERY) {
574        /* Setup a wipe via recovery, and reboot into recovery */
575        ERROR("fs_mgr_mount_all suggested recovery, so wiping data via recovery.\n");
576        ret = wipe_data_via_recovery("wipe_data_via_recovery");
577        /* If reboot worked, there is no return. */
578    } else if (code == FS_MGR_MNTALL_DEV_FILE_ENCRYPTED) {
579        if (e4crypt_install_keyring()) {
580            return -1;
581        }
582        property_set("ro.crypto.state", "encrypted");
583        property_set("ro.crypto.type", "file");
584
585        // Although encrypted, we have device key, so we do not need to
586        // do anything different from the nonencrypted case.
587        ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
588    } else if (code > 0) {
589        ERROR("fs_mgr_mount_all returned unexpected error %d\n", code);
590    }
591    /* else ... < 0: error */
592
593    return ret;
594}
595
596/* mount_all <fstab> [ <path> ]* [--<options>]*
597 *
598 * This function might request a reboot, in which case it will
599 * not return.
600 */
601static int do_mount_all(const std::vector<std::string>& args) {
602    std::size_t na = 0;
603    bool import_rc = true;
604    bool queue_event = true;
605    int mount_mode = MOUNT_MODE_DEFAULT;
606    const char* fstabfile = args[1].c_str();
607    std::size_t path_arg_end = args.size();
608
609    for (na = args.size() - 1; na > 1; --na) {
610        if (args[na] == "--early") {
611             path_arg_end = na;
612             queue_event = false;
613             mount_mode = MOUNT_MODE_EARLY;
614        } else if (args[na] == "--late") {
615            path_arg_end = na;
616            import_rc = false;
617            mount_mode = MOUNT_MODE_LATE;
618        }
619    }
620
621    int ret =  mount_fstab(fstabfile, mount_mode);
622
623    if (import_rc) {
624        /* Paths of .rc files are specified at the 2nd argument and beyond */
625        import_late(args, 2, path_arg_end);
626    }
627
628    if (queue_event) {
629        /* queue_fs_event will queue event based on mount_fstab return code
630         * and return processed return code*/
631        ret = queue_fs_event(ret);
632    }
633
634    return ret;
635}
636
637static int do_swapon_all(const std::vector<std::string>& args) {
638    struct fstab *fstab;
639    int ret;
640
641    fstab = fs_mgr_read_fstab(args[1].c_str());
642    ret = fs_mgr_swapon_all(fstab);
643    fs_mgr_free_fstab(fstab);
644
645    return ret;
646}
647
648static int do_setprop(const std::vector<std::string>& args) {
649    const char* name = args[1].c_str();
650    const char* value = args[2].c_str();
651    property_set(name, value);
652    return 0;
653}
654
655static int do_setrlimit(const std::vector<std::string>& args) {
656    struct rlimit limit;
657    int resource;
658    resource = std::stoi(args[1]);
659    limit.rlim_cur = std::stoi(args[2]);
660    limit.rlim_max = std::stoi(args[3]);
661    return setrlimit(resource, &limit);
662}
663
664static int do_start(const std::vector<std::string>& args) {
665    Service* svc = ServiceManager::GetInstance().FindServiceByName(args[1]);
666    if (!svc) {
667        ERROR("do_start: Service %s not found\n", args[1].c_str());
668        return -1;
669    }
670    if (!svc->Start())
671        return -1;
672    return 0;
673}
674
675static int do_stop(const std::vector<std::string>& args) {
676    Service* svc = ServiceManager::GetInstance().FindServiceByName(args[1]);
677    if (!svc) {
678        ERROR("do_stop: Service %s not found\n", args[1].c_str());
679        return -1;
680    }
681    svc->Stop();
682    return 0;
683}
684
685static int do_restart(const std::vector<std::string>& args) {
686    Service* svc = ServiceManager::GetInstance().FindServiceByName(args[1]);
687    if (!svc) {
688        ERROR("do_restart: Service %s not found\n", args[1].c_str());
689        return -1;
690    }
691    svc->Restart();
692    return 0;
693}
694
695static int do_powerctl(const std::vector<std::string>& args) {
696    const char* command = args[1].c_str();
697    int len = 0;
698    unsigned int cmd = 0;
699    const char *reboot_target = "";
700    void (*callback_on_ro_remount)(const struct mntent*) = NULL;
701
702    if (strncmp(command, "shutdown", 8) == 0) {
703        cmd = ANDROID_RB_POWEROFF;
704        len = 8;
705    } else if (strncmp(command, "reboot", 6) == 0) {
706        cmd = ANDROID_RB_RESTART2;
707        len = 6;
708    } else {
709        ERROR("powerctl: unrecognized command '%s'\n", command);
710        return -EINVAL;
711    }
712
713    if (command[len] == ',') {
714        if (cmd == ANDROID_RB_POWEROFF &&
715            !strcmp(&command[len + 1], "userrequested")) {
716            // The shutdown reason is PowerManager.SHUTDOWN_USER_REQUESTED.
717            // Run fsck once the file system is remounted in read-only mode.
718            callback_on_ro_remount = unmount_and_fsck;
719        } else if (cmd == ANDROID_RB_RESTART2) {
720            reboot_target = &command[len + 1];
721        }
722    } else if (command[len] != '\0') {
723        ERROR("powerctl: unrecognized reboot target '%s'\n", &command[len]);
724        return -EINVAL;
725    }
726
727    std::string timeout = property_get("ro.build.shutdown_timeout");
728    unsigned int delay = 0;
729
730    if (android::base::ParseUint(timeout.c_str(), &delay) && delay > 0) {
731        Timer t;
732        // Ask all services to terminate.
733        ServiceManager::GetInstance().ForEachService(
734            [] (Service* s) { s->Terminate(); });
735
736        while (t.duration() < delay) {
737            ServiceManager::GetInstance().ReapAnyOutstandingChildren();
738
739            int service_count = 0;
740            ServiceManager::GetInstance().ForEachService(
741                [&service_count] (Service* s) {
742                    // Count the number of services running.
743                    // Exclude the console as it will ignore the SIGTERM signal
744                    // and not exit.
745                    // Note: SVC_CONSOLE actually means "requires console" but
746                    // it is only used by the shell.
747                    if (s->pid() != 0 && (s->flags() & SVC_CONSOLE) == 0) {
748                        service_count++;
749                    }
750                });
751
752            if (service_count == 0) {
753                // All terminable services terminated. We can exit early.
754                break;
755            }
756
757            // Wait a bit before recounting the number or running services.
758            usleep(kTerminateServiceDelayMicroSeconds);
759        }
760        NOTICE("Terminating running services took %.02f seconds", t.duration());
761    }
762
763    return android_reboot_with_callback(cmd, 0, reboot_target,
764                                        callback_on_ro_remount);
765}
766
767static int do_trigger(const std::vector<std::string>& args) {
768    ActionManager::GetInstance().QueueEventTrigger(args[1]);
769    return 0;
770}
771
772static int do_symlink(const std::vector<std::string>& args) {
773    return symlink(args[1].c_str(), args[2].c_str());
774}
775
776static int do_rm(const std::vector<std::string>& args) {
777    return unlink(args[1].c_str());
778}
779
780static int do_rmdir(const std::vector<std::string>& args) {
781    return rmdir(args[1].c_str());
782}
783
784static int do_sysclktz(const std::vector<std::string>& args) {
785    struct timezone tz;
786
787    memset(&tz, 0, sizeof(tz));
788    tz.tz_minuteswest = std::stoi(args[1]);
789    if (settimeofday(NULL, &tz))
790        return -1;
791    return 0;
792}
793
794static int do_verity_load_state(const std::vector<std::string>& args) {
795    int mode = -1;
796    int rc = fs_mgr_load_verity_state(&mode);
797    if (rc == 0 && mode != VERITY_MODE_DEFAULT) {
798        ActionManager::GetInstance().QueueEventTrigger("verity-logging");
799    }
800    return rc;
801}
802
803static void verity_update_property(fstab_rec *fstab, const char *mount_point,
804                                   int mode, int status) {
805    property_set(android::base::StringPrintf("partition.%s.verified", mount_point).c_str(),
806                 android::base::StringPrintf("%d", mode).c_str());
807}
808
809static int do_verity_update_state(const std::vector<std::string>& args) {
810    return fs_mgr_update_verity_state(verity_update_property);
811}
812
813static int do_write(const std::vector<std::string>& args) {
814    const char* path = args[1].c_str();
815    const char* value = args[2].c_str();
816    return write_file(path, value);
817}
818
819static int do_copy(const std::vector<std::string>& args) {
820    char *buffer = NULL;
821    int rc = 0;
822    int fd1 = -1, fd2 = -1;
823    struct stat info;
824    int brtw, brtr;
825    char *p;
826
827    if (stat(args[1].c_str(), &info) < 0)
828        return -1;
829
830    if ((fd1 = open(args[1].c_str(), O_RDONLY|O_CLOEXEC)) < 0)
831        goto out_err;
832
833    if ((fd2 = open(args[2].c_str(), O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0660)) < 0)
834        goto out_err;
835
836    if (!(buffer = (char*) malloc(info.st_size)))
837        goto out_err;
838
839    p = buffer;
840    brtr = info.st_size;
841    while(brtr) {
842        rc = read(fd1, p, brtr);
843        if (rc < 0)
844            goto out_err;
845        if (rc == 0)
846            break;
847        p += rc;
848        brtr -= rc;
849    }
850
851    p = buffer;
852    brtw = info.st_size;
853    while(brtw) {
854        rc = write(fd2, p, brtw);
855        if (rc < 0)
856            goto out_err;
857        if (rc == 0)
858            break;
859        p += rc;
860        brtw -= rc;
861    }
862
863    rc = 0;
864    goto out;
865out_err:
866    rc = -1;
867out:
868    if (buffer)
869        free(buffer);
870    if (fd1 >= 0)
871        close(fd1);
872    if (fd2 >= 0)
873        close(fd2);
874    return rc;
875}
876
877static int do_chown(const std::vector<std::string>& args) {
878    /* GID is optional. */
879    if (args.size() == 3) {
880        if (lchown(args[2].c_str(), decode_uid(args[1].c_str()), -1) == -1)
881            return -errno;
882    } else if (args.size() == 4) {
883        if (lchown(args[3].c_str(), decode_uid(args[1].c_str()),
884                   decode_uid(args[2].c_str())) == -1)
885            return -errno;
886    } else {
887        return -1;
888    }
889    return 0;
890}
891
892static mode_t get_mode(const char *s) {
893    mode_t mode = 0;
894    while (*s) {
895        if (*s >= '0' && *s <= '7') {
896            mode = (mode<<3) | (*s-'0');
897        } else {
898            return -1;
899        }
900        s++;
901    }
902    return mode;
903}
904
905static int do_chmod(const std::vector<std::string>& args) {
906    mode_t mode = get_mode(args[1].c_str());
907    if (fchmodat(AT_FDCWD, args[2].c_str(), mode, AT_SYMLINK_NOFOLLOW) < 0) {
908        return -errno;
909    }
910    return 0;
911}
912
913static int do_restorecon(const std::vector<std::string>& args) {
914    int ret = 0;
915
916    for (auto it = std::next(args.begin()); it != args.end(); ++it) {
917        if (restorecon(it->c_str()) < 0)
918            ret = -errno;
919    }
920    return ret;
921}
922
923static int do_restorecon_recursive(const std::vector<std::string>& args) {
924    int ret = 0;
925
926    for (auto it = std::next(args.begin()); it != args.end(); ++it) {
927        /* The contents of CE paths are encrypted on FBE devices until user
928         * credentials are presented (filenames inside are mangled), so we need
929         * to delay restorecon of those until vold explicitly requests it. */
930        if (restorecon_recursive_skipce(it->c_str()) < 0) {
931            ret = -errno;
932        }
933    }
934    return ret;
935}
936
937static int do_loglevel(const std::vector<std::string>& args) {
938    int log_level = std::stoi(args[1]);
939    if (log_level < KLOG_ERROR_LEVEL || log_level > KLOG_DEBUG_LEVEL) {
940        ERROR("loglevel: invalid log level'%d'\n", log_level);
941        return -EINVAL;
942    }
943    klog_set_level(log_level);
944    return 0;
945}
946
947static int do_load_persist_props(const std::vector<std::string>& args) {
948    load_persist_props();
949    return 0;
950}
951
952static int do_load_system_props(const std::vector<std::string>& args) {
953    load_system_props();
954    return 0;
955}
956
957static int do_wait(const std::vector<std::string>& args) {
958    if (args.size() == 2) {
959        return wait_for_file(args[1].c_str(), COMMAND_RETRY_TIMEOUT);
960    } else if (args.size() == 3) {
961        return wait_for_file(args[1].c_str(), std::stoi(args[2]));
962    } else
963        return -1;
964}
965
966/*
967 * Callback to make a directory from the ext4 code
968 */
969static int do_installkeys_ensure_dir_exists(const char* dir) {
970    if (make_dir(dir, 0700) && errno != EEXIST) {
971        return -1;
972    }
973
974    return 0;
975}
976
977static bool is_file_crypto() {
978    std::string value = property_get("ro.crypto.type");
979    return value == "file";
980}
981
982static int do_installkey(const std::vector<std::string>& args) {
983    if (!is_file_crypto()) {
984        return 0;
985    }
986    return e4crypt_create_device_key(args[1].c_str(),
987                                     do_installkeys_ensure_dir_exists);
988}
989
990static int do_init_user0(const std::vector<std::string>& args) {
991    return e4crypt_do_init_user0();
992}
993
994BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const {
995    constexpr std::size_t kMax = std::numeric_limits<std::size_t>::max();
996    static const Map builtin_functions = {
997        {"bootchart_init",          {0,     0,    do_bootchart_init}},
998        {"chmod",                   {2,     2,    do_chmod}},
999        {"chown",                   {2,     3,    do_chown}},
1000        {"class_reset",             {1,     1,    do_class_reset}},
1001        {"class_start",             {1,     1,    do_class_start}},
1002        {"class_stop",              {1,     1,    do_class_stop}},
1003        {"copy",                    {2,     2,    do_copy}},
1004        {"domainname",              {1,     1,    do_domainname}},
1005        {"enable",                  {1,     1,    do_enable}},
1006        {"exec",                    {1,     kMax, do_exec}},
1007        {"export",                  {2,     2,    do_export}},
1008        {"hostname",                {1,     1,    do_hostname}},
1009        {"ifup",                    {1,     1,    do_ifup}},
1010        {"init_user0",              {0,     0,    do_init_user0}},
1011        {"insmod",                  {1,     kMax, do_insmod}},
1012        {"installkey",              {1,     1,    do_installkey}},
1013        {"load_persist_props",      {0,     0,    do_load_persist_props}},
1014        {"load_system_props",       {0,     0,    do_load_system_props}},
1015        {"loglevel",                {1,     1,    do_loglevel}},
1016        {"mkdir",                   {1,     4,    do_mkdir}},
1017        {"mount_all",               {1,     kMax, do_mount_all}},
1018        {"mount",                   {3,     kMax, do_mount}},
1019        {"umount",                  {1,     1,    do_umount}},
1020        {"powerctl",                {1,     1,    do_powerctl}},
1021        {"restart",                 {1,     1,    do_restart}},
1022        {"restorecon",              {1,     kMax, do_restorecon}},
1023        {"restorecon_recursive",    {1,     kMax, do_restorecon_recursive}},
1024        {"rm",                      {1,     1,    do_rm}},
1025        {"rmdir",                   {1,     1,    do_rmdir}},
1026        {"setprop",                 {2,     2,    do_setprop}},
1027        {"setrlimit",               {3,     3,    do_setrlimit}},
1028        {"start",                   {1,     1,    do_start}},
1029        {"stop",                    {1,     1,    do_stop}},
1030        {"swapon_all",              {1,     1,    do_swapon_all}},
1031        {"symlink",                 {2,     2,    do_symlink}},
1032        {"sysclktz",                {1,     1,    do_sysclktz}},
1033        {"trigger",                 {1,     1,    do_trigger}},
1034        {"verity_load_state",       {0,     0,    do_verity_load_state}},
1035        {"verity_update_state",     {0,     0,    do_verity_update_state}},
1036        {"wait",                    {1,     2,    do_wait}},
1037        {"write",                   {2,     2,    do_write}},
1038    };
1039    return builtin_functions;
1040}
1041