diff options
author | Tom Cherry <tomcherry@google.com> | 2017-10-02 20:40:03 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2017-10-02 20:40:03 +0000 |
commit | 821cb5e16ccd3b4566b11abe2621073a698662f9 (patch) | |
tree | 64d589ad8eba9833111eeb8c582e9b01239171dc /init/builtins.cpp | |
parent | a0113de2f379144dd66f144115f31c541524518c (diff) | |
parent | 8e09b0b953d21837e86b81c9ded43979d6a54dac (diff) | |
download | system_core-821cb5e16ccd3b4566b11abe2621073a698662f9.tar.gz system_core-821cb5e16ccd3b4566b11abe2621073a698662f9.tar.bz2 system_core-821cb5e16ccd3b4566b11abe2621073a698662f9.zip |
Merge "init: run vendor commands in a separate SELinux context"
am: 8e09b0b953
Change-Id: I7e0272f29bd8bab029a9f9c07aa413c9172f6f5a
Diffstat (limited to 'init/builtins.cpp')
-rw-r--r-- | init/builtins.cpp | 197 |
1 files changed, 100 insertions, 97 deletions
diff --git a/init/builtins.cpp b/init/builtins.cpp index 0fef8838d..4c2dc9adb 100644 --- a/init/builtins.cpp +++ b/init/builtins.cpp @@ -66,6 +66,7 @@ #include "reboot.h" #include "rlimit_parser.h" #include "service.h" +#include "subcontext.h" #include "util.h" using namespace std::literals::string_literals; @@ -95,36 +96,36 @@ static void ForEachServiceInClass(const std::string& classname, F function) { } } -static Result<Success> do_class_start(const std::vector<std::string>& args) { +static Result<Success> do_class_start(const BuiltinArguments& args) { // Starting a class does not start services which are explicitly disabled. // They must be started individually. ForEachServiceInClass(args[1], &Service::StartIfNotDisabled); return Success(); } -static Result<Success> do_class_stop(const std::vector<std::string>& args) { +static Result<Success> do_class_stop(const BuiltinArguments& args) { ForEachServiceInClass(args[1], &Service::Stop); return Success(); } -static Result<Success> do_class_reset(const std::vector<std::string>& args) { +static Result<Success> do_class_reset(const BuiltinArguments& args) { ForEachServiceInClass(args[1], &Service::Reset); return Success(); } -static Result<Success> do_class_restart(const std::vector<std::string>& args) { +static Result<Success> do_class_restart(const BuiltinArguments& args) { ForEachServiceInClass(args[1], &Service::Restart); return Success(); } -static Result<Success> do_domainname(const std::vector<std::string>& args) { +static Result<Success> do_domainname(const BuiltinArguments& args) { if (auto result = WriteFile("/proc/sys/kernel/domainname", args[1]); !result) { return Error() << "Unable to write to /proc/sys/kernel/domainname: " << result.error(); } return Success(); } -static Result<Success> do_enable(const std::vector<std::string>& args) { +static Result<Success> do_enable(const BuiltinArguments& args) { Service* svc = ServiceList::GetInstance().FindService(args[1]); if (!svc) return Error() << "Could not find service"; @@ -135,8 +136,8 @@ static Result<Success> do_enable(const std::vector<std::string>& args) { return Success(); } -static Result<Success> do_exec(const std::vector<std::string>& args) { - auto service = Service::MakeTemporaryOneshotService(args); +static Result<Success> do_exec(const BuiltinArguments& args) { + auto service = Service::MakeTemporaryOneshotService(args.args); if (!service) { return Error() << "Could not create exec service"; } @@ -148,8 +149,8 @@ static Result<Success> do_exec(const std::vector<std::string>& args) { return Success(); } -static Result<Success> do_exec_background(const std::vector<std::string>& args) { - auto service = Service::MakeTemporaryOneshotService(args); +static Result<Success> do_exec_background(const BuiltinArguments& args) { + auto service = Service::MakeTemporaryOneshotService(args.args); if (!service) { return Error() << "Could not create exec background service"; } @@ -161,7 +162,7 @@ static Result<Success> do_exec_background(const std::vector<std::string>& args) return Success(); } -static Result<Success> do_exec_start(const std::vector<std::string>& args) { +static Result<Success> do_exec_start(const BuiltinArguments& args) { Service* service = ServiceList::GetInstance().FindService(args[1]); if (!service) { return Error() << "Service not found"; @@ -174,21 +175,21 @@ static Result<Success> do_exec_start(const std::vector<std::string>& args) { return Success(); } -static Result<Success> do_export(const std::vector<std::string>& args) { +static Result<Success> do_export(const BuiltinArguments& args) { if (setenv(args[1].c_str(), args[2].c_str(), 1) == -1) { return ErrnoError() << "setenv() failed"; } return Success(); } -static Result<Success> do_hostname(const std::vector<std::string>& args) { +static Result<Success> do_hostname(const BuiltinArguments& args) { if (auto result = WriteFile("/proc/sys/kernel/hostname", args[1]); !result) { return Error() << "Unable to write to /proc/sys/kernel/hostname: " << result.error(); } return Success(); } -static Result<Success> do_ifup(const std::vector<std::string>& args) { +static Result<Success> do_ifup(const BuiltinArguments& args) { struct ifreq ifr; strlcpy(ifr.ifr_name, args[1].c_str(), IFNAMSIZ); @@ -209,7 +210,7 @@ static Result<Success> do_ifup(const std::vector<std::string>& args) { return Success(); } -static Result<Success> do_insmod(const std::vector<std::string>& args) { +static Result<Success> do_insmod(const BuiltinArguments& args) { int flags = 0; auto it = args.begin() + 1; @@ -231,7 +232,7 @@ static Result<Success> do_insmod(const std::vector<std::string>& args) { } // mkdir <path> [mode] [owner] [group] -static Result<Success> do_mkdir(const std::vector<std::string>& args) { +static Result<Success> do_mkdir(const BuiltinArguments& args) { mode_t mode = 0755; if (args.size() >= 3) { mode = std::strtoul(args[2].c_str(), 0, 8); @@ -287,7 +288,7 @@ static Result<Success> do_mkdir(const std::vector<std::string>& args) { } /* umount <path> */ -static Result<Success> do_umount(const std::vector<std::string>& args) { +static Result<Success> do_umount(const BuiltinArguments& args) { if (umount(args[1].c_str()) < 0) { return ErrnoError() << "umount() failed"; } @@ -319,7 +320,7 @@ static struct { #define DATA_MNT_POINT "/data" /* mount <type> <device> <path> <flags ...> <options> */ -static Result<Success> do_mount(const std::vector<std::string>& args) { +static Result<Success> do_mount(const BuiltinArguments& args) { const char* options = nullptr; unsigned flags = 0; bool wait = false; @@ -530,7 +531,7 @@ static Result<Success> queue_fs_event(int code) { * This function might request a reboot, in which case it will * not return. */ -static Result<Success> do_mount_all(const std::vector<std::string>& args) { +static Result<Success> do_mount_all(const BuiltinArguments& args) { std::size_t na = 0; bool import_rc = true; bool queue_event = true; @@ -563,7 +564,7 @@ static Result<Success> do_mount_all(const std::vector<std::string>& args) { if (import_rc) { /* Paths of .rc files are specified at the 2nd argument and beyond */ - import_late(args, 2, path_arg_end); + import_late(args.args, 2, path_arg_end); } if (queue_event) { @@ -578,7 +579,7 @@ static Result<Success> do_mount_all(const std::vector<std::string>& args) { return Success(); } -static Result<Success> do_swapon_all(const std::vector<std::string>& args) { +static Result<Success> do_swapon_all(const BuiltinArguments& args) { struct fstab *fstab; int ret; @@ -590,13 +591,13 @@ static Result<Success> do_swapon_all(const std::vector<std::string>& args) { return Success(); } -static Result<Success> do_setprop(const std::vector<std::string>& args) { +static Result<Success> do_setprop(const BuiltinArguments& args) { property_set(args[1], args[2]); return Success(); } -static Result<Success> do_setrlimit(const std::vector<std::string>& args) { - auto rlimit = ParseRlimit(args); +static Result<Success> do_setrlimit(const BuiltinArguments& args) { + auto rlimit = ParseRlimit(args.args); if (!rlimit) return rlimit.error(); if (setrlimit(rlimit->first, &rlimit->second) == -1) { @@ -605,7 +606,7 @@ static Result<Success> do_setrlimit(const std::vector<std::string>& args) { return Success(); } -static Result<Success> do_start(const std::vector<std::string>& args) { +static Result<Success> do_start(const BuiltinArguments& args) { Service* svc = ServiceList::GetInstance().FindService(args[1]); if (!svc) return Error() << "service " << args[1] << " not found"; if (auto result = svc->Start(); !result) { @@ -614,26 +615,26 @@ static Result<Success> do_start(const std::vector<std::string>& args) { return Success(); } -static Result<Success> do_stop(const std::vector<std::string>& args) { +static Result<Success> do_stop(const BuiltinArguments& args) { Service* svc = ServiceList::GetInstance().FindService(args[1]); if (!svc) return Error() << "service " << args[1] << " not found"; svc->Stop(); return Success(); } -static Result<Success> do_restart(const std::vector<std::string>& args) { +static Result<Success> do_restart(const BuiltinArguments& args) { Service* svc = ServiceList::GetInstance().FindService(args[1]); if (!svc) return Error() << "service " << args[1] << " not found"; svc->Restart(); return Success(); } -static Result<Success> do_trigger(const std::vector<std::string>& args) { +static Result<Success> do_trigger(const BuiltinArguments& args) { ActionManager::GetInstance().QueueEventTrigger(args[1]); return Success(); } -static Result<Success> do_symlink(const std::vector<std::string>& args) { +static Result<Success> do_symlink(const BuiltinArguments& args) { if (symlink(args[1].c_str(), args[2].c_str()) < 0) { // The symlink builtin is often used to create symlinks for older devices to be backwards // compatible with new paths, therefore we skip reporting this error. @@ -645,21 +646,21 @@ static Result<Success> do_symlink(const std::vector<std::string>& args) { return Success(); } -static Result<Success> do_rm(const std::vector<std::string>& args) { +static Result<Success> do_rm(const BuiltinArguments& args) { if (unlink(args[1].c_str()) < 0) { return ErrnoError() << "unlink() failed"; } return Success(); } -static Result<Success> do_rmdir(const std::vector<std::string>& args) { +static Result<Success> do_rmdir(const BuiltinArguments& args) { if (rmdir(args[1].c_str()) < 0) { return ErrnoError() << "rmdir() failed"; } return Success(); } -static Result<Success> do_sysclktz(const std::vector<std::string>& args) { +static Result<Success> do_sysclktz(const BuiltinArguments& args) { struct timezone tz = {}; if (!android::base::ParseInt(args[1], &tz.tz_minuteswest)) { return Error() << "Unable to parse mins_west_of_gmt"; @@ -671,7 +672,7 @@ static Result<Success> do_sysclktz(const std::vector<std::string>& args) { return Success(); } -static Result<Success> do_verity_load_state(const std::vector<std::string>& args) { +static Result<Success> do_verity_load_state(const BuiltinArguments& args) { int mode = -1; bool loaded = fs_mgr_load_verity_state(&mode); if (loaded && mode != VERITY_MODE_DEFAULT) { @@ -687,14 +688,14 @@ static void verity_update_property(fstab_rec *fstab, const char *mount_point, property_set("partition."s + mount_point + ".verified", std::to_string(mode)); } -static Result<Success> do_verity_update_state(const std::vector<std::string>& args) { +static Result<Success> do_verity_update_state(const BuiltinArguments& args) { if (!fs_mgr_update_verity_state(verity_update_property)) { return Error() << "fs_mgr_update_verity_state() failed"; } return Success(); } -static Result<Success> do_write(const std::vector<std::string>& args) { +static Result<Success> do_write(const BuiltinArguments& args) { if (auto result = WriteFile(args[1], args[2]); !result) { return Error() << "Unable to write to file '" << args[1] << "': " << result.error(); } @@ -725,7 +726,7 @@ static Result<Success> readahead_file(const std::string& filename, bool fully) { return Success(); } -static Result<Success> do_readahead(const std::vector<std::string>& args) { +static Result<Success> do_readahead(const BuiltinArguments& args) { struct stat sb; if (stat(args[1].c_str(), &sb)) { @@ -784,7 +785,7 @@ static Result<Success> do_readahead(const std::vector<std::string>& args) { return Success(); } -static Result<Success> do_copy(const std::vector<std::string>& args) { +static Result<Success> do_copy(const BuiltinArguments& args) { auto file_contents = ReadFile(args[1]); if (!file_contents) { return Error() << "Could not read input file '" << args[1] << "': " << file_contents.error(); @@ -796,7 +797,7 @@ static Result<Success> do_copy(const std::vector<std::string>& args) { return Success(); } -static Result<Success> do_chown(const std::vector<std::string>& args) { +static Result<Success> do_chown(const BuiltinArguments& args) { auto uid = DecodeUid(args[1]); if (!uid) { return Error() << "Unable to decode UID for '" << args[1] << "': " << uid.error(); @@ -833,7 +834,7 @@ static mode_t get_mode(const char *s) { return mode; } -static Result<Success> do_chmod(const std::vector<std::string>& args) { +static Result<Success> do_chmod(const BuiltinArguments& args) { mode_t mode = get_mode(args[1].c_str()); if (fchmodat(AT_FDCWD, args[2].c_str(), mode, AT_SYMLINK_NOFOLLOW) < 0) { return ErrnoError() << "fchmodat() failed"; @@ -841,7 +842,7 @@ static Result<Success> do_chmod(const std::vector<std::string>& args) { return Success(); } -static Result<Success> do_restorecon(const std::vector<std::string>& args) { +static Result<Success> do_restorecon(const BuiltinArguments& args) { int ret = 0; struct flag_type {const char* name; int value;}; @@ -883,13 +884,13 @@ static Result<Success> do_restorecon(const std::vector<std::string>& args) { return Success(); } -static Result<Success> do_restorecon_recursive(const std::vector<std::string>& args) { - std::vector<std::string> non_const_args(args); +static Result<Success> do_restorecon_recursive(const BuiltinArguments& args) { + std::vector<std::string> non_const_args(args.args); non_const_args.insert(std::next(non_const_args.begin()), "--recursive"); - return do_restorecon(non_const_args); + return do_restorecon({std::move(non_const_args), args.context}); } -static Result<Success> do_loglevel(const std::vector<std::string>& args) { +static Result<Success> do_loglevel(const BuiltinArguments& args) { // TODO: support names instead/as well? int log_level = -1; android::base::ParseInt(args[1], &log_level); @@ -910,17 +911,17 @@ static Result<Success> do_loglevel(const std::vector<std::string>& args) { return Success(); } -static Result<Success> do_load_persist_props(const std::vector<std::string>& args) { +static Result<Success> do_load_persist_props(const BuiltinArguments& args) { load_persist_props(); return Success(); } -static Result<Success> do_load_system_props(const std::vector<std::string>& args) { +static Result<Success> do_load_system_props(const BuiltinArguments& args) { load_system_props(); return Success(); } -static Result<Success> do_wait(const std::vector<std::string>& args) { +static Result<Success> do_wait(const BuiltinArguments& args) { auto timeout = kCommandRetryTimeout; if (args.size() == 3) { int timeout_int; @@ -937,7 +938,7 @@ static Result<Success> do_wait(const std::vector<std::string>& args) { return Success(); } -static Result<Success> do_wait_for_prop(const std::vector<std::string>& args) { +static Result<Success> do_wait_for_prop(const BuiltinArguments& args) { const char* name = args[1].c_str(); const char* value = args[2].c_str(); size_t value_len = strlen(value); @@ -958,7 +959,7 @@ static bool is_file_crypto() { return android::base::GetProperty("ro.crypto.type", "") == "file"; } -static Result<Success> do_installkey(const std::vector<std::string>& args) { +static Result<Success> do_installkey(const BuiltinArguments& args) { if (!is_file_crypto()) return Success(); auto unencrypted_dir = args[1] + e4crypt_unencrypted_folder; @@ -967,64 +968,66 @@ static Result<Success> do_installkey(const std::vector<std::string>& args) { } std::vector<std::string> exec_args = {"exec", "/system/bin/vdc", "--wait", "cryptfs", "enablefilecrypto"}; - return do_exec(exec_args); + return do_exec({std::move(exec_args), args.context}); } -static Result<Success> do_init_user0(const std::vector<std::string>& args) { +static Result<Success> do_init_user0(const BuiltinArguments& args) { std::vector<std::string> exec_args = {"exec", "/system/bin/vdc", "--wait", "cryptfs", "init_user0"}; - return do_exec(exec_args); + return do_exec({std::move(exec_args), args.context}); } const BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const { constexpr std::size_t kMax = std::numeric_limits<std::size_t>::max(); // clang-format off static const Map builtin_functions = { - {"bootchart", {1, 1, do_bootchart}}, - {"chmod", {2, 2, do_chmod}}, - {"chown", {2, 3, do_chown}}, - {"class_reset", {1, 1, do_class_reset}}, - {"class_restart", {1, 1, do_class_restart}}, - {"class_start", {1, 1, do_class_start}}, - {"class_stop", {1, 1, do_class_stop}}, - {"copy", {2, 2, do_copy}}, - {"domainname", {1, 1, do_domainname}}, - {"enable", {1, 1, do_enable}}, - {"exec", {1, kMax, do_exec}}, - {"exec_background", {1, kMax, do_exec_background}}, - {"exec_start", {1, 1, do_exec_start}}, - {"export", {2, 2, do_export}}, - {"hostname", {1, 1, do_hostname}}, - {"ifup", {1, 1, do_ifup}}, - {"init_user0", {0, 0, do_init_user0}}, - {"insmod", {1, kMax, do_insmod}}, - {"installkey", {1, 1, do_installkey}}, - {"load_persist_props", {0, 0, do_load_persist_props}}, - {"load_system_props", {0, 0, do_load_system_props}}, - {"loglevel", {1, 1, do_loglevel}}, - {"mkdir", {1, 4, do_mkdir}}, - {"mount_all", {1, kMax, do_mount_all}}, - {"mount", {3, kMax, do_mount}}, - {"umount", {1, 1, do_umount}}, - {"readahead", {1, 2, do_readahead}}, - {"restart", {1, 1, do_restart}}, - {"restorecon", {1, kMax, do_restorecon}}, - {"restorecon_recursive", {1, kMax, do_restorecon_recursive}}, - {"rm", {1, 1, do_rm}}, - {"rmdir", {1, 1, do_rmdir}}, - {"setprop", {2, 2, do_setprop}}, - {"setrlimit", {3, 3, do_setrlimit}}, - {"start", {1, 1, do_start}}, - {"stop", {1, 1, do_stop}}, - {"swapon_all", {1, 1, do_swapon_all}}, - {"symlink", {2, 2, do_symlink}}, - {"sysclktz", {1, 1, do_sysclktz}}, - {"trigger", {1, 1, do_trigger}}, - {"verity_load_state", {0, 0, do_verity_load_state}}, - {"verity_update_state", {0, 0, do_verity_update_state}}, - {"wait", {1, 2, do_wait}}, - {"wait_for_prop", {2, 2, do_wait_for_prop}}, - {"write", {2, 2, do_write}}, + {"bootchart", {1, 1, {false, do_bootchart}}}, + {"chmod", {2, 2, {true, do_chmod}}}, + {"chown", {2, 3, {true, do_chown}}}, + {"class_reset", {1, 1, {false, do_class_reset}}}, + {"class_restart", {1, 1, {false, do_class_restart}}}, + {"class_start", {1, 1, {false, do_class_start}}}, + {"class_stop", {1, 1, {false, do_class_stop}}}, + {"copy", {2, 2, {true, do_copy}}}, + {"domainname", {1, 1, {true, do_domainname}}}, + {"enable", {1, 1, {false, do_enable}}}, + {"exec", {1, kMax, {false, do_exec}}}, + {"exec_background", {1, kMax, {false, do_exec_background}}}, + {"exec_start", {1, 1, {false, do_exec_start}}}, + {"export", {2, 2, {false, do_export}}}, + {"hostname", {1, 1, {true, do_hostname}}}, + {"ifup", {1, 1, {true, do_ifup}}}, + {"init_user0", {0, 0, {false, do_init_user0}}}, + {"insmod", {1, kMax, {true, do_insmod}}}, + {"installkey", {1, 1, {false, do_installkey}}}, + {"load_persist_props", {0, 0, {false, do_load_persist_props}}}, + {"load_system_props", {0, 0, {false, do_load_system_props}}}, + {"loglevel", {1, 1, {false, do_loglevel}}}, + {"mkdir", {1, 4, {true, do_mkdir}}}, + {"mount_all", {1, kMax, {false, do_mount_all}}}, + {"mount", {3, kMax, {false, do_mount}}}, + {"umount", {1, 1, {false, do_umount}}}, + {"readahead", {1, 2, {true, do_readahead}}}, + {"restart", {1, 1, {false, do_restart}}}, + {"restorecon", {1, kMax, {true, do_restorecon}}}, + {"restorecon_recursive", {1, kMax, {true, do_restorecon_recursive}}}, + {"rm", {1, 1, {true, do_rm}}}, + {"rmdir", {1, 1, {true, do_rmdir}}}, + // TODO: setprop should be run in the subcontext, but property service needs to be split + // out from init before that is possible. + {"setprop", {2, 2, {false, do_setprop}}}, + {"setrlimit", {3, 3, {false, do_setrlimit}}}, + {"start", {1, 1, {false, do_start}}}, + {"stop", {1, 1, {false, do_stop}}}, + {"swapon_all", {1, 1, {false, do_swapon_all}}}, + {"symlink", {2, 2, {true, do_symlink}}}, + {"sysclktz", {1, 1, {false, do_sysclktz}}}, + {"trigger", {1, 1, {false, do_trigger}}}, + {"verity_load_state", {0, 0, {false, do_verity_load_state}}}, + {"verity_update_state", {0, 0, {false, do_verity_update_state}}}, + {"wait", {1, 2, {true, do_wait}}}, + {"wait_for_prop", {2, 2, {true, do_wait_for_prop}}}, + {"write", {2, 2, {true, do_write}}}, }; // clang-format on return builtin_functions; |