Loading init/property_service.cpp +81 −7 Original line number Original line Diff line number Diff line Loading @@ -39,6 +39,7 @@ #include <sys/_system_properties.h> #include <sys/_system_properties.h> #include <memory> #include <memory> #include <queue> #include <vector> #include <vector> #include <android-base/file.h> #include <android-base/file.h> Loading Loading @@ -162,7 +163,7 @@ bool is_legal_property_name(const std::string& name) { return true; return true; } } uint32_t property_set(const std::string& name, const std::string& value) { static uint32_t PropertySetImpl(const std::string& name, const std::string& value) { size_t valuelen = value.size(); size_t valuelen = value.size(); if (!is_legal_property_name(name)) { if (!is_legal_property_name(name)) { Loading @@ -176,12 +177,6 @@ uint32_t property_set(const std::string& name, const std::string& value) { return PROP_ERROR_INVALID_VALUE; return PROP_ERROR_INVALID_VALUE; } } if (name == "selinux.restorecon_recursive" && valuelen > 0) { if (selinux_android_restorecon(value.c_str(), SELINUX_ANDROID_RESTORECON_RECURSE) != 0) { LOG(ERROR) << "Failed to restorecon_recursive " << value; } } prop_info* pi = (prop_info*) __system_property_find(name.c_str()); prop_info* pi = (prop_info*) __system_property_find(name.c_str()); if (pi != nullptr) { if (pi != nullptr) { // ro.* properties are actually "write-once". // ro.* properties are actually "write-once". Loading Loading @@ -210,6 +205,85 @@ uint32_t property_set(const std::string& name, const std::string& value) { return PROP_SUCCESS; return PROP_SUCCESS; } } typedef int (*PropertyAsyncFunc)(const std::string&, const std::string&); struct PropertyChildInfo { pid_t pid; PropertyAsyncFunc func; std::string name; std::string value; }; static std::queue<PropertyChildInfo> property_children; static void PropertyChildLaunch() { auto& info = property_children.front(); pid_t pid = fork(); if (pid < 0) { LOG(ERROR) << "Failed to fork for property_set_async"; while (!property_children.empty()) { property_children.pop(); } return; } if (pid != 0) { info.pid = pid; } else { if (info.func(info.name, info.value) != 0) { LOG(ERROR) << "property_set_async(\"" << info.name << "\", \"" << info.value << "\") failed"; } exit(0); } } bool PropertyChildReap(pid_t pid) { if (property_children.empty()) { return false; } auto& info = property_children.front(); if (info.pid != pid) { return false; } if (PropertySetImpl(info.name, info.value) != PROP_SUCCESS) { LOG(ERROR) << "Failed to set async property " << info.name; } property_children.pop(); if (!property_children.empty()) { PropertyChildLaunch(); } return true; } static uint32_t PropertySetAsync(const std::string& name, const std::string& value, PropertyAsyncFunc func) { if (value.empty()) { return PropertySetImpl(name, value); } PropertyChildInfo info; info.func = func; info.name = name; info.value = value; property_children.push(info); if (property_children.size() == 1) { PropertyChildLaunch(); } return PROP_SUCCESS; } static int RestoreconRecursiveAsync(const std::string& name, const std::string& value) { return selinux_android_restorecon(value.c_str(), SELINUX_ANDROID_RESTORECON_RECURSE); } uint32_t property_set(const std::string& name, const std::string& value) { if (name == "selinux.restorecon_recursive") { return PropertySetAsync(name, value, RestoreconRecursiveAsync); } return PropertySetImpl(name, value); } class SocketConnection { class SocketConnection { public: public: SocketConnection(int socket, const struct ucred& cred) SocketConnection(int socket, const struct ucred& cred) Loading init/property_service.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,8 @@ struct property_audit_data { const char* name; const char* name; }; }; extern bool PropertyChildReap(pid_t pid); void property_init(void); void property_init(void); void property_load_boot_defaults(void); void property_load_boot_defaults(void); void load_persist_props(void); void load_persist_props(void); Loading init/service.cpp +2 −0 Original line number Original line Diff line number Diff line Loading @@ -1085,6 +1085,8 @@ bool ServiceManager::ReapOneProcess() { } else if (pid == -1) { } else if (pid == -1) { PLOG(ERROR) << "waitpid failed"; PLOG(ERROR) << "waitpid failed"; return false; return false; } else if (PropertyChildReap(pid)) { return true; } } Service* svc = FindServiceByPid(pid); Service* svc = FindServiceByPid(pid); Loading Loading
init/property_service.cpp +81 −7 Original line number Original line Diff line number Diff line Loading @@ -39,6 +39,7 @@ #include <sys/_system_properties.h> #include <sys/_system_properties.h> #include <memory> #include <memory> #include <queue> #include <vector> #include <vector> #include <android-base/file.h> #include <android-base/file.h> Loading Loading @@ -162,7 +163,7 @@ bool is_legal_property_name(const std::string& name) { return true; return true; } } uint32_t property_set(const std::string& name, const std::string& value) { static uint32_t PropertySetImpl(const std::string& name, const std::string& value) { size_t valuelen = value.size(); size_t valuelen = value.size(); if (!is_legal_property_name(name)) { if (!is_legal_property_name(name)) { Loading @@ -176,12 +177,6 @@ uint32_t property_set(const std::string& name, const std::string& value) { return PROP_ERROR_INVALID_VALUE; return PROP_ERROR_INVALID_VALUE; } } if (name == "selinux.restorecon_recursive" && valuelen > 0) { if (selinux_android_restorecon(value.c_str(), SELINUX_ANDROID_RESTORECON_RECURSE) != 0) { LOG(ERROR) << "Failed to restorecon_recursive " << value; } } prop_info* pi = (prop_info*) __system_property_find(name.c_str()); prop_info* pi = (prop_info*) __system_property_find(name.c_str()); if (pi != nullptr) { if (pi != nullptr) { // ro.* properties are actually "write-once". // ro.* properties are actually "write-once". Loading Loading @@ -210,6 +205,85 @@ uint32_t property_set(const std::string& name, const std::string& value) { return PROP_SUCCESS; return PROP_SUCCESS; } } typedef int (*PropertyAsyncFunc)(const std::string&, const std::string&); struct PropertyChildInfo { pid_t pid; PropertyAsyncFunc func; std::string name; std::string value; }; static std::queue<PropertyChildInfo> property_children; static void PropertyChildLaunch() { auto& info = property_children.front(); pid_t pid = fork(); if (pid < 0) { LOG(ERROR) << "Failed to fork for property_set_async"; while (!property_children.empty()) { property_children.pop(); } return; } if (pid != 0) { info.pid = pid; } else { if (info.func(info.name, info.value) != 0) { LOG(ERROR) << "property_set_async(\"" << info.name << "\", \"" << info.value << "\") failed"; } exit(0); } } bool PropertyChildReap(pid_t pid) { if (property_children.empty()) { return false; } auto& info = property_children.front(); if (info.pid != pid) { return false; } if (PropertySetImpl(info.name, info.value) != PROP_SUCCESS) { LOG(ERROR) << "Failed to set async property " << info.name; } property_children.pop(); if (!property_children.empty()) { PropertyChildLaunch(); } return true; } static uint32_t PropertySetAsync(const std::string& name, const std::string& value, PropertyAsyncFunc func) { if (value.empty()) { return PropertySetImpl(name, value); } PropertyChildInfo info; info.func = func; info.name = name; info.value = value; property_children.push(info); if (property_children.size() == 1) { PropertyChildLaunch(); } return PROP_SUCCESS; } static int RestoreconRecursiveAsync(const std::string& name, const std::string& value) { return selinux_android_restorecon(value.c_str(), SELINUX_ANDROID_RESTORECON_RECURSE); } uint32_t property_set(const std::string& name, const std::string& value) { if (name == "selinux.restorecon_recursive") { return PropertySetAsync(name, value, RestoreconRecursiveAsync); } return PropertySetImpl(name, value); } class SocketConnection { class SocketConnection { public: public: SocketConnection(int socket, const struct ucred& cred) SocketConnection(int socket, const struct ucred& cred) Loading
init/property_service.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,8 @@ struct property_audit_data { const char* name; const char* name; }; }; extern bool PropertyChildReap(pid_t pid); void property_init(void); void property_init(void); void property_load_boot_defaults(void); void property_load_boot_defaults(void); void load_persist_props(void); void load_persist_props(void); Loading
init/service.cpp +2 −0 Original line number Original line Diff line number Diff line Loading @@ -1085,6 +1085,8 @@ bool ServiceManager::ReapOneProcess() { } else if (pid == -1) { } else if (pid == -1) { PLOG(ERROR) << "waitpid failed"; PLOG(ERROR) << "waitpid failed"; return false; return false; } else if (PropertyChildReap(pid)) { return true; } } Service* svc = FindServiceByPid(pid); Service* svc = FindServiceByPid(pid); Loading