Loading init/README.md +3 −1 Original line number Diff line number Diff line Loading @@ -161,11 +161,13 @@ Options Options are modifiers to services. They affect how and when init runs the service. `capabilities <capability> [ <capability>\* ]` `capabilities [ <capability>\* ]` > Set capabilities when exec'ing this service. 'capability' should be a Linux capability without the "CAP\_" prefix, like "NET\_ADMIN" or "SETPCAP". See http://man7.org/linux/man-pages/man7/capabilities.7.html for a list of Linux capabilities. If no capabilities are provided, then all capabilities are removed from this service, even if it runs as root. `class <name> [ <name>\* ]` > Specify class names for the service. All services in a Loading init/service.cpp +12 −14 Original line number Diff line number Diff line Loading @@ -218,12 +218,12 @@ bool Service::is_exec_service_running_ = false; Service::Service(const std::string& name, Subcontext* subcontext_for_restart_commands, const std::vector<std::string>& args) : Service(name, 0, 0, 0, {}, 0, 0, "", subcontext_for_restart_commands, args) {} : Service(name, 0, 0, 0, {}, 0, "", subcontext_for_restart_commands, args) {} Service::Service(const std::string& name, unsigned flags, uid_t uid, gid_t gid, const std::vector<gid_t>& supp_gids, const CapSet& capabilities, unsigned namespace_flags, const std::string& seclabel, Subcontext* subcontext_for_restart_commands, const std::vector<std::string>& args) const std::vector<gid_t>& supp_gids, unsigned namespace_flags, const std::string& seclabel, Subcontext* subcontext_for_restart_commands, const std::vector<std::string>& args) : name_(name), classnames_({"default"}), flags_(flags), Loading @@ -232,7 +232,6 @@ Service::Service(const std::string& name, unsigned flags, uid_t uid, gid_t gid, uid_(uid), gid_(gid), supp_gids_(supp_gids), capabilities_(capabilities), namespace_flags_(namespace_flags), seclabel_(seclabel), onrestart_(false, subcontext_for_restart_commands, "<Service '" + name + "' onrestart>", 0, Loading Loading @@ -289,7 +288,7 @@ void Service::SetProcessAttributes() { } } // Keep capabilites on uid change. if (capabilities_.any() && uid_) { if (capabilities_ && uid_) { // If Android is running in a container, some securebits might already // be locked, so don't change those. unsigned long securebits = prctl(PR_GET_SECUREBITS); Loading Loading @@ -328,8 +327,8 @@ void Service::SetProcessAttributes() { PLOG(FATAL) << "setpriority failed for " << name_; } } if (capabilities_.any()) { if (!SetCapsForExec(capabilities_)) { if (capabilities_) { if (!SetCapsForExec(*capabilities_)) { LOG(FATAL) << "cannot set capabilities for " << name_; } } else if (uid_) { Loading Loading @@ -420,7 +419,7 @@ Result<Success> Service::ParseCapabilities(std::vector<std::string>&& args) { } unsigned int last_valid_cap = GetLastValidCap(); if (last_valid_cap >= capabilities_.size()) { if (last_valid_cap >= capabilities_->size()) { LOG(WARNING) << "last valid run-time capability is larger than CAP_LAST_CAP"; } Loading @@ -435,7 +434,7 @@ Result<Success> Service::ParseCapabilities(std::vector<std::string>&& args) { return Error() << StringPrintf("capability '%s' not supported by the kernel", arg.c_str()); } capabilities_[cap] = true; (*capabilities_)[cap] = true; } return Success(); } Loading Loading @@ -796,7 +795,7 @@ const Service::OptionParserMap::Map& Service::OptionParserMap::map() const { // clang-format off static const Map option_parsers = { {"capabilities", {1, kMax, &Service::ParseCapabilities}}, {0, kMax, &Service::ParseCapabilities}}, {"class", {1, kMax, &Service::ParseClass}}, {"console", {0, 1, &Service::ParseConsole}}, {"critical", {0, 0, &Service::ParseCritical}}, Loading Loading @@ -1268,7 +1267,6 @@ std::unique_ptr<Service> Service::MakeTemporaryOneshotService(const std::vector< std::string name = "exec " + std::to_string(exec_count) + " (" + Join(str_args, " ") + ")"; unsigned flags = SVC_ONESHOT | SVC_TEMPORARY; CapSet no_capabilities; unsigned namespace_flags = 0; std::string seclabel = ""; Loading Loading @@ -1303,8 +1301,8 @@ std::unique_ptr<Service> Service::MakeTemporaryOneshotService(const std::vector< } } return std::make_unique<Service>(name, flags, *uid, *gid, supp_gids, no_capabilities, namespace_flags, seclabel, nullptr, str_args); return std::make_unique<Service>(name, flags, *uid, *gid, supp_gids, namespace_flags, seclabel, nullptr, str_args); } // Shutdown services in the opposite order that they were started. Loading init/service.h +4 −4 Original line number Diff line number Diff line Loading @@ -68,9 +68,9 @@ class Service { const std::vector<std::string>& args); Service(const std::string& name, unsigned flags, uid_t uid, gid_t gid, const std::vector<gid_t>& supp_gids, const CapSet& capabilities, unsigned namespace_flags, const std::string& seclabel, Subcontext* subcontext_for_restart_commands, const std::vector<std::string>& args); const std::vector<gid_t>& supp_gids, unsigned namespace_flags, const std::string& seclabel, Subcontext* subcontext_for_restart_commands, const std::vector<std::string>& args); static std::unique_ptr<Service> MakeTemporaryOneshotService(const std::vector<std::string>& args); Loading Loading @@ -192,7 +192,7 @@ class Service { uid_t uid_; gid_t gid_; std::vector<gid_t> supp_gids_; CapSet capabilities_; std::optional<CapSet> capabilities_; unsigned namespace_flags_; // Pair of namespace type, path to namespace. std::vector<std::pair<int, std::string>> namespaces_to_enter_; Loading init/service_test.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -57,7 +57,7 @@ TEST(service, pod_initialized) { } Service* service_in_old_memory2 = new (old_memory) Service( "test_old_memory", 0U, 0U, 0U, std::vector<gid_t>(), CapSet(), 0U, "", nullptr, dummy_args); "test_old_memory", 0U, 0U, 0U, std::vector<gid_t>(), 0U, "", nullptr, dummy_args); EXPECT_EQ(0U, service_in_old_memory2->flags()); EXPECT_EQ(0, service_in_old_memory2->pid()); Loading Loading
init/README.md +3 −1 Original line number Diff line number Diff line Loading @@ -161,11 +161,13 @@ Options Options are modifiers to services. They affect how and when init runs the service. `capabilities <capability> [ <capability>\* ]` `capabilities [ <capability>\* ]` > Set capabilities when exec'ing this service. 'capability' should be a Linux capability without the "CAP\_" prefix, like "NET\_ADMIN" or "SETPCAP". See http://man7.org/linux/man-pages/man7/capabilities.7.html for a list of Linux capabilities. If no capabilities are provided, then all capabilities are removed from this service, even if it runs as root. `class <name> [ <name>\* ]` > Specify class names for the service. All services in a Loading
init/service.cpp +12 −14 Original line number Diff line number Diff line Loading @@ -218,12 +218,12 @@ bool Service::is_exec_service_running_ = false; Service::Service(const std::string& name, Subcontext* subcontext_for_restart_commands, const std::vector<std::string>& args) : Service(name, 0, 0, 0, {}, 0, 0, "", subcontext_for_restart_commands, args) {} : Service(name, 0, 0, 0, {}, 0, "", subcontext_for_restart_commands, args) {} Service::Service(const std::string& name, unsigned flags, uid_t uid, gid_t gid, const std::vector<gid_t>& supp_gids, const CapSet& capabilities, unsigned namespace_flags, const std::string& seclabel, Subcontext* subcontext_for_restart_commands, const std::vector<std::string>& args) const std::vector<gid_t>& supp_gids, unsigned namespace_flags, const std::string& seclabel, Subcontext* subcontext_for_restart_commands, const std::vector<std::string>& args) : name_(name), classnames_({"default"}), flags_(flags), Loading @@ -232,7 +232,6 @@ Service::Service(const std::string& name, unsigned flags, uid_t uid, gid_t gid, uid_(uid), gid_(gid), supp_gids_(supp_gids), capabilities_(capabilities), namespace_flags_(namespace_flags), seclabel_(seclabel), onrestart_(false, subcontext_for_restart_commands, "<Service '" + name + "' onrestart>", 0, Loading Loading @@ -289,7 +288,7 @@ void Service::SetProcessAttributes() { } } // Keep capabilites on uid change. if (capabilities_.any() && uid_) { if (capabilities_ && uid_) { // If Android is running in a container, some securebits might already // be locked, so don't change those. unsigned long securebits = prctl(PR_GET_SECUREBITS); Loading Loading @@ -328,8 +327,8 @@ void Service::SetProcessAttributes() { PLOG(FATAL) << "setpriority failed for " << name_; } } if (capabilities_.any()) { if (!SetCapsForExec(capabilities_)) { if (capabilities_) { if (!SetCapsForExec(*capabilities_)) { LOG(FATAL) << "cannot set capabilities for " << name_; } } else if (uid_) { Loading Loading @@ -420,7 +419,7 @@ Result<Success> Service::ParseCapabilities(std::vector<std::string>&& args) { } unsigned int last_valid_cap = GetLastValidCap(); if (last_valid_cap >= capabilities_.size()) { if (last_valid_cap >= capabilities_->size()) { LOG(WARNING) << "last valid run-time capability is larger than CAP_LAST_CAP"; } Loading @@ -435,7 +434,7 @@ Result<Success> Service::ParseCapabilities(std::vector<std::string>&& args) { return Error() << StringPrintf("capability '%s' not supported by the kernel", arg.c_str()); } capabilities_[cap] = true; (*capabilities_)[cap] = true; } return Success(); } Loading Loading @@ -796,7 +795,7 @@ const Service::OptionParserMap::Map& Service::OptionParserMap::map() const { // clang-format off static const Map option_parsers = { {"capabilities", {1, kMax, &Service::ParseCapabilities}}, {0, kMax, &Service::ParseCapabilities}}, {"class", {1, kMax, &Service::ParseClass}}, {"console", {0, 1, &Service::ParseConsole}}, {"critical", {0, 0, &Service::ParseCritical}}, Loading Loading @@ -1268,7 +1267,6 @@ std::unique_ptr<Service> Service::MakeTemporaryOneshotService(const std::vector< std::string name = "exec " + std::to_string(exec_count) + " (" + Join(str_args, " ") + ")"; unsigned flags = SVC_ONESHOT | SVC_TEMPORARY; CapSet no_capabilities; unsigned namespace_flags = 0; std::string seclabel = ""; Loading Loading @@ -1303,8 +1301,8 @@ std::unique_ptr<Service> Service::MakeTemporaryOneshotService(const std::vector< } } return std::make_unique<Service>(name, flags, *uid, *gid, supp_gids, no_capabilities, namespace_flags, seclabel, nullptr, str_args); return std::make_unique<Service>(name, flags, *uid, *gid, supp_gids, namespace_flags, seclabel, nullptr, str_args); } // Shutdown services in the opposite order that they were started. Loading
init/service.h +4 −4 Original line number Diff line number Diff line Loading @@ -68,9 +68,9 @@ class Service { const std::vector<std::string>& args); Service(const std::string& name, unsigned flags, uid_t uid, gid_t gid, const std::vector<gid_t>& supp_gids, const CapSet& capabilities, unsigned namespace_flags, const std::string& seclabel, Subcontext* subcontext_for_restart_commands, const std::vector<std::string>& args); const std::vector<gid_t>& supp_gids, unsigned namespace_flags, const std::string& seclabel, Subcontext* subcontext_for_restart_commands, const std::vector<std::string>& args); static std::unique_ptr<Service> MakeTemporaryOneshotService(const std::vector<std::string>& args); Loading Loading @@ -192,7 +192,7 @@ class Service { uid_t uid_; gid_t gid_; std::vector<gid_t> supp_gids_; CapSet capabilities_; std::optional<CapSet> capabilities_; unsigned namespace_flags_; // Pair of namespace type, path to namespace. std::vector<std::pair<int, std::string>> namespaces_to_enter_; Loading
init/service_test.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -57,7 +57,7 @@ TEST(service, pod_initialized) { } Service* service_in_old_memory2 = new (old_memory) Service( "test_old_memory", 0U, 0U, 0U, std::vector<gid_t>(), CapSet(), 0U, "", nullptr, dummy_args); "test_old_memory", 0U, 0U, 0U, std::vector<gid_t>(), 0U, "", nullptr, dummy_args); EXPECT_EQ(0U, service_in_old_memory2->flags()); EXPECT_EQ(0, service_in_old_memory2->pid()); Loading