14f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project/*
24f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
34f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project *
44f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
54f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * you may not use this file except in compliance with the License.
64f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * You may obtain a copy of the License at
74f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project *
84f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
94f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project *
104f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
114f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
124f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * See the License for the specific language governing permissions and
144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project * limitations under the License.
154f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project */
164f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
178d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes#include <ctype.h>
186a52443d31d4de56ead022a55f63683316d96634Rom Lemarchand#include <dirent.h>
198d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes#include <errno.h>
208d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes#include <fcntl.h>
215d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman#include <fstream>
228d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes#include <libgen.h>
23cc86fb2b29b13570ff416d4590a8cab705b19ec3Elliott Hughes#include <paths.h>
248d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes#include <signal.h>
258d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes#include <stdarg.h>
264f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <stdio.h>
274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <stdlib.h>
284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <string.h>
29929f4070767d1e4806c058849178afa13d9ded1eElliott Hughes#include <sys/epoll.h>
304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <sys/mount.h>
314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <sys/socket.h>
328d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes#include <sys/stat.h>
338d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes#include <sys/types.h>
344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include <sys/un.h>
358d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes#include <sys/wait.h>
368d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes#include <unistd.h>
378d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes
388d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes#include <mtd/mtd-user.h>
39e46f9d510db9351682cf17c49115110870147335Stephen Smalley
40e46f9d510db9351682cf17c49115110870147335Stephen Smalley#include <selinux/selinux.h>
41e46f9d510db9351682cf17c49115110870147335Stephen Smalley#include <selinux/label.h>
42ae6f3d7c05070f7e0e56fe0056c8923c6ee2f473Stephen Smalley#include <selinux/android.h>
43e46f9d510db9351682cf17c49115110870147335Stephen Smalley
444f71319df011d796a60a43fc1bc68e16fbf7d321Elliott Hughes#include <android-base/file.h>
454f71319df011d796a60a43fc1bc68e16fbf7d321Elliott Hughes#include <android-base/stringprintf.h>
464f71319df011d796a60a43fc1bc68e16fbf7d321Elliott Hughes#include <android-base/strings.h>
4756fa0ac6b6e4ca790c0169c21a3106e09cab672cNick Kralevich#include <cutils/android_reboot.h>
480d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin#include <cutils/fs.h>
498d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes#include <cutils/iosched_policy.h>
508d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes#include <cutils/list.h>
518d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes#include <cutils/sockets.h>
52f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross#include <private/android_filesystem_config.h>
534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
546a52443d31d4de56ead022a55f63683316d96634Rom Lemarchand#include <memory>
556a52443d31d4de56ead022a55f63683316d96634Rom Lemarchand
56fa0c21c94ccb98bfa5cf3cc7a6b220be4a5fa378Tom Cherry#include "action.h"
57bac3299720623f4226bca103b26260052732ad30Tom Cherry#include "bootchart.h"
584f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include "devices.h"
59b7349902a945903f9e36a569051f5131beb0bc24Tom Cherry#include "import_parser.h"
604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include "init.h"
61bac3299720623f4226bca103b26260052732ad30Tom Cherry#include "init_parser.h"
62bac3299720623f4226bca103b26260052732ad30Tom Cherry#include "keychords.h"
63ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross#include "log.h"
644f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project#include "property_service.h"
65bac3299720623f4226bca103b26260052732ad30Tom Cherry#include "service.h"
669c5366ba55b1553b2d66f48e3d14fbd274a2944dColin Cross#include "signal_handler.h"
67f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross#include "ueventd.h"
68bac3299720623f4226bca103b26260052732ad30Tom Cherry#include "util.h"
69d97d9074ba818de5af45ce4e0f5c30053ae467d0Arve Hjønnevåg#include "watchdogd.h"
704f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
71e46f9d510db9351682cf17c49115110870147335Stephen Smalleystruct selabel_handle *sehandle;
7263207cd20f2156bec937a85e789f07de0d1afa9drpcraigstruct selabel_handle *sehandle_prop;
73e46f9d510db9351682cf17c49115110870147335Stephen Smalley
744f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic int property_triggers_enabled = 0;
754f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
764f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic char qemu[32];
774f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
78bac3299720623f4226bca103b26260052732ad30Tom Cherryint have_console;
79bac3299720623f4226bca103b26260052732ad30Tom Cherrystd::string console_name = "/dev/console";
804f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic time_t process_needs_restart;
814f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
82bac3299720623f4226bca103b26260052732ad30Tom Cherryconst char *ENV[32];
834f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
848d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughesbool waiting_for_exec = false;
858d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes
86929f4070767d1e4806c058849178afa13d9ded1eElliott Hughesstatic int epoll_fd = -1;
87929f4070767d1e4806c058849178afa13d9ded1eElliott Hughes
88929f4070767d1e4806c058849178afa13d9ded1eElliott Hughesvoid register_epoll_handler(int fd, void (*fn)()) {
89929f4070767d1e4806c058849178afa13d9ded1eElliott Hughes    epoll_event ev;
90929f4070767d1e4806c058849178afa13d9ded1eElliott Hughes    ev.events = EPOLLIN;
91929f4070767d1e4806c058849178afa13d9ded1eElliott Hughes    ev.data.ptr = reinterpret_cast<void*>(fn);
92929f4070767d1e4806c058849178afa13d9ded1eElliott Hughes    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ev) == -1) {
93929f4070767d1e4806c058849178afa13d9ded1eElliott Hughes        ERROR("epoll_ctl failed: %s\n", strerror(errno));
94929f4070767d1e4806c058849178afa13d9ded1eElliott Hughes    }
95929f4070767d1e4806c058849178afa13d9ded1eElliott Hughes}
96929f4070767d1e4806c058849178afa13d9ded1eElliott Hughes
974f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project/* add_environment - add "key=value" to the current environment */
984f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectint add_environment(const char *key, const char *val)
994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
100381341f5f72a46b34126e5c8e6f62f04b702ba47James Morrissey    size_t n;
101381341f5f72a46b34126e5c8e6f62f04b702ba47James Morrissey    size_t key_len = strlen(key);
102381341f5f72a46b34126e5c8e6f62f04b702ba47James Morrissey
103381341f5f72a46b34126e5c8e6f62f04b702ba47James Morrissey    /* The last environment entry is reserved to terminate the list */
104381341f5f72a46b34126e5c8e6f62f04b702ba47James Morrissey    for (n = 0; n < (ARRAY_SIZE(ENV) - 1); n++) {
105381341f5f72a46b34126e5c8e6f62f04b702ba47James Morrissey
106381341f5f72a46b34126e5c8e6f62f04b702ba47James Morrissey        /* Delete any existing entry for this key */
107381341f5f72a46b34126e5c8e6f62f04b702ba47James Morrissey        if (ENV[n] != NULL) {
108381341f5f72a46b34126e5c8e6f62f04b702ba47James Morrissey            size_t entry_key_len = strcspn(ENV[n], "=");
109381341f5f72a46b34126e5c8e6f62f04b702ba47James Morrissey            if ((entry_key_len == key_len) && (strncmp(ENV[n], key, entry_key_len) == 0)) {
110381341f5f72a46b34126e5c8e6f62f04b702ba47James Morrissey                free((char*)ENV[n]);
111381341f5f72a46b34126e5c8e6f62f04b702ba47James Morrissey                ENV[n] = NULL;
112381341f5f72a46b34126e5c8e6f62f04b702ba47James Morrissey            }
113381341f5f72a46b34126e5c8e6f62f04b702ba47James Morrissey        }
1142b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine
115381341f5f72a46b34126e5c8e6f62f04b702ba47James Morrissey        /* Add entry if a free slot is available */
116381341f5f72a46b34126e5c8e6f62f04b702ba47James Morrissey        if (ENV[n] == NULL) {
117f3cf438714aa1284d8a58e2f3b108ba93f6d3abbElliott Hughes            char* entry;
118f3cf438714aa1284d8a58e2f3b108ba93f6d3abbElliott Hughes            asprintf(&entry, "%s=%s", key, val);
1194f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            ENV[n] = entry;
1204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            return 0;
1214f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        }
1224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
1234f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
124381341f5f72a46b34126e5c8e6f62f04b702ba47James Morrissey    ERROR("No env. room to store: '%s':'%s'\n", key, val);
125381341f5f72a46b34126e5c8e6f62f04b702ba47James Morrissey
126381341f5f72a46b34126e5c8e6f62f04b702ba47James Morrissey    return -1;
1274f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
1284f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1294f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectvoid property_changed(const char *name, const char *value)
1304f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
131ebc6ff105a114ff5b5465e64fa0f3889730da19dColin Cross    if (property_triggers_enabled)
132fa0c21c94ccb98bfa5cf3cc7a6b220be4a5fa378Tom Cherry        ActionManager::GetInstance().QueuePropertyTrigger(name, value);
1334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
1344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
1354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Projectstatic void restart_processes()
1364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
1374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    process_needs_restart = 0;
138bac3299720623f4226bca103b26260052732ad30Tom Cherry    ServiceManager::GetInstance().
139bac3299720623f4226bca103b26260052732ad30Tom Cherry        ForEachServiceWithFlags(SVC_RESTARTING, [] (Service* s) {
140bac3299720623f4226bca103b26260052732ad30Tom Cherry                s->RestartIfNeeded(process_needs_restart);
141bac3299720623f4226bca103b26260052732ad30Tom Cherry            });
1424f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
1434f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
144a3cc6026301db08285028c760af2665a66b3cc44Elliott Hughesvoid handle_control_message(const std::string& msg, const std::string& name) {
145bac3299720623f4226bca103b26260052732ad30Tom Cherry    Service* svc = ServiceManager::GetInstance().FindServiceByName(name);
146a3cc6026301db08285028c760af2665a66b3cc44Elliott Hughes    if (svc == nullptr) {
147bac3299720623f4226bca103b26260052732ad30Tom Cherry        ERROR("no such service '%s'\n", name.c_str());
148a3cc6026301db08285028c760af2665a66b3cc44Elliott Hughes        return;
149b54f39fdd97c50e0e8dfa439722be0786f5e6f52Mike Kasick    }
150b54f39fdd97c50e0e8dfa439722be0786f5e6f52Mike Kasick
151bac3299720623f4226bca103b26260052732ad30Tom Cherry    if (msg == "start") {
152a3cc6026301db08285028c760af2665a66b3cc44Elliott Hughes        svc->Start();
153bac3299720623f4226bca103b26260052732ad30Tom Cherry    } else if (msg == "stop") {
154a3cc6026301db08285028c760af2665a66b3cc44Elliott Hughes        svc->Stop();
155bac3299720623f4226bca103b26260052732ad30Tom Cherry    } else if (msg == "restart") {
156a3cc6026301db08285028c760af2665a66b3cc44Elliott Hughes        svc->Restart();
1574f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    } else {
158bac3299720623f4226bca103b26260052732ad30Tom Cherry        ERROR("unknown control msg '%s'\n", msg.c_str());
1594f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
1604f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
1614f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
16296f67316a22bc9236aed70b198e91a5406389e5bTom Cherrystatic int wait_for_coldboot_done_action(const std::vector<std::string>& args) {
163c6c26ed781d9ae1ba388cebba63532d2ecda3227Elliott Hughes    Timer t;
164c6c26ed781d9ae1ba388cebba63532d2ecda3227Elliott Hughes
165c6c26ed781d9ae1ba388cebba63532d2ecda3227Elliott Hughes    NOTICE("Waiting for %s...\n", COLDBOOT_DONE);
166c7331d02d1c6b1e51b3a1210506f38fd61819495Elliott Hughes    // Any longer than 1s is an unreasonable length of time to delay booting.
167c7331d02d1c6b1e51b3a1210506f38fd61819495Elliott Hughes    // If you're hitting this timeout, check that you didn't make your
168c7331d02d1c6b1e51b3a1210506f38fd61819495Elliott Hughes    // sepolicy regular expressions too expensive (http://b/19899875).
169c7331d02d1c6b1e51b3a1210506f38fd61819495Elliott Hughes    if (wait_for_file(COLDBOOT_DONE, 1)) {
170a016c42b4f7122625a417929afa0e9379ffa4887Andreas Gampe        ERROR("Timed out waiting for %s\n", COLDBOOT_DONE);
171c6c26ed781d9ae1ba388cebba63532d2ecda3227Elliott Hughes    }
172c6c26ed781d9ae1ba388cebba63532d2ecda3227Elliott Hughes
173c6c26ed781d9ae1ba388cebba63532d2ecda3227Elliott Hughes    NOTICE("Waiting for %s took %.2fs.\n", COLDBOOT_DONE, t.duration());
174c6c26ed781d9ae1ba388cebba63532d2ecda3227Elliott Hughes    return 0;
175ebc6ff105a114ff5b5465e64fa0f3889730da19dColin Cross}
176ebc6ff105a114ff5b5465e64fa0f3889730da19dColin Cross
1770d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin/*
1780d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin * Writes 512 bytes of output from Hardware RNG (/dev/hw_random, backed
1790d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin * by Linux kernel's hw_random framework) into Linux RNG's via /dev/urandom.
1800d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin * Does nothing if Hardware RNG is not present.
1810d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin *
1820d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin * Since we don't yet trust the quality of Hardware RNG, these bytes are not
1830d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin * mixed into the primary pool of Linux RNG and the entropy estimate is left
1840d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin * unmodified.
1850d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin *
1860d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin * If the HW RNG device /dev/hw_random is present, we require that at least
1870d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin * 512 bytes read from it are written into Linux RNG. QA is expected to catch
1880d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin * devices/configurations where these I/O operations are blocking for a long
1890d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin * time. We do not reboot or halt on failures, as this is a best-effort
1900d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin * attempt.
1910d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin */
19296f67316a22bc9236aed70b198e91a5406389e5bTom Cherrystatic int mix_hwrng_into_linux_rng_action(const std::vector<std::string>& args)
1930d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin{
1940d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin    int result = -1;
1950d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin    int hwrandom_fd = -1;
1960d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin    int urandom_fd = -1;
1970d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin    char buf[512];
1980d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin    ssize_t chunk_size;
1990d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin    size_t total_bytes_written = 0;
2000d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin
2010d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin    hwrandom_fd = TEMP_FAILURE_RETRY(
20245a884f85f8eae602fe6e7c9718c90db65675e07Nick Kralevich            open("/dev/hw_random", O_RDONLY | O_NOFOLLOW | O_CLOEXEC));
2030d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin    if (hwrandom_fd == -1) {
2040d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin        if (errno == ENOENT) {
2050d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin          ERROR("/dev/hw_random not found\n");
2060d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin          /* It's not an error to not have a Hardware RNG. */
2070d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin          result = 0;
2080d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin        } else {
2090d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin          ERROR("Failed to open /dev/hw_random: %s\n", strerror(errno));
2100d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin        }
2110d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin        goto ret;
2120d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin    }
2130d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin
2140d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin    urandom_fd = TEMP_FAILURE_RETRY(
21545a884f85f8eae602fe6e7c9718c90db65675e07Nick Kralevich            open("/dev/urandom", O_WRONLY | O_NOFOLLOW | O_CLOEXEC));
2160d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin    if (urandom_fd == -1) {
2170d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin        ERROR("Failed to open /dev/urandom: %s\n", strerror(errno));
2180d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin        goto ret;
2190d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin    }
2200d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin
2210d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin    while (total_bytes_written < sizeof(buf)) {
2220d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin        chunk_size = TEMP_FAILURE_RETRY(
2230d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin                read(hwrandom_fd, buf, sizeof(buf) - total_bytes_written));
2240d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin        if (chunk_size == -1) {
2250d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin            ERROR("Failed to read from /dev/hw_random: %s\n", strerror(errno));
2260d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin            goto ret;
2270d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin        } else if (chunk_size == 0) {
2280d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin            ERROR("Failed to read from /dev/hw_random: EOF\n");
2290d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin            goto ret;
2300d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin        }
2310d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin
2320d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin        chunk_size = TEMP_FAILURE_RETRY(write(urandom_fd, buf, chunk_size));
2330d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin        if (chunk_size == -1) {
2340d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin            ERROR("Failed to write to /dev/urandom: %s\n", strerror(errno));
2350d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin            goto ret;
2360d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin        }
2370d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin        total_bytes_written += chunk_size;
2380d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin    }
2390d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin
240ccecf1425412beb2bc3bb38d470293fdc244d6f1Elliott Hughes    INFO("Mixed %zu bytes from /dev/hw_random into /dev/urandom",
2410d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin                total_bytes_written);
2420d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin    result = 0;
2430d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin
2440d872d8bb4f5371200601b7615ea48993383befbAlex Klyubinret:
2450d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin    if (hwrandom_fd != -1) {
2460d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin        close(hwrandom_fd);
2470d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin    }
2480d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin    if (urandom_fd != -1) {
2490d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin        close(urandom_fd);
2500d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin    }
2510d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin    return result;
2520d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin}
2530d872d8bb4f5371200601b7615ea48993383befbAlex Klyubin
2545d36813dc8d3be3f62856cf5147b828a7a8594a7dcashmanstatic void security_failure() {
2555d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    ERROR("Security failure; rebooting into recovery mode...\n");
2565d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    android_reboot(ANDROID_RB_RESTART2, 0, "recovery");
2575d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    while (true) { pause(); }  // never reached
2585d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman}
2595d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman
2605d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman#define MMAP_RND_PATH "/proc/sys/vm/mmap_rnd_bits"
2615d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman#define MMAP_RND_COMPAT_PATH "/proc/sys/vm/mmap_rnd_compat_bits"
2625d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman
2635d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman/* __attribute__((unused)) due to lack of mips support: see mips block
2645d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman * in set_mmap_rnd_bits_action */
2655d36813dc8d3be3f62856cf5147b828a7a8594a7dcashmanstatic bool __attribute__((unused)) set_mmap_rnd_bits_min(int start, int min, bool compat) {
2665d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    std::string path;
2675d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    if (compat) {
2685d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman        path = MMAP_RND_COMPAT_PATH;
2695d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    } else {
2705d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman        path = MMAP_RND_PATH;
2715d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    }
2725d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    std::ifstream inf(path, std::fstream::in);
2735d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    if (!inf) {
2745d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman        return false;
2755d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    }
2765d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    while (start >= min) {
2775d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman        // try to write out new value
2785d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman        std::string str_val = std::to_string(start);
2795d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman        std::ofstream of(path, std::fstream::out);
2805d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman        if (!of) {
2815d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman            return false;
2825d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman        }
2835d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman        of << str_val << std::endl;
2845d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman        of.close();
2855d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman
2865d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman        // check to make sure it was recorded
2875d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman        inf.seekg(0);
2885d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman        std::string str_rec;
2895d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman        inf >> str_rec;
2905d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman        if (str_val.compare(str_rec) == 0) {
2915d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman            break;
2925d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman        }
2935d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman        start--;
2945d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    }
2955d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    inf.close();
2965d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    return (start >= min);
2975d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman}
2985d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman
2995d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman/*
3005d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman * Set /proc/sys/vm/mmap_rnd_bits and potentially
3015d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman * /proc/sys/vm/mmap_rnd_compat_bits to the maximum supported values.
3025d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman * Returns -1 if unable to set these to an acceptable value.  Apply
3035d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman * upstream patch-sets https://lkml.org/lkml/2015/12/21/337 and
3045d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman * https://lkml.org/lkml/2016/2/4/831 to enable this.
3055d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman */
3065d36813dc8d3be3f62856cf5147b828a7a8594a7dcashmanstatic int set_mmap_rnd_bits_action(const std::vector<std::string>& args)
3075d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman{
3085d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    int ret = -1;
3095d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman
3105d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    /* values are arch-dependent */
3115d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman#if defined(__aarch64__)
3125d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    /* arm64 supports 18 - 33 bits depending on pagesize and VA_SIZE */
3135d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    if (set_mmap_rnd_bits_min(33, 24, false)
3145d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman            && set_mmap_rnd_bits_min(16, 16, true)) {
3155d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman        ret = 0;
3165d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    }
3179261ad13ed8a6bf5d43450f3eb5a48ecd65587f1dcashman#elif defined(__x86_64__)
3185d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    /* x86_64 supports 28 - 32 bits */
3195d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    if (set_mmap_rnd_bits_min(32, 32, false)
3205d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman            && set_mmap_rnd_bits_min(16, 16, true)) {
3215d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman        ret = 0;
3225d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    }
3235d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman#elif defined(__arm__) || defined(__i386__)
3245d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    /* check to see if we're running on 64-bit kernel */
3255d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    bool h64 = !access(MMAP_RND_COMPAT_PATH, F_OK);
3265d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    /* supported 32-bit architecture must have 16 bits set */
3275d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    if (set_mmap_rnd_bits_min(16, 16, h64)) {
3285d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman        ret = 0;
3295d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    }
3305d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman#elif defined(__mips__) || defined(__mips64__)
3315d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    // TODO: add mips support b/27788820
3325d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    ret = 0;
3335d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman#else
3345d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    ERROR("Unknown architecture\n");
3355d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman#endif
33669022e03d81e43455cf7c21555314c4d08664311dcashman
33769022e03d81e43455cf7c21555314c4d08664311dcashman#ifdef __BRILLO__
33869022e03d81e43455cf7c21555314c4d08664311dcashman    // TODO: b/27794137
33969022e03d81e43455cf7c21555314c4d08664311dcashman    ret = 0;
34069022e03d81e43455cf7c21555314c4d08664311dcashman#endif
3415d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    if (ret == -1) {
3425d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman        ERROR("Unable to set adequate mmap entropy value!\n");
3435d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman        security_failure();
3445d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    }
3455d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    return ret;
3465d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman}
3475d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman
34896f67316a22bc9236aed70b198e91a5406389e5bTom Cherrystatic int keychord_init_action(const std::vector<std::string>& args)
349ebc6ff105a114ff5b5465e64fa0f3889730da19dColin Cross{
350ebc6ff105a114ff5b5465e64fa0f3889730da19dColin Cross    keychord_init();
351ebc6ff105a114ff5b5465e64fa0f3889730da19dColin Cross    return 0;
352ebc6ff105a114ff5b5465e64fa0f3889730da19dColin Cross}
353ebc6ff105a114ff5b5465e64fa0f3889730da19dColin Cross
35496f67316a22bc9236aed70b198e91a5406389e5bTom Cherrystatic int console_init_action(const std::vector<std::string>& args)
3554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project{
35674edcea90e31a3795e58aa1b2bbe96032f0bcd61Yabin Cui    std::string console = property_get("ro.boot.console");
35774edcea90e31a3795e58aa1b2bbe96032f0bcd61Yabin Cui    if (!console.empty()) {
35874edcea90e31a3795e58aa1b2bbe96032f0bcd61Yabin Cui        console_name = "/dev/" + console;
359ebc6ff105a114ff5b5465e64fa0f3889730da19dColin Cross    }
360ebc6ff105a114ff5b5465e64fa0f3889730da19dColin Cross
36174edcea90e31a3795e58aa1b2bbe96032f0bcd61Yabin Cui    int fd = open(console_name.c_str(), O_RDWR | O_CLOEXEC);
362ebc6ff105a114ff5b5465e64fa0f3889730da19dColin Cross    if (fd >= 0)
363ebc6ff105a114ff5b5465e64fa0f3889730da19dColin Cross        have_console = 1;
364ebc6ff105a114ff5b5465e64fa0f3889730da19dColin Cross    close(fd);
365ebc6ff105a114ff5b5465e64fa0f3889730da19dColin Cross
36645a884f85f8eae602fe6e7c9718c90db65675e07Nick Kralevich    fd = open("/dev/tty0", O_WRONLY | O_CLOEXEC);
36750dc936964e057ad779ce271c6d1c12e4d81f0aaMarcin Chojnacki    if (fd >= 0) {
36850dc936964e057ad779ce271c6d1c12e4d81f0aaMarcin Chojnacki        const char *msg;
36950dc936964e057ad779ce271c6d1c12e4d81f0aaMarcin Chojnacki            msg = "\n"
37050dc936964e057ad779ce271c6d1c12e4d81f0aaMarcin Chojnacki        "\n"
37150dc936964e057ad779ce271c6d1c12e4d81f0aaMarcin Chojnacki        "\n"
37250dc936964e057ad779ce271c6d1c12e4d81f0aaMarcin Chojnacki        "\n"
37350dc936964e057ad779ce271c6d1c12e4d81f0aaMarcin Chojnacki        "\n"
37450dc936964e057ad779ce271c6d1c12e4d81f0aaMarcin Chojnacki        "\n"
37550dc936964e057ad779ce271c6d1c12e4d81f0aaMarcin Chojnacki        "\n"  // console is 40 cols x 30 lines
37650dc936964e057ad779ce271c6d1c12e4d81f0aaMarcin Chojnacki        "\n"
37750dc936964e057ad779ce271c6d1c12e4d81f0aaMarcin Chojnacki        "\n"
37850dc936964e057ad779ce271c6d1c12e4d81f0aaMarcin Chojnacki        "\n"
37950dc936964e057ad779ce271c6d1c12e4d81f0aaMarcin Chojnacki        "\n"
38050dc936964e057ad779ce271c6d1c12e4d81f0aaMarcin Chojnacki        "\n"
38150dc936964e057ad779ce271c6d1c12e4d81f0aaMarcin Chojnacki        "\n"
38250dc936964e057ad779ce271c6d1c12e4d81f0aaMarcin Chojnacki        "\n"
38350dc936964e057ad779ce271c6d1c12e4d81f0aaMarcin Chojnacki        "             A N D R O I D ";
38450dc936964e057ad779ce271c6d1c12e4d81f0aaMarcin Chojnacki        write(fd, msg, strlen(msg));
38550dc936964e057ad779ce271c6d1c12e4d81f0aaMarcin Chojnacki        close(fd);
386ebc6ff105a114ff5b5465e64fa0f3889730da19dColin Cross    }
38750dc936964e057ad779ce271c6d1c12e4d81f0aaMarcin Chojnacki
388ebc6ff105a114ff5b5465e64fa0f3889730da19dColin Cross    return 0;
389ebc6ff105a114ff5b5465e64fa0f3889730da19dColin Cross}
390ebc6ff105a114ff5b5465e64fa0f3889730da19dColin Cross
391e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughesstatic void import_kernel_nv(const std::string& key, const std::string& value, bool for_emulator) {
392e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughes    if (key.empty()) return;
3935511c84a50617d1b3c280beb49de38ed1aae21c6Dima Zavin
3945511c84a50617d1b3c280beb49de38ed1aae21c6Dima Zavin    if (for_emulator) {
395e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughes        // In the emulator, export any kernel option with the "ro.kernel." prefix.
396e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughes        property_set(android::base::StringPrintf("ro.kernel.%s", key.c_str()).c_str(), value.c_str());
3975511c84a50617d1b3c280beb49de38ed1aae21c6Dima Zavin        return;
3985511c84a50617d1b3c280beb49de38ed1aae21c6Dima Zavin    }
3995511c84a50617d1b3c280beb49de38ed1aae21c6Dima Zavin
400e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughes    if (key == "qemu") {
401e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughes        strlcpy(qemu, value.c_str(), sizeof(qemu));
402e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughes    } else if (android::base::StartsWith(key, "androidboot.")) {
403e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughes        property_set(android::base::StringPrintf("ro.boot.%s", key.c_str() + 12).c_str(),
404e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughes                     value.c_str());
4055511c84a50617d1b3c280beb49de38ed1aae21c6Dima Zavin    }
4065511c84a50617d1b3c280beb49de38ed1aae21c6Dima Zavin}
4075511c84a50617d1b3c280beb49de38ed1aae21c6Dima Zavin
4089e9efcadc5144e465314d30ca7b3db0ec0a2bc57Sami Tolvanenstatic void export_oem_lock_status() {
4099e9efcadc5144e465314d30ca7b3db0ec0a2bc57Sami Tolvanen    if (property_get("ro.oem_unlock_supported") != "1") {
4109e9efcadc5144e465314d30ca7b3db0ec0a2bc57Sami Tolvanen        return;
4119e9efcadc5144e465314d30ca7b3db0ec0a2bc57Sami Tolvanen    }
4129e9efcadc5144e465314d30ca7b3db0ec0a2bc57Sami Tolvanen
4139e9efcadc5144e465314d30ca7b3db0ec0a2bc57Sami Tolvanen    std::string value = property_get("ro.boot.verifiedbootstate");
4149e9efcadc5144e465314d30ca7b3db0ec0a2bc57Sami Tolvanen
4159e9efcadc5144e465314d30ca7b3db0ec0a2bc57Sami Tolvanen    if (!value.empty()) {
4169e9efcadc5144e465314d30ca7b3db0ec0a2bc57Sami Tolvanen        property_set("ro.boot.flash.locked", value == "orange" ? "0" : "1");
4179e9efcadc5144e465314d30ca7b3db0ec0a2bc57Sami Tolvanen    }
4189e9efcadc5144e465314d30ca7b3db0ec0a2bc57Sami Tolvanen}
4199e9efcadc5144e465314d30ca7b3db0ec0a2bc57Sami Tolvanen
420d679bc9e568fa1e7d1d2ce9f478b1d4f00dae42aElliott Hughesstatic void export_kernel_boot_props() {
4215511c84a50617d1b3c280beb49de38ed1aae21c6Dima Zavin    struct {
4225511c84a50617d1b3c280beb49de38ed1aae21c6Dima Zavin        const char *src_prop;
423d679bc9e568fa1e7d1d2ce9f478b1d4f00dae42aElliott Hughes        const char *dst_prop;
424d679bc9e568fa1e7d1d2ce9f478b1d4f00dae42aElliott Hughes        const char *default_value;
4255511c84a50617d1b3c280beb49de38ed1aae21c6Dima Zavin    } prop_map[] = {
426d679bc9e568fa1e7d1d2ce9f478b1d4f00dae42aElliott Hughes        { "ro.boot.serialno",   "ro.serialno",   "", },
427d679bc9e568fa1e7d1d2ce9f478b1d4f00dae42aElliott Hughes        { "ro.boot.mode",       "ro.bootmode",   "unknown", },
428d679bc9e568fa1e7d1d2ce9f478b1d4f00dae42aElliott Hughes        { "ro.boot.baseband",   "ro.baseband",   "unknown", },
4295511c84a50617d1b3c280beb49de38ed1aae21c6Dima Zavin        { "ro.boot.bootloader", "ro.bootloader", "unknown", },
430d679bc9e568fa1e7d1d2ce9f478b1d4f00dae42aElliott Hughes        { "ro.boot.hardware",   "ro.hardware",   "unknown", },
431d679bc9e568fa1e7d1d2ce9f478b1d4f00dae42aElliott Hughes        { "ro.boot.revision",   "ro.revision",   "0", },
4325511c84a50617d1b3c280beb49de38ed1aae21c6Dima Zavin    };
433d679bc9e568fa1e7d1d2ce9f478b1d4f00dae42aElliott Hughes    for (size_t i = 0; i < ARRAY_SIZE(prop_map); i++) {
43474edcea90e31a3795e58aa1b2bbe96032f0bcd61Yabin Cui        std::string value = property_get(prop_map[i].src_prop);
43574edcea90e31a3795e58aa1b2bbe96032f0bcd61Yabin Cui        property_set(prop_map[i].dst_prop, (!value.empty()) ? value.c_str() : prop_map[i].default_value);
4365511c84a50617d1b3c280beb49de38ed1aae21c6Dima Zavin    }
4375511c84a50617d1b3c280beb49de38ed1aae21c6Dima Zavin}
438ebc6ff105a114ff5b5465e64fa0f3889730da19dColin Cross
439e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughesstatic void process_kernel_dt() {
4406a52443d31d4de56ead022a55f63683316d96634Rom Lemarchand    static const char android_dir[] = "/proc/device-tree/firmware/android";
4416a52443d31d4de56ead022a55f63683316d96634Rom Lemarchand
4426a52443d31d4de56ead022a55f63683316d96634Rom Lemarchand    std::string file_name = android::base::StringPrintf("%s/compatible", android_dir);
4436a52443d31d4de56ead022a55f63683316d96634Rom Lemarchand
4446a52443d31d4de56ead022a55f63683316d96634Rom Lemarchand    std::string dt_file;
4456a52443d31d4de56ead022a55f63683316d96634Rom Lemarchand    android::base::ReadFileToString(file_name, &dt_file);
4466a52443d31d4de56ead022a55f63683316d96634Rom Lemarchand    if (!dt_file.compare("android,firmware")) {
4476a52443d31d4de56ead022a55f63683316d96634Rom Lemarchand        ERROR("firmware/android is not compatible with 'android,firmware'\n");
4486a52443d31d4de56ead022a55f63683316d96634Rom Lemarchand        return;
4496a52443d31d4de56ead022a55f63683316d96634Rom Lemarchand    }
4506a52443d31d4de56ead022a55f63683316d96634Rom Lemarchand
4516a52443d31d4de56ead022a55f63683316d96634Rom Lemarchand    std::unique_ptr<DIR, int(*)(DIR*)>dir(opendir(android_dir), closedir);
452e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughes    if (!dir) return;
4536a52443d31d4de56ead022a55f63683316d96634Rom Lemarchand
4546a52443d31d4de56ead022a55f63683316d96634Rom Lemarchand    struct dirent *dp;
4556a52443d31d4de56ead022a55f63683316d96634Rom Lemarchand    while ((dp = readdir(dir.get())) != NULL) {
4561dcf325844df54a3a2d274f37dea8dd676391eedRom Lemarchand        if (dp->d_type != DT_REG || !strcmp(dp->d_name, "compatible") || !strcmp(dp->d_name, "name")) {
4576a52443d31d4de56ead022a55f63683316d96634Rom Lemarchand            continue;
458e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughes        }
4596a52443d31d4de56ead022a55f63683316d96634Rom Lemarchand
4606a52443d31d4de56ead022a55f63683316d96634Rom Lemarchand        file_name = android::base::StringPrintf("%s/%s", android_dir, dp->d_name);
4616a52443d31d4de56ead022a55f63683316d96634Rom Lemarchand
4626a52443d31d4de56ead022a55f63683316d96634Rom Lemarchand        android::base::ReadFileToString(file_name, &dt_file);
4636a52443d31d4de56ead022a55f63683316d96634Rom Lemarchand        std::replace(dt_file.begin(), dt_file.end(), ',', '.');
4646a52443d31d4de56ead022a55f63683316d96634Rom Lemarchand
4656a52443d31d4de56ead022a55f63683316d96634Rom Lemarchand        std::string property_name = android::base::StringPrintf("ro.boot.%s", dp->d_name);
466db3f267c99411b10144998c6c1f1a6288d0191bcElliott Hughes        property_set(property_name.c_str(), dt_file.c_str());
4676a52443d31d4de56ead022a55f63683316d96634Rom Lemarchand    }
4686a52443d31d4de56ead022a55f63683316d96634Rom Lemarchand}
4696a52443d31d4de56ead022a55f63683316d96634Rom Lemarchand
470e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughesstatic void process_kernel_cmdline() {
471e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughes    // Don't expose the raw commandline to unprivileged processes.
4725511c84a50617d1b3c280beb49de38ed1aae21c6Dima Zavin    chmod("/proc/cmdline", 0440);
473ebc6ff105a114ff5b5465e64fa0f3889730da19dColin Cross
474e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughes    // The first pass does the common stuff, and finds if we are in qemu.
475e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughes    // The second pass is only necessary for qemu to export all kernel params
476e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughes    // as properties.
477f667a3247a7e814355feedbc08c6bbc92a9409b5Nick Kralevich    import_kernel_cmdline(false, import_kernel_nv);
478e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughes    if (qemu[0]) import_kernel_cmdline(true, import_kernel_nv);
479ebc6ff105a114ff5b5465e64fa0f3889730da19dColin Cross}
480ebc6ff105a114ff5b5465e64fa0f3889730da19dColin Cross
481876ad4571e2eab037a2537f7334220e249a78343caozhiyuanstatic int property_enable_triggers_action(const std::vector<std::string>& args)
482876ad4571e2eab037a2537f7334220e249a78343caozhiyuan{
483876ad4571e2eab037a2537f7334220e249a78343caozhiyuan    /* Enable property triggers. */
484876ad4571e2eab037a2537f7334220e249a78343caozhiyuan    property_triggers_enabled = 1;
485876ad4571e2eab037a2537f7334220e249a78343caozhiyuan    return 0;
486876ad4571e2eab037a2537f7334220e249a78343caozhiyuan}
487876ad4571e2eab037a2537f7334220e249a78343caozhiyuan
48896f67316a22bc9236aed70b198e91a5406389e5bTom Cherrystatic int queue_property_triggers_action(const std::vector<std::string>& args)
489ebc6ff105a114ff5b5465e64fa0f3889730da19dColin Cross{
490876ad4571e2eab037a2537f7334220e249a78343caozhiyuan    ActionManager::GetInstance().QueueBuiltinAction(property_enable_triggers_action, "enable_property_trigger");
491fa0c21c94ccb98bfa5cf3cc7a6b220be4a5fa378Tom Cherry    ActionManager::GetInstance().QueueAllPropertyTriggers();
492ebc6ff105a114ff5b5465e64fa0f3889730da19dColin Cross    return 0;
493ebc6ff105a114ff5b5465e64fa0f3889730da19dColin Cross}
494ebc6ff105a114ff5b5465e64fa0f3889730da19dColin Cross
495c6c26ed781d9ae1ba388cebba63532d2ecda3227Elliott Hughesstatic void selinux_init_all_handles(void)
496e46f9d510db9351682cf17c49115110870147335Stephen Smalley{
497ae6f3d7c05070f7e0e56fe0056c8923c6ee2f473Stephen Smalley    sehandle = selinux_android_file_context_handle();
498dbd37f2e1da5b27ef1ad6d0cc9580e6893560f5fStephen Smalley    selinux_android_set_sehandle(sehandle);
49963207cd20f2156bec937a85e789f07de0d1afa9drpcraig    sehandle_prop = selinux_android_prop_context_handle();
500ae6f3d7c05070f7e0e56fe0056c8923c6ee2f473Stephen Smalley}
501e46f9d510db9351682cf17c49115110870147335Stephen Smalley
502d34e407aeb5898f19d4f042b7558420bbb3a1817Nick Kralevichenum selinux_enforcing_status { SELINUX_PERMISSIVE, SELINUX_ENFORCING };
503f667a3247a7e814355feedbc08c6bbc92a9409b5Nick Kralevich
504f667a3247a7e814355feedbc08c6bbc92a9409b5Nick Kralevichstatic selinux_enforcing_status selinux_status_from_cmdline() {
505f667a3247a7e814355feedbc08c6bbc92a9409b5Nick Kralevich    selinux_enforcing_status status = SELINUX_ENFORCING;
506f667a3247a7e814355feedbc08c6bbc92a9409b5Nick Kralevich
507e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughes    import_kernel_cmdline(false, [&](const std::string& key, const std::string& value, bool in_qemu) {
508e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughes        if (key == "androidboot.selinux" && value == "permissive") {
509e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughes            status = SELINUX_PERMISSIVE;
510f667a3247a7e814355feedbc08c6bbc92a9409b5Nick Kralevich        }
511e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughes    });
512f667a3247a7e814355feedbc08c6bbc92a9409b5Nick Kralevich
513f667a3247a7e814355feedbc08c6bbc92a9409b5Nick Kralevich    return status;
514f667a3247a7e814355feedbc08c6bbc92a9409b5Nick Kralevich}
515f667a3247a7e814355feedbc08c6bbc92a9409b5Nick Kralevich
516935bd3e31574ea83db84797b0dee2a6581a19cdfNick Kralevichstatic bool selinux_is_enforcing(void)
517935bd3e31574ea83db84797b0dee2a6581a19cdfNick Kralevich{
518d34e407aeb5898f19d4f042b7558420bbb3a1817Nick Kralevich    if (ALLOW_PERMISSIVE_SELINUX) {
519f667a3247a7e814355feedbc08c6bbc92a9409b5Nick Kralevich        return selinux_status_from_cmdline() == SELINUX_ENFORCING;
520935bd3e31574ea83db84797b0dee2a6581a19cdfNick Kralevich    }
521935bd3e31574ea83db84797b0dee2a6581a19cdfNick Kralevich    return true;
522935bd3e31574ea83db84797b0dee2a6581a19cdfNick Kralevich}
523935bd3e31574ea83db84797b0dee2a6581a19cdfNick Kralevich
524ae6f3d7c05070f7e0e56fe0056c8923c6ee2f473Stephen Smalleyint selinux_reload_policy(void)
525ae6f3d7c05070f7e0e56fe0056c8923c6ee2f473Stephen Smalley{
526ae6f3d7c05070f7e0e56fe0056c8923c6ee2f473Stephen Smalley    INFO("SELinux: Attempting to reload policy files\n");
527e46f9d510db9351682cf17c49115110870147335Stephen Smalley
528ae6f3d7c05070f7e0e56fe0056c8923c6ee2f473Stephen Smalley    if (selinux_android_reload_policy() == -1) {
529ae6f3d7c05070f7e0e56fe0056c8923c6ee2f473Stephen Smalley        return -1;
530e46f9d510db9351682cf17c49115110870147335Stephen Smalley    }
531e46f9d510db9351682cf17c49115110870147335Stephen Smalley
532ae6f3d7c05070f7e0e56fe0056c8923c6ee2f473Stephen Smalley    if (sehandle)
533ae6f3d7c05070f7e0e56fe0056c8923c6ee2f473Stephen Smalley        selabel_close(sehandle);
534e46f9d510db9351682cf17c49115110870147335Stephen Smalley
53563207cd20f2156bec937a85e789f07de0d1afa9drpcraig    if (sehandle_prop)
53663207cd20f2156bec937a85e789f07de0d1afa9drpcraig        selabel_close(sehandle_prop);
53763207cd20f2156bec937a85e789f07de0d1afa9drpcraig
538ae6f3d7c05070f7e0e56fe0056c8923c6ee2f473Stephen Smalley    selinux_init_all_handles();
539ae6f3d7c05070f7e0e56fe0056c8923c6ee2f473Stephen Smalley    return 0;
540e46f9d510db9351682cf17c49115110870147335Stephen Smalley}
54163207cd20f2156bec937a85e789f07de0d1afa9drpcraig
542da40c00137f75543a69972f1be506e2d14a41845Elliott Hughesstatic int audit_callback(void *data, security_class_t /*cls*/, char *buf, size_t len) {
543d7aea443d9bc0b1f37a2c31d0d476d61ff41fb66William Roberts
544d7aea443d9bc0b1f37a2c31d0d476d61ff41fb66William Roberts    property_audit_data *d = reinterpret_cast<property_audit_data*>(data);
545d7aea443d9bc0b1f37a2c31d0d476d61ff41fb66William Roberts
546d7aea443d9bc0b1f37a2c31d0d476d61ff41fb66William Roberts    if (!d || !d->name || !d->cr) {
547d7aea443d9bc0b1f37a2c31d0d476d61ff41fb66William Roberts        ERROR("audit_callback invoked with null data arguments!");
548d7aea443d9bc0b1f37a2c31d0d476d61ff41fb66William Roberts        return 0;
549d7aea443d9bc0b1f37a2c31d0d476d61ff41fb66William Roberts    }
550d7aea443d9bc0b1f37a2c31d0d476d61ff41fb66William Roberts
551d7aea443d9bc0b1f37a2c31d0d476d61ff41fb66William Roberts    snprintf(buf, len, "property=%s pid=%d uid=%d gid=%d", d->name,
552d7aea443d9bc0b1f37a2c31d0d476d61ff41fb66William Roberts            d->cr->pid, d->cr->uid, d->cr->gid);
55363207cd20f2156bec937a85e789f07de0d1afa9drpcraig    return 0;
55463207cd20f2156bec937a85e789f07de0d1afa9drpcraig}
55563207cd20f2156bec937a85e789f07de0d1afa9drpcraig
556f65730e620dde083133b8c1ab61c0d07b4dd8c2fElliott Hughesstatic void selinux_initialize(bool in_kernel_domain) {
557da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes    Timer t;
558da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes
559da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes    selinux_callback cb;
560da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes    cb.func_log = selinux_klog_callback;
561da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes    selinux_set_callback(SELINUX_CB_LOG, cb);
562da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes    cb.func_audit = audit_callback;
563da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes    selinux_set_callback(SELINUX_CB_AUDIT, cb);
564eb3f421e028608e37e4eb814351f03b99ae55900Stephen Smalley
565f65730e620dde083133b8c1ab61c0d07b4dd8c2fElliott Hughes    if (in_kernel_domain) {
566f65730e620dde083133b8c1ab61c0d07b4dd8c2fElliott Hughes        INFO("Loading SELinux policy...\n");
567f65730e620dde083133b8c1ab61c0d07b4dd8c2fElliott Hughes        if (selinux_android_load_policy() < 0) {
568f65730e620dde083133b8c1ab61c0d07b4dd8c2fElliott Hughes            ERROR("failed to load policy: %s\n", strerror(errno));
569f65730e620dde083133b8c1ab61c0d07b4dd8c2fElliott Hughes            security_failure();
570f65730e620dde083133b8c1ab61c0d07b4dd8c2fElliott Hughes        }
571f65730e620dde083133b8c1ab61c0d07b4dd8c2fElliott Hughes
572d34e407aeb5898f19d4f042b7558420bbb3a1817Nick Kralevich        bool kernel_enforcing = (security_getenforce() == 1);
573f65730e620dde083133b8c1ab61c0d07b4dd8c2fElliott Hughes        bool is_enforcing = selinux_is_enforcing();
574d34e407aeb5898f19d4f042b7558420bbb3a1817Nick Kralevich        if (kernel_enforcing != is_enforcing) {
575d34e407aeb5898f19d4f042b7558420bbb3a1817Nick Kralevich            if (security_setenforce(is_enforcing)) {
576d34e407aeb5898f19d4f042b7558420bbb3a1817Nick Kralevich                ERROR("security_setenforce(%s) failed: %s\n",
577d34e407aeb5898f19d4f042b7558420bbb3a1817Nick Kralevich                      is_enforcing ? "true" : "false", strerror(errno));
578d34e407aeb5898f19d4f042b7558420bbb3a1817Nick Kralevich                security_failure();
579d34e407aeb5898f19d4f042b7558420bbb3a1817Nick Kralevich            }
580d34e407aeb5898f19d4f042b7558420bbb3a1817Nick Kralevich        }
581da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes
582eedbe81f753fd19e5eb2238187c5618e9153bf55Nick Kralevich        if (write_file("/sys/fs/selinux/checkreqprot", "0") == -1) {
583eedbe81f753fd19e5eb2238187c5618e9153bf55Nick Kralevich            security_failure();
584eedbe81f753fd19e5eb2238187c5618e9153bf55Nick Kralevich        }
585eedbe81f753fd19e5eb2238187c5618e9153bf55Nick Kralevich
586f65730e620dde083133b8c1ab61c0d07b4dd8c2fElliott Hughes        NOTICE("(Initializing SELinux %s took %.2fs.)\n",
587f65730e620dde083133b8c1ab61c0d07b4dd8c2fElliott Hughes               is_enforcing ? "enforcing" : "non-enforcing", t.duration());
588f65730e620dde083133b8c1ab61c0d07b4dd8c2fElliott Hughes    } else {
589f65730e620dde083133b8c1ab61c0d07b4dd8c2fElliott Hughes        selinux_init_all_handles();
590f65730e620dde083133b8c1ab61c0d07b4dd8c2fElliott Hughes    }
59156fa0ac6b6e4ca790c0169c21a3106e09cab672cNick Kralevich}
59256fa0ac6b6e4ca790c0169c21a3106e09cab672cNick Kralevich
5938d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughesint main(int argc, char** argv) {
594da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes    if (!strcmp(basename(argv[0]), "ueventd")) {
595f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross        return ueventd_main(argc, argv);
596da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes    }
597f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross
598da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes    if (!strcmp(basename(argv[0]), "watchdogd")) {
599d97d9074ba818de5af45ce4e0f5c30053ae467d0Arve Hjønnevåg        return watchdogd_main(argc, argv);
600da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes    }
601d97d9074ba818de5af45ce4e0f5c30053ae467d0Arve Hjønnevåg
6028d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes    // Clear the umask.
6034f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    umask(0);
6044f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
605cc86fb2b29b13570ff416d4590a8cab705b19ec3Elliott Hughes    add_environment("PATH", _PATH_DEFPATH);
606cc86fb2b29b13570ff416d4590a8cab705b19ec3Elliott Hughes
6079dec93bfeb7a4c1ef49745f60f551e0b11a35b2dNick Kralevich    bool is_first_stage = (argc == 1) || (strcmp(argv[1], "--second-stage") != 0);
6089dec93bfeb7a4c1ef49745f60f551e0b11a35b2dNick Kralevich
6098d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes    // Get the basic filesystem setup we need put together in the initramdisk
6108d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes    // on / and then we'll let the rc file figure out the rest.
6119dec93bfeb7a4c1ef49745f60f551e0b11a35b2dNick Kralevich    if (is_first_stage) {
612f667a3247a7e814355feedbc08c6bbc92a9409b5Nick Kralevich        mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
613f667a3247a7e814355feedbc08c6bbc92a9409b5Nick Kralevich        mkdir("/dev/pts", 0755);
614f667a3247a7e814355feedbc08c6bbc92a9409b5Nick Kralevich        mkdir("/dev/socket", 0755);
615f667a3247a7e814355feedbc08c6bbc92a9409b5Nick Kralevich        mount("devpts", "/dev/pts", "devpts", 0, NULL);
616c39ba5ae32afb6329d42e61d2941d87ff66d92e3Nick Kralevich        #define MAKE_STR(x) __STRING(x)
617c39ba5ae32afb6329d42e61d2941d87ff66d92e3Nick Kralevich        mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC));
6189dec93bfeb7a4c1ef49745f60f551e0b11a35b2dNick Kralevich        mount("sysfs", "/sys", "sysfs", 0, NULL);
6199dec93bfeb7a4c1ef49745f60f551e0b11a35b2dNick Kralevich    }
6204f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
6218d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes    // We must have some place other than / to create the device nodes for
6228d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes    // kmsg and null, otherwise we won't be able to remount / read-only
6238d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes    // later on. Now that tmpfs is mounted on /dev, we can actually talk
6248d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes    // to the outside world.
6254f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    open_devnull_stdio();
6268f91282ebe1963b9d27f8779ad1342302b293bd2Dima Zavin    klog_init();
627da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes    klog_set_level(KLOG_NOTICE_LEVEL);
628da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes
629e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughes    NOTICE("init %s started!\n", is_first_stage ? "first stage" : "second stage");
630da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes
631f667a3247a7e814355feedbc08c6bbc92a9409b5Nick Kralevich    if (!is_first_stage) {
632f667a3247a7e814355feedbc08c6bbc92a9409b5Nick Kralevich        // Indicate that booting is in progress to background fw loaders, etc.
633f667a3247a7e814355feedbc08c6bbc92a9409b5Nick Kralevich        close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000));
6342b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine
635f667a3247a7e814355feedbc08c6bbc92a9409b5Nick Kralevich        property_init();
6365511c84a50617d1b3c280beb49de38ed1aae21c6Dima Zavin
637f667a3247a7e814355feedbc08c6bbc92a9409b5Nick Kralevich        // If arguments are passed both on the command line and in DT,
638f667a3247a7e814355feedbc08c6bbc92a9409b5Nick Kralevich        // properties set in DT always have priority over the command-line ones.
639f667a3247a7e814355feedbc08c6bbc92a9409b5Nick Kralevich        process_kernel_dt();
640f667a3247a7e814355feedbc08c6bbc92a9409b5Nick Kralevich        process_kernel_cmdline();
641f667a3247a7e814355feedbc08c6bbc92a9409b5Nick Kralevich
642e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughes        // Propagate the kernel variables to internal variables
643f667a3247a7e814355feedbc08c6bbc92a9409b5Nick Kralevich        // used by init as well as the current required properties.
644f667a3247a7e814355feedbc08c6bbc92a9409b5Nick Kralevich        export_kernel_boot_props();
645f667a3247a7e814355feedbc08c6bbc92a9409b5Nick Kralevich    }
6466a52443d31d4de56ead022a55f63683316d96634Rom Lemarchand
647f65730e620dde083133b8c1ab61c0d07b4dd8c2fElliott Hughes    // Set up SELinux, including loading the SELinux policy if we're in the kernel domain.
648f65730e620dde083133b8c1ab61c0d07b4dd8c2fElliott Hughes    selinux_initialize(is_first_stage);
649f65730e620dde083133b8c1ab61c0d07b4dd8c2fElliott Hughes
650f65730e620dde083133b8c1ab61c0d07b4dd8c2fElliott Hughes    // If we're in the kernel domain, re-exec init to transition to the init domain now
651f65730e620dde083133b8c1ab61c0d07b4dd8c2fElliott Hughes    // that the SELinux policy has been loaded.
652f65730e620dde083133b8c1ab61c0d07b4dd8c2fElliott Hughes    if (is_first_stage) {
653f65730e620dde083133b8c1ab61c0d07b4dd8c2fElliott Hughes        if (restorecon("/init") == -1) {
654f65730e620dde083133b8c1ab61c0d07b4dd8c2fElliott Hughes            ERROR("restorecon failed: %s\n", strerror(errno));
655f65730e620dde083133b8c1ab61c0d07b4dd8c2fElliott Hughes            security_failure();
656f65730e620dde083133b8c1ab61c0d07b4dd8c2fElliott Hughes        }
657f65730e620dde083133b8c1ab61c0d07b4dd8c2fElliott Hughes        char* path = argv[0];
658f65730e620dde083133b8c1ab61c0d07b4dd8c2fElliott Hughes        char* args[] = { path, const_cast<char*>("--second-stage"), nullptr };
659f65730e620dde083133b8c1ab61c0d07b4dd8c2fElliott Hughes        if (execv(path, args) == -1) {
660f65730e620dde083133b8c1ab61c0d07b4dd8c2fElliott Hughes            ERROR("execv(\"%s\") failed: %s\n", path, strerror(errno));
661f65730e620dde083133b8c1ab61c0d07b4dd8c2fElliott Hughes            security_failure();
662f65730e620dde083133b8c1ab61c0d07b4dd8c2fElliott Hughes        }
663f65730e620dde083133b8c1ab61c0d07b4dd8c2fElliott Hughes    }
6648d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes
6658d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes    // These directories were necessarily created before initial policy load
6668d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes    // and therefore need their security context restored to the proper value.
6678d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes    // This must happen before /dev is populated by ueventd.
668e5ce30fed81d1918a259be092dcd8bfffc3c2649Elliott Hughes    NOTICE("Running restorecon...\n");
669e096e36e50b4b66638ebc4d3c09c2ee35f538dfaStephen Smalley    restorecon("/dev");
670e096e36e50b4b66638ebc4d3c09c2ee35f538dfaStephen Smalley    restorecon("/dev/socket");
6718e15eabdc0b40e68426eaf3179dc076d20df75b6Geremy Condra    restorecon("/dev/__properties__");
672e36a85cdcc93a84a6869fc8fc3fc82e3639d4398Tom Cherry    restorecon("/property_contexts");
673ae76f6dbcf3dfd6eda223911f91f4a1316433771Nick Kralevich    restorecon_recursive("/sys");
674e46f9d510db9351682cf17c49115110870147335Stephen Smalley
675929f4070767d1e4806c058849178afa13d9ded1eElliott Hughes    epoll_fd = epoll_create1(EPOLL_CLOEXEC);
676929f4070767d1e4806c058849178afa13d9ded1eElliott Hughes    if (epoll_fd == -1) {
677929f4070767d1e4806c058849178afa13d9ded1eElliott Hughes        ERROR("epoll_create1 failed: %s\n", strerror(errno));
678929f4070767d1e4806c058849178afa13d9ded1eElliott Hughes        exit(1);
679929f4070767d1e4806c058849178afa13d9ded1eElliott Hughes    }
680929f4070767d1e4806c058849178afa13d9ded1eElliott Hughes
681929f4070767d1e4806c058849178afa13d9ded1eElliott Hughes    signal_handler_init();
6829042cae40b60f37294073b59744d04c18033a07cElliott Hughes
683e4b7b294f37d9b64d6b7c1931e2c9bfb1a500d68Riley Andrews    property_load_boot_defaults();
6849e9efcadc5144e465314d30ca7b3db0ec0a2bc57Sami Tolvanen    export_oem_lock_status();
685c6c26ed781d9ae1ba388cebba63532d2ecda3227Elliott Hughes    start_property_service();
686d7634c9cdad7bec39294a993b0bc898eaf709829Dima Zavin
687b7349902a945903f9e36a569051f5131beb0bc24Tom Cherry    const BuiltinFunctionMap function_map;
688b7349902a945903f9e36a569051f5131beb0bc24Tom Cherry    Action::set_function_map(&function_map);
689b7349902a945903f9e36a569051f5131beb0bc24Tom Cherry
690b7349902a945903f9e36a569051f5131beb0bc24Tom Cherry    Parser& parser = Parser::GetInstance();
691b7349902a945903f9e36a569051f5131beb0bc24Tom Cherry    parser.AddSectionParser("service",std::make_unique<ServiceParser>());
692b7349902a945903f9e36a569051f5131beb0bc24Tom Cherry    parser.AddSectionParser("on", std::make_unique<ActionParser>());
693b7349902a945903f9e36a569051f5131beb0bc24Tom Cherry    parser.AddSectionParser("import", std::make_unique<ImportParser>());
694b7349902a945903f9e36a569051f5131beb0bc24Tom Cherry    parser.ParseConfig("/init.rc");
6954f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
696fa0c21c94ccb98bfa5cf3cc7a6b220be4a5fa378Tom Cherry    ActionManager& am = ActionManager::GetInstance();
697fa0c21c94ccb98bfa5cf3cc7a6b220be4a5fa378Tom Cherry
698fa0c21c94ccb98bfa5cf3cc7a6b220be4a5fa378Tom Cherry    am.QueueEventTrigger("early-init");
6994f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
700c6c26ed781d9ae1ba388cebba63532d2ecda3227Elliott Hughes    // Queue an action that waits for coldboot done so we know ueventd has set up all of /dev...
701fa0c21c94ccb98bfa5cf3cc7a6b220be4a5fa378Tom Cherry    am.QueueBuiltinAction(wait_for_coldboot_done_action, "wait_for_coldboot_done");
702c6c26ed781d9ae1ba388cebba63532d2ecda3227Elliott Hughes    // ... so that we can start queuing up actions that require stuff from /dev.
703fa0c21c94ccb98bfa5cf3cc7a6b220be4a5fa378Tom Cherry    am.QueueBuiltinAction(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");
7045d36813dc8d3be3f62856cf5147b828a7a8594a7dcashman    am.QueueBuiltinAction(set_mmap_rnd_bits_action, "set_mmap_rnd_bits");
705fa0c21c94ccb98bfa5cf3cc7a6b220be4a5fa378Tom Cherry    am.QueueBuiltinAction(keychord_init_action, "keychord_init");
706fa0c21c94ccb98bfa5cf3cc7a6b220be4a5fa378Tom Cherry    am.QueueBuiltinAction(console_init_action, "console_init");
7074f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
708da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes    // Trigger all the boot actions to get us started.
709fa0c21c94ccb98bfa5cf3cc7a6b220be4a5fa378Tom Cherry    am.QueueEventTrigger("init");
710ca47cef7491caf6072984d9d64c768717baad09aDima Zavin
7118d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes    // Repeat mix_hwrng_into_linux_rng in case /dev/hw_random or /dev/random
7128d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes    // wasn't ready immediately after wait_for_coldboot_done
713fa0c21c94ccb98bfa5cf3cc7a6b220be4a5fa378Tom Cherry    am.QueueBuiltinAction(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");
7144f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
7158d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes    // Don't mount filesystems or start core system services in charger mode.
71674edcea90e31a3795e58aa1b2bbe96032f0bcd61Yabin Cui    std::string bootmode = property_get("ro.bootmode");
71774edcea90e31a3795e58aa1b2bbe96032f0bcd61Yabin Cui    if (bootmode == "charger") {
718fa0c21c94ccb98bfa5cf3cc7a6b220be4a5fa378Tom Cherry        am.QueueEventTrigger("charger");
719ca47cef7491caf6072984d9d64c768717baad09aDima Zavin    } else {
720fa0c21c94ccb98bfa5cf3cc7a6b220be4a5fa378Tom Cherry        am.QueueEventTrigger("late-init");
721ca47cef7491caf6072984d9d64c768717baad09aDima Zavin    }
7224f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
7238d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes    // Run all property triggers based on current state of the properties.
724fa0c21c94ccb98bfa5cf3cc7a6b220be4a5fa378Tom Cherry    am.QueueBuiltinAction(queue_property_triggers_action, "queue_property_triggers");
725ebc6ff105a114ff5b5465e64fa0f3889730da19dColin Cross
726c6c26ed781d9ae1ba388cebba63532d2ecda3227Elliott Hughes    while (true) {
7278d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes        if (!waiting_for_exec) {
728fa0c21c94ccb98bfa5cf3cc7a6b220be4a5fa378Tom Cherry            am.ExecuteOneCommand();
7298d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes            restart_processes();
7308d82ea05cb0945ba6cb8bf321b9ffbd0b6932745Elliott Hughes        }
7314f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
732a197ff12dd336a9945ad1164402980296f9c235cYongqin Liu        int timeout = -1;
7334f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        if (process_needs_restart) {
7344f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            timeout = (process_needs_restart - gettime()) * 1000;
7354f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project            if (timeout < 0)
7364f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project                timeout = 0;
7374f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        }
7384f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
739fa0c21c94ccb98bfa5cf3cc7a6b220be4a5fa378Tom Cherry        if (am.HasMoreCommands()) {
740ebc6ff105a114ff5b5465e64fa0f3889730da19dColin Cross            timeout = 0;
741c0e919c92062360a69b771722677d041c9998403Elliott Hughes        }
742ebc6ff105a114ff5b5465e64fa0f3889730da19dColin Cross
743a197ff12dd336a9945ad1164402980296f9c235cYongqin Liu        bootchart_sample(&timeout);
744ebc6ff105a114ff5b5465e64fa0f3889730da19dColin Cross
745929f4070767d1e4806c058849178afa13d9ded1eElliott Hughes        epoll_event ev;
746929f4070767d1e4806c058849178afa13d9ded1eElliott Hughes        int nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd, &ev, 1, timeout));
747929f4070767d1e4806c058849178afa13d9ded1eElliott Hughes        if (nr == -1) {
748929f4070767d1e4806c058849178afa13d9ded1eElliott Hughes            ERROR("epoll_wait failed: %s\n", strerror(errno));
749929f4070767d1e4806c058849178afa13d9ded1eElliott Hughes        } else if (nr == 1) {
750929f4070767d1e4806c058849178afa13d9ded1eElliott Hughes            ((void (*)()) ev.data.ptr)();
7514f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project        }
7524f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    }
7534f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project
7544f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project    return 0;
7554f6e8d7a00cbeda1e70cc15be9c4af1018bdad5The Android Open Source Project}
756