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