diff --git a/init/Android.bp b/init/Android.bp index 57555f62f..81e7dd970 100644 --- a/init/Android.bp +++ b/init/Android.bp @@ -130,6 +130,7 @@ cc_library_static { "persistent_properties.cpp", "persistent_properties.proto", "property_service.cpp", + "property_service.proto", "property_type.cpp", "reboot.cpp", "reboot_utils.cpp", diff --git a/init/builtins.cpp b/init/builtins.cpp index d2c73cb69..21db8dca7 100644 --- a/init/builtins.cpp +++ b/init/builtins.cpp @@ -80,6 +80,7 @@ using namespace std::literals::string_literals; using android::base::Basename; +using android::base::StartsWith; using android::base::StringPrintf; using android::base::unique_fd; using android::fs_mgr::Fstab; @@ -701,6 +702,15 @@ static Result do_swapon_all(const BuiltinArguments& args) { } static Result do_setprop(const BuiltinArguments& args) { + if (StartsWith(args[1], "ctl.")) { + return Error() + << "Cannot set ctl. properties from init; call the Service functions directly"; + } + if (args[1] == kRestoreconProperty) { + return Error() << "Cannot set '" << kRestoreconProperty + << "' from init; use the restorecon builtin directly"; + } + property_set(args[1], args[2]); return {}; } @@ -1016,7 +1026,20 @@ static Result do_loglevel(const BuiltinArguments& args) { } static Result do_load_persist_props(const BuiltinArguments& args) { - load_persist_props(); + // Devices with FDE have load_persist_props called twice; the first time when the temporary + // /data partition is mounted and then again once /data is truly mounted. We do not want to + // read persistent properties from the temporary /data partition or mark persistent properties + // as having been loaded during the first call, so we return in that case. + std::string crypto_state = android::base::GetProperty("ro.crypto.state", ""); + std::string crypto_type = android::base::GetProperty("ro.crypto.type", ""); + if (crypto_state == "encrypted" && crypto_type == "block") { + static size_t num_calls = 0; + if (++num_calls == 1) return {}; + } + + SendLoadPersistentPropertiesMessage(); + + start_waiting_for_property("ro.persistent_properties.ready", "true"); return {}; } diff --git a/init/init.cpp b/init/init.cpp index d4cbb5f57..ec3eb3cdf 100644 --- a/init/init.cpp +++ b/init/init.cpp @@ -28,6 +28,9 @@ #include #include +#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_ +#include + #include #include #include @@ -61,6 +64,7 @@ #include "mount_handler.h" #include "mount_namespace.h" #include "property_service.h" +#include "proto_utils.h" #include "reboot.h" #include "reboot_utils.h" #include "security.h" @@ -69,6 +73,7 @@ #include "service.h" #include "service_parser.h" #include "sigchld_handler.h" +#include "system/core/init/property_service.pb.h" #include "util.h" using namespace std::chrono_literals; @@ -90,6 +95,7 @@ static int property_triggers_enabled = 0; static char qemu[32]; static int signal_fd = -1; +static int property_fd = -1; static std::unique_ptr waiting_for_prop(nullptr); static std::string wait_prop_name; @@ -615,6 +621,60 @@ static void RecordStageBoottimes(const boot_clock::time_point& second_stage_star selinux_start_time_ns)); } +void SendLoadPersistentPropertiesMessage() { + auto init_message = InitMessage{}; + init_message.set_load_persistent_properties(true); + if (auto result = SendMessage(property_fd, init_message); !result) { + LOG(ERROR) << "Failed to send load persistent properties message: " << result.error(); + } +} + +void SendStopSendingMessagesMessage() { + auto init_message = InitMessage{}; + init_message.set_stop_sending_messages(true); + if (auto result = SendMessage(property_fd, init_message); !result) { + LOG(ERROR) << "Failed to send load persistent properties message: " << result.error(); + } +} + +static void HandlePropertyFd() { + auto message = ReadMessage(property_fd); + if (!message) { + LOG(ERROR) << "Could not read message from property service: " << message.error(); + return; + } + + auto property_message = PropertyMessage{}; + if (!property_message.ParseFromString(*message)) { + LOG(ERROR) << "Could not parse message from property service"; + return; + } + + switch (property_message.msg_case()) { + case PropertyMessage::kControlMessage: { + auto& control_message = property_message.control_message(); + bool success = HandleControlMessage(control_message.msg(), control_message.name(), + control_message.pid()); + + uint32_t response = success ? PROP_SUCCESS : PROP_ERROR_HANDLE_CONTROL_MESSAGE; + if (control_message.has_fd()) { + int fd = control_message.fd(); + TEMP_FAILURE_RETRY(send(fd, &response, sizeof(response), 0)); + close(fd); + } + break; + } + case PropertyMessage::kChangedMessage: { + auto& changed_message = property_message.changed_message(); + property_changed(changed_message.name(), changed_message.value()); + break; + } + default: + LOG(ERROR) << "Unknown message type from property service: " + << property_message.msg_case(); + } +} + int SecondStageMain(int argc, char** argv) { if (REBOOT_BOOTLOADER_ON_PANIC) { InstallRebootSignalHandlers(); @@ -686,7 +746,12 @@ int SecondStageMain(int argc, char** argv) { UmountDebugRamdisk(); fs_mgr_vendor_overlay_mount_all(); export_oem_lock_status(); - StartPropertyService(&epoll); + + StartPropertyService(&property_fd); + if (auto result = epoll.RegisterHandler(property_fd, HandlePropertyFd); !result) { + LOG(FATAL) << "Could not register epoll handler for property fd: " << result.error(); + } + MountHandler mount_handler(&epoll); set_usb_controller(); diff --git a/init/init.h b/init/init.h index cfc28f1be..8ac52e2c4 100644 --- a/init/init.h +++ b/init/init.h @@ -31,16 +31,15 @@ namespace init { Parser CreateParser(ActionManager& action_manager, ServiceList& service_list); Parser CreateServiceOnlyParser(ServiceList& service_list); -bool HandleControlMessage(const std::string& msg, const std::string& arg, pid_t pid); - -void property_changed(const std::string& name, const std::string& value); - bool start_waiting_for_property(const char *name, const char *value); void DumpState(); void ResetWaitForProp(); +void SendLoadPersistentPropertiesMessage(); +void SendStopSendingMessagesMessage(); + int SecondStageMain(int argc, char** argv); } // namespace init diff --git a/init/property_service.cpp b/init/property_service.cpp index 3408ff3be..c18decc7a 100644 --- a/init/property_service.cpp +++ b/init/property_service.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -63,8 +64,10 @@ #include "init.h" #include "persistent_properties.h" #include "property_type.h" +#include "proto_utils.h" #include "selinux.h" #include "subcontext.h" +#include "system/core/init/property_service.pb.h" #include "util.h" using namespace std::literals; @@ -76,6 +79,7 @@ using android::base::StartsWith; using android::base::StringPrintf; using android::base::Timer; using android::base::Trim; +using android::base::unique_fd; using android::base::WriteStringToFile; using android::properties::BuildTrie; using android::properties::ParsePropertyInfoFile; @@ -85,18 +89,13 @@ using android::properties::PropertyInfoEntry; namespace android { namespace init { -static constexpr const char kRestoreconProperty[] = "selinux.restorecon_recursive"; - static bool persistent_properties_loaded = false; static int property_set_fd = -1; +static int init_socket = -1; static PropertyInfoAreaFile property_info_area; -uint32_t InitPropertySet(const std::string& name, const std::string& value); - -uint32_t (*property_set)(const std::string& name, const std::string& value) = InitPropertySet; - void CreateSerializedPropertyInfo(); struct PropertyAuditData { @@ -164,6 +163,17 @@ static bool CheckMacPerms(const std::string& name, const char* target_context, return has_access; } +static void SendPropertyChanged(const std::string& name, const std::string& value) { + auto property_msg = PropertyMessage{}; + auto* changed_message = property_msg.mutable_changed_message(); + changed_message->set_name(name); + changed_message->set_value(value); + + if (auto result = SendMessage(init_socket, property_msg); !result) { + LOG(ERROR) << "Failed to send property changed message: " << result.error(); + } +} + static uint32_t PropertySet(const std::string& name, const std::string& value, std::string* error) { size_t valuelen = value.size(); @@ -199,7 +209,11 @@ static uint32_t PropertySet(const std::string& name, const std::string& value, s if (persistent_properties_loaded && StartsWith(name, "persist.")) { WritePersistentProperty(name, value); } - property_changed(name, value); + // If init hasn't started its main loop, then it won't be handling property changed messages + // anyway, so there's no need to try to send them. + if (init_socket != -1) { + SendPropertyChanged(name, value); + } return PROP_SUCCESS; } @@ -239,35 +253,10 @@ class AsyncRestorecon { bool thread_started_ = false; }; -uint32_t InitPropertySet(const std::string& name, const std::string& value) { - if (StartsWith(name, "ctl.")) { - LOG(ERROR) << "InitPropertySet: Do not set ctl. properties from init; call the Service " - "functions directly"; - return PROP_ERROR_INVALID_NAME; - } - if (name == kRestoreconProperty) { - LOG(ERROR) << "InitPropertySet: Do not set '" << kRestoreconProperty - << "' from init; use the restorecon builtin directly"; - return PROP_ERROR_INVALID_NAME; - } - - uint32_t result = 0; - ucred cr = {.pid = 1, .uid = 0, .gid = 0}; - std::string error; - result = HandlePropertySet(name, value, kInitContext.c_str(), cr, &error); - if (result != PROP_SUCCESS) { - LOG(ERROR) << "Init cannot set '" << name << "' to '" << value << "': " << error; - } - - return result; -} - class SocketConnection { public: SocketConnection(int socket, const ucred& cred) : socket_(socket), cred_(cred) {} - ~SocketConnection() { close(socket_); } - bool RecvUint32(uint32_t* value, uint32_t* timeout_ms) { return RecvFully(value, sizeof(*value), timeout_ms); } @@ -304,6 +293,9 @@ class SocketConnection { } bool SendUint32(uint32_t value) { + if (!socket_.ok()) { + return true; + } int result = TEMP_FAILURE_RETRY(send(socket_, &value, sizeof(value), 0)); return result == sizeof(value); } @@ -318,7 +310,7 @@ class SocketConnection { return true; } - int socket() { return socket_; } + [[nodiscard]] int Release() { return socket_.release(); } const ucred& cred() { return cred_; } @@ -389,12 +381,46 @@ class SocketConnection { return bytes_left == 0; } - int socket_; + unique_fd socket_; ucred cred_; DISALLOW_IMPLICIT_CONSTRUCTORS(SocketConnection); }; +static uint32_t SendControlMessage(const std::string& msg, const std::string& name, pid_t pid, + SocketConnection* socket, std::string* error) { + if (init_socket == -1) { + *error = "Received control message after shutdown, ignoring"; + return PROP_ERROR_HANDLE_CONTROL_MESSAGE; + } + + auto property_msg = PropertyMessage{}; + auto* control_message = property_msg.mutable_control_message(); + control_message->set_msg(msg); + control_message->set_name(name); + control_message->set_pid(pid); + + // We must release the fd before sending it to init, otherwise there will be a race with init. + // If init calls close() before Release(), then fdsan will see the wrong tag and abort(). + int fd = -1; + if (socket != nullptr) { + fd = socket->Release(); + control_message->set_fd(fd); + } + + if (auto result = SendMessage(init_socket, property_msg); !result) { + // We've already released the fd above, so if we fail to send the message to init, we need + // to manually free it here. + if (fd != -1) { + close(fd); + } + *error = "Failed to send control message: " + result.error().message(); + return PROP_ERROR_HANDLE_CONTROL_MESSAGE; + } + + return PROP_SUCCESS; +} + bool CheckControlPropertyPerms(const std::string& name, const std::string& value, const std::string& source_context, const ucred& cr) { // We check the legacy method first but these properties are dontaudit, so we only log an audit @@ -462,15 +488,14 @@ uint32_t CheckPermissions(const std::string& name, const std::string& value, // This returns one of the enum of PROP_SUCCESS or PROP_ERROR*. uint32_t HandlePropertySet(const std::string& name, const std::string& value, - const std::string& source_context, const ucred& cr, std::string* error) { + const std::string& source_context, const ucred& cr, + SocketConnection* socket, std::string* error) { if (auto ret = CheckPermissions(name, value, source_context, cr, error); ret != PROP_SUCCESS) { return ret; } if (StartsWith(name, "ctl.")) { - return HandleControlMessage(name.c_str() + 4, value, cr.pid) - ? PROP_SUCCESS - : PROP_ERROR_HANDLE_CONTROL_MESSAGE; + return SendControlMessage(name.c_str() + 4, value, cr.pid, socket, error); } // sys.powerctl is a special property that is used to make the device reboot. We want to log @@ -501,6 +526,20 @@ uint32_t HandlePropertySet(const std::string& name, const std::string& value, return PropertySet(name, value, error); } +uint32_t InitPropertySet(const std::string& name, const std::string& value) { + uint32_t result = 0; + ucred cr = {.pid = 1, .uid = 0, .gid = 0}; + std::string error; + result = HandlePropertySet(name, value, kInitContext.c_str(), cr, nullptr, &error); + if (result != PROP_SUCCESS) { + LOG(ERROR) << "Init cannot set '" << name << "' to '" << value << "': " << error; + } + + return result; +} + +uint32_t (*property_set)(const std::string& name, const std::string& value) = InitPropertySet; + static void handle_property_set_fd() { static constexpr uint32_t kDefaultSocketTimeout = 2000; /* ms */ @@ -549,7 +588,8 @@ static void handle_property_set_fd() { const auto& cr = socket.cred(); std::string error; - uint32_t result = HandlePropertySet(prop_name, prop_value, source_context, cr, &error); + uint32_t result = + HandlePropertySet(prop_name, prop_value, source_context, cr, nullptr, &error); if (result != PROP_SUCCESS) { LOG(ERROR) << "Unable to set property '" << prop_name << "' from uid:" << cr.uid << " gid:" << cr.gid << " pid:" << cr.pid << ": " << error; @@ -577,7 +617,7 @@ static void handle_property_set_fd() { const auto& cr = socket.cred(); std::string error; - uint32_t result = HandlePropertySet(name, value, source_context, cr, &error); + uint32_t result = HandlePropertySet(name, value, source_context, cr, &socket, &error); if (result != PROP_SUCCESS) { LOG(ERROR) << "Unable to set property '" << name << "' from uid:" << cr.uid << " gid:" << cr.gid << " pid:" << cr.pid << ": " << error; @@ -741,33 +781,6 @@ static void load_override_properties() { } } -/* When booting an encrypted system, /data is not mounted when the - * property service is started, so any properties stored there are - * not loaded. Vold triggers init to load these properties once it - * has mounted /data. - */ -void load_persist_props(void) { - // Devices with FDE have load_persist_props called twice; the first time when the temporary - // /data partition is mounted and then again once /data is truly mounted. We do not want to - // read persistent properties from the temporary /data partition or mark persistent properties - // as having been loaded during the first call, so we return in that case. - std::string crypto_state = android::base::GetProperty("ro.crypto.state", ""); - std::string crypto_type = android::base::GetProperty("ro.crypto.type", ""); - if (crypto_state == "encrypted" && crypto_type == "block") { - static size_t num_calls = 0; - if (++num_calls == 1) return; - } - - load_override_properties(); - /* Read persistent properties after all default values have been loaded. */ - auto persistent_properties = LoadPersistentProperties(); - for (const auto& persistent_property_record : persistent_properties.properties()) { - property_set(persistent_property_record.name(), persistent_property_record.value()); - } - persistent_properties_loaded = true; - property_set("ro.persistent_properties.ready", "true"); -} - // If the ro.product.[brand|device|manufacturer|model|name] properties have not been explicitly // set, derive them from ro.product.${partition}.* properties static void property_initialize_ro_product_props() { @@ -985,21 +998,92 @@ void CreateSerializedPropertyInfo() { selinux_android_restorecon(kPropertyInfosPath, 0); } -void StartPropertyService(Epoll* epoll) { +static void HandleInitSocket() { + auto message = ReadMessage(init_socket); + if (!message) { + LOG(ERROR) << "Could not read message from init_dedicated_recv_socket: " << message.error(); + return; + } + + auto init_message = InitMessage{}; + if (!init_message.ParseFromString(*message)) { + LOG(ERROR) << "Could not parse message from init"; + return; + } + + switch (init_message.msg_case()) { + case InitMessage::kLoadPersistentProperties: { + load_override_properties(); + // Read persistent properties after all default values have been loaded. + auto persistent_properties = LoadPersistentProperties(); + for (const auto& persistent_property_record : persistent_properties.properties()) { + InitPropertySet(persistent_property_record.name(), + persistent_property_record.value()); + } + InitPropertySet("ro.persistent_properties.ready", "true"); + persistent_properties_loaded = true; + break; + } + case InitMessage::kStopSendingMessages: { + init_socket = -1; + break; + } + default: + LOG(ERROR) << "Unknown message type from init: " << init_message.msg_case(); + } +} + +static void PropertyServiceThread() { + Epoll epoll; + if (auto result = epoll.Open(); !result) { + LOG(FATAL) << result.error(); + } + + if (auto result = epoll.RegisterHandler(property_set_fd, handle_property_set_fd); !result) { + LOG(FATAL) << result.error(); + } + + if (auto result = epoll.RegisterHandler(init_socket, HandleInitSocket); !result) { + LOG(FATAL) << result.error(); + } + + while (true) { + auto pending_functions = epoll.Wait(std::nullopt); + if (!pending_functions) { + LOG(ERROR) << pending_functions.error(); + } else { + for (const auto& function : *pending_functions) { + (*function)(); + } + } + } +} + +void StartPropertyService(int* epoll_socket) { property_set("ro.property_service.version", "2"); + int sockets[2]; + if (socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0, sockets) != 0) { + PLOG(FATAL) << "Failed to socketpair() between property_service and init"; + } + *epoll_socket = sockets[0]; + init_socket = sockets[1]; + if (auto result = CreateSocket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, false, 0666, 0, 0, {})) { property_set_fd = *result; } else { - PLOG(FATAL) << "start_property_service socket creation failed: " << result.error(); + LOG(FATAL) << "start_property_service socket creation failed: " << result.error(); } listen(property_set_fd, 8); - if (auto result = epoll->RegisterHandler(property_set_fd, handle_property_set_fd); !result) { - PLOG(FATAL) << result.error(); - } + std::thread{PropertyServiceThread}.detach(); + + property_set = [](const std::string& key, const std::string& value) -> uint32_t { + android::base::SetProperty(key, value); + return 0; + }; } } // namespace init diff --git a/init/property_service.h b/init/property_service.h index 7f9f84422..8f7d8d96e 100644 --- a/init/property_service.h +++ b/init/property_service.h @@ -25,17 +25,15 @@ namespace android { namespace init { +static constexpr const char kRestoreconProperty[] = "selinux.restorecon_recursive"; + bool CanReadProperty(const std::string& source_context, const std::string& name); extern uint32_t (*property_set)(const std::string& name, const std::string& value); -uint32_t HandlePropertySet(const std::string& name, const std::string& value, - const std::string& source_context, const ucred& cr, std::string* error); - void property_init(); void property_load_boot_defaults(bool load_debug_prop); -void load_persist_props(); -void StartPropertyService(Epoll* epoll); +void StartPropertyService(int* epoll_socket); } // namespace init } // namespace android diff --git a/init/property_service.proto b/init/property_service.proto new file mode 100644 index 000000000..ea454d402 --- /dev/null +++ b/init/property_service.proto @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +syntax = "proto2"; +option optimize_for = LITE_RUNTIME; + +message PropertyMessage { + message ControlMessage { + optional string msg = 1; + optional string name = 2; + optional int32 pid = 3; + optional int32 fd = 4; + } + + message ChangedMessage { + optional string name = 1; + optional string value = 2; + } + + oneof msg { + ControlMessage control_message = 1; + ChangedMessage changed_message = 2; + }; +} + +message InitMessage { + oneof msg { + bool load_persistent_properties = 1; + bool stop_sending_messages = 2; + }; +} diff --git a/init/proto_utils.h b/init/proto_utils.h new file mode 100644 index 000000000..93a7d57a8 --- /dev/null +++ b/init/proto_utils.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +#include + +#include "result.h" + +namespace android { +namespace init { + +constexpr size_t kBufferSize = 4096; + +inline Result ReadMessage(int socket) { + char buffer[kBufferSize] = {}; + auto result = TEMP_FAILURE_RETRY(recv(socket, buffer, sizeof(buffer), 0)); + if (result == 0) { + return Error(); + } else if (result < 0) { + return ErrnoError(); + } + return std::string(buffer, result); +} + +template +Result SendMessage(int socket, const T& message) { + std::string message_string; + if (!message.SerializeToString(&message_string)) { + return Error() << "Unable to serialize message"; + } + + if (message_string.size() > kBufferSize) { + return Error() << "Serialized message too long to send"; + } + + if (auto result = + TEMP_FAILURE_RETRY(send(socket, message_string.c_str(), message_string.size(), 0)); + result != static_cast(message_string.size())) { + return ErrnoError() << "send() failed to send message contents"; + } + return {}; +} + +} // namespace init +} // namespace android diff --git a/init/reboot.cpp b/init/reboot.cpp index b0b5b546d..786a084a7 100644 --- a/init/reboot.cpp +++ b/init/reboot.cpp @@ -730,6 +730,12 @@ bool HandlePowerctlMessage(const std::string& command) { s->UnSetExec(); } + // We no longer process messages about properties changing coming from property service, so we + // need to tell property service to stop sending us these messages, otherwise it'll fill the + // buffers and block indefinitely, causing future property sets, including those that init makes + // during shutdown in Service::NotifyStateChange() to also block indefinitely. + SendStopSendingMessagesMessage(); + return true; } diff --git a/init/subcontext.cpp b/init/subcontext.cpp index 00f91d830..ec93b5837 100644 --- a/init/subcontext.cpp +++ b/init/subcontext.cpp @@ -18,16 +18,17 @@ #include #include -#include #include #include #include +#include #include #include #include "action.h" #include "builtins.h" +#include "proto_utils.h" #include "util.h" #if defined(__ANDROID__) @@ -59,45 +60,6 @@ const char* const paths_and_secontexts[2][2] = { namespace { -constexpr size_t kBufferSize = 4096; - -Result ReadMessage(int socket) { - char buffer[kBufferSize] = {}; - auto result = TEMP_FAILURE_RETRY(recv(socket, buffer, sizeof(buffer), 0)); - if (result == 0) { - return Error(); - } else if (result < 0) { - return ErrnoError(); - } - return std::string(buffer, result); -} - -template -Result SendMessage(int socket, const T& message) { - std::string message_string; - if (!message.SerializeToString(&message_string)) { - return Error() << "Unable to serialize message"; - } - - if (message_string.size() > kBufferSize) { - return Error() << "Serialized message too long to send"; - } - - if (auto result = - TEMP_FAILURE_RETRY(send(socket, message_string.c_str(), message_string.size(), 0)); - result != static_cast(message_string.size())) { - return ErrnoError() << "send() failed to send message contents"; - } - return {}; -} - -std::vector> properties_to_set; - -uint32_t SubcontextPropertySet(const std::string& name, const std::string& value) { - properties_to_set.emplace_back(name, value); - return 0; -} - class SubcontextProcess { public: SubcontextProcess(const BuiltinFunctionMap* function_map, std::string context, int init_fd) @@ -131,14 +93,6 @@ void SubcontextProcess::RunCommand(const SubcontextCommand::ExecuteCommand& exec result = RunBuiltinFunction(map_result->function, args, context_); } - for (const auto& [name, value] : properties_to_set) { - auto property = reply->add_properties_to_set(); - property->set_name(name); - property->set_value(value); - } - - properties_to_set.clear(); - if (result) { reply->set_success(true); } else { @@ -224,7 +178,10 @@ int SubcontextMain(int argc, char** argv, const BuiltinFunctionMap* function_map SelabelInitialize(); - property_set = SubcontextPropertySet; + property_set = [](const std::string& key, const std::string& value) -> uint32_t { + android::base::SetProperty(key, value); + return 0; + }; auto subcontext_process = SubcontextProcess(function_map, context, init_fd); subcontext_process.MainLoop(); @@ -311,15 +268,6 @@ Result Subcontext::Execute(const std::vector& args) { return subcontext_reply.error(); } - for (const auto& property : subcontext_reply->properties_to_set()) { - ucred cr = {.pid = pid_, .uid = 0, .gid = 0}; - std::string error; - if (HandlePropertySet(property.name(), property.value(), context_, cr, &error) != 0) { - LOG(ERROR) << "Subcontext init could not set '" << property.name() << "' to '" - << property.value() << "': " << error; - } - } - if (subcontext_reply->reply_case() == SubcontextReply::kFailure) { auto& failure = subcontext_reply->failure(); return ResultError(failure.error_string(), failure.error_errno()); diff --git a/init/subcontext.proto b/init/subcontext.proto index c31f4fb68..e68115e0e 100644 --- a/init/subcontext.proto +++ b/init/subcontext.proto @@ -38,10 +38,4 @@ message SubcontextReply { Failure failure = 2; ExpandArgsReply expand_args_reply = 3; } - - message PropertyToSet { - optional string name = 1; - optional string value = 2; - } - repeated PropertyToSet properties_to_set = 4; } \ No newline at end of file