Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4772f1da authored by Tom Cherry's avatar Tom Cherry
Browse files

init: check the arguments of builtins during the build

Host init verifier already checks that the names and number of
arguments for builtins are correct, but it can check more.  This
change ensures that property expansions are well formed, and that
arguments that can be parsed on the host are correct.  For example it
checks that UIDs and GIDs exist, that numerical values can be parsed,
and that rlimit strings are correct.

Test: build

Change-Id: Ied8882498a88a9f8324db6b8d1020aeeccc8177b
parent c5cf85db
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -227,9 +227,10 @@ cc_benchmark {

genrule {
    name: "generated_stub_builtin_function_map",
    tool_files: ["host_builtin_map.py"],
    out: ["generated_stub_builtin_function_map.h"],
    srcs: ["builtins.cpp"],
    cmd: "sed -n '/Builtin-function-map start/{:a;n;/Builtin-function-map end/q;p;ba}' $(in) | sed -e 's/do_[^}]*/do_stub/g' > $(out)",
    srcs: ["builtins.cpp", "check_builtins.cpp"],
    cmd: "$(location host_builtin_map.py) --builtins $(location builtins.cpp) --check_builtins $(location check_builtins.cpp) > $(out)",
}

cc_binary {
@@ -260,6 +261,7 @@ cc_binary {
        "action_manager.cpp",
        "action_parser.cpp",
        "capabilities.cpp",
        "check_builtins.cpp",
        "epoll.cpp",
        "keychords.cpp",
        "import_parser.cpp",
+36 −0
Original line number Diff line number Diff line
@@ -68,6 +68,30 @@ Result<void> Command::InvokeFunc(Subcontext* subcontext) const {
    return RunBuiltinFunction(func_, args_, kInitContext);
}

Result<void> Command::CheckCommand() const {
    auto builtin_arguments = BuiltinArguments("host_init_verifier");

    builtin_arguments.args.resize(args_.size());
    builtin_arguments.args[0] = args_[0];
    for (size_t i = 1; i < args_.size(); ++i) {
        auto expanded_arg = ExpandProps(args_[i]);
        if (!expanded_arg) {
            if (expanded_arg.error().message().find("doesn't exist while expanding") !=
                std::string::npos) {
                // If we failed because we won't have a property, use an empty string, which is
                // never returned from the parser, to indicate that this field cannot be checked.
                builtin_arguments.args[i] = "";
            } else {
                return expanded_arg.error();
            }
        } else {
            builtin_arguments.args[i] = std::move(*expanded_arg);
        }
    }

    return func_(builtin_arguments);
}

std::string Command::BuildCommandString() const {
    return Join(args_, ' ');
}
@@ -107,6 +131,18 @@ std::size_t Action::NumCommands() const {
    return commands_.size();
}

size_t Action::CheckAllCommands() const {
    size_t failures = 0;
    for (const auto& command : commands_) {
        if (auto result = command.CheckCommand(); !result) {
            LOG(ERROR) << "Command '" << command.BuildCommandString() << "' (" << filename_ << ":"
                       << command.line() << ") failed: " << result.error();
            ++failures;
        }
    }
    return failures;
}

void Action::ExecuteOneCommand(std::size_t command) const {
    // We need a copy here since some Command execution may result in
    // changing commands_ vector by importing .rc files through parser
+4 −5
Original line number Diff line number Diff line
@@ -14,8 +14,7 @@
 * limitations under the License.
 */

#ifndef _INIT_ACTION_H
#define _INIT_ACTION_H
#pragma once

#include <map>
#include <queue>
@@ -41,6 +40,7 @@ class Command {

    Result<void> InvokeFunc(Subcontext* subcontext) const;
    std::string BuildCommandString() const;
    Result<void> CheckCommand() const;

    int line() const { return line_; }

@@ -63,7 +63,7 @@ class Action {

    Result<void> AddCommand(std::vector<std::string>&& args, int line);
    void AddCommand(BuiltinFunction f, std::vector<std::string>&& args, int line);
    std::size_t NumCommands() const;
    size_t NumCommands() const;
    void ExecuteOneCommand(std::size_t command) const;
    void ExecuteAllCommands() const;
    bool CheckEvent(const EventTrigger& event_trigger) const;
@@ -71,6 +71,7 @@ class Action {
    bool CheckEvent(const BuiltinAction& builtin_action) const;
    std::string BuildTriggersString() const;
    void DumpState() const;
    size_t CheckAllCommands() const;

    bool oneshot() const { return oneshot_; }
    const std::string& filename() const { return filename_; }
@@ -96,5 +97,3 @@ class Action {

}  // namespace init
}  // namespace android

#endif
+8 −0
Original line number Diff line number Diff line
@@ -23,6 +23,14 @@ namespace init {

ActionManager::ActionManager() : current_command_(0) {}

size_t ActionManager::CheckAllCommands() {
    size_t failures = 0;
    for (const auto& action : actions_) {
        failures += action->CheckAllCommands();
    }
    return failures;
}

ActionManager& ActionManager::GetInstance() {
    static ActionManager instance;
    return instance;
+2 −4
Original line number Diff line number Diff line
@@ -14,8 +14,7 @@
 * limitations under the License.
 */

#ifndef _INIT_ACTION_MANAGER_H
#define _INIT_ACTION_MANAGER_H
#pragma once

#include <string>
#include <vector>
@@ -32,6 +31,7 @@ class ActionManager {

    // Exposed for testing
    ActionManager();
    size_t CheckAllCommands();

    void AddAction(std::unique_ptr<Action> action);
    void QueueEventTrigger(const std::string& trigger);
@@ -55,5 +55,3 @@ class ActionManager {

}  // namespace init
}  // namespace android

#endif
Loading