diff --git a/init/README.md b/init/README.md index 3a7c71c6c..f0e5d55ce 100644 --- a/init/README.md +++ b/init/README.md @@ -161,11 +161,13 @@ Options Options are modifiers to services. They affect how and when init runs the service. -`capabilities [ \* ]` +`capabilities [ \* ]` > 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 [ \* ]` > Specify class names for the service. All services in a diff --git a/init/service.cpp b/init/service.cpp index d64f2f395..2186a851f 100644 --- a/init/service.cpp +++ b/init/service.cpp @@ -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& 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& supp_gids, const CapSet& capabilities, - unsigned namespace_flags, const std::string& seclabel, - Subcontext* subcontext_for_restart_commands, const std::vector& args) + const std::vector& supp_gids, unsigned namespace_flags, + const std::string& seclabel, Subcontext* subcontext_for_restart_commands, + const std::vector& args) : name_(name), classnames_({"default"}), flags_(flags), @@ -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, "", 0, @@ -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); @@ -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_) { @@ -420,7 +419,7 @@ Result Service::ParseCapabilities(std::vector&& 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"; } @@ -435,7 +434,7 @@ Result Service::ParseCapabilities(std::vector&& args) { return Error() << StringPrintf("capability '%s' not supported by the kernel", arg.c_str()); } - capabilities_[cap] = true; + (*capabilities_)[cap] = true; } return Success(); } @@ -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}}, @@ -1268,7 +1267,6 @@ std::unique_ptr 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 = ""; @@ -1303,8 +1301,8 @@ std::unique_ptr Service::MakeTemporaryOneshotService(const std::vector< } } - return std::make_unique(name, flags, *uid, *gid, supp_gids, no_capabilities, - namespace_flags, seclabel, nullptr, str_args); + return std::make_unique(name, flags, *uid, *gid, supp_gids, namespace_flags, seclabel, + nullptr, str_args); } // Shutdown services in the opposite order that they were started. diff --git a/init/service.h b/init/service.h index c29723a4e..c42a5a371 100644 --- a/init/service.h +++ b/init/service.h @@ -68,9 +68,9 @@ class Service { const std::vector& args); Service(const std::string& name, unsigned flags, uid_t uid, gid_t gid, - const std::vector& supp_gids, const CapSet& capabilities, - unsigned namespace_flags, const std::string& seclabel, - Subcontext* subcontext_for_restart_commands, const std::vector& args); + const std::vector& supp_gids, unsigned namespace_flags, + const std::string& seclabel, Subcontext* subcontext_for_restart_commands, + const std::vector& args); static std::unique_ptr MakeTemporaryOneshotService(const std::vector& args); @@ -192,7 +192,7 @@ class Service { uid_t uid_; gid_t gid_; std::vector supp_gids_; - CapSet capabilities_; + std::optional capabilities_; unsigned namespace_flags_; // Pair of namespace type, path to namespace. std::vector> namespaces_to_enter_; diff --git a/init/service_test.cpp b/init/service_test.cpp index 194aa2be0..4bfaa6b78 100644 --- a/init/service_test.cpp +++ b/init/service_test.cpp @@ -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(), CapSet(), 0U, "", nullptr, dummy_args); + "test_old_memory", 0U, 0U, 0U, std::vector(), 0U, "", nullptr, dummy_args); EXPECT_EQ(0U, service_in_old_memory2->flags()); EXPECT_EQ(0, service_in_old_memory2->pid());