diff --git a/init/ueventd.cpp b/init/ueventd.cpp index 8b2cf6225..cffc1b91c 100644 --- a/init/ueventd.cpp +++ b/init/ueventd.cpp @@ -17,12 +17,15 @@ #include "ueventd.h" #include +#include #include #include #include #include #include +#include #include +#include #include #include @@ -121,8 +124,9 @@ class ColdBoot { void UeventHandlerMain(unsigned int process_num, unsigned int total_processes); void RegenerateUevents(); void ForkSubProcesses(); - void DoRestoreCon(); void WaitForSubProcesses(); + void RestoreConHandler(unsigned int process_num, unsigned int total_processes); + void GenerateRestoreCon(const std::string& directory); UeventListener& uevent_listener_; std::vector>& uevent_handlers_; @@ -131,6 +135,8 @@ class ColdBoot { std::vector uevent_queue_; std::set subprocess_pids_; + + std::vector restorecon_queue_; }; void ColdBoot::UeventHandlerMain(unsigned int process_num, unsigned int total_processes) { @@ -141,9 +147,38 @@ void ColdBoot::UeventHandlerMain(unsigned int process_num, unsigned int total_pr uevent_handler->HandleUevent(uevent); } } +} + +void ColdBoot::RestoreConHandler(unsigned int process_num, unsigned int total_processes) { + for (unsigned int i = process_num; i < restorecon_queue_.size(); i += total_processes) { + auto& dir = restorecon_queue_[i]; + + selinux_android_restorecon(dir.c_str(), SELINUX_ANDROID_RESTORECON_RECURSE); + } _exit(EXIT_SUCCESS); } +void ColdBoot::GenerateRestoreCon(const std::string& directory) { + std::unique_ptr dir(opendir(directory.c_str()), &closedir); + + if (!dir) return; + + struct dirent* dent; + while ((dent = readdir(dir.get())) != NULL) { + if (strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0) continue; + + struct stat st; + if (fstatat(dirfd(dir.get()), dent->d_name, &st, 0) == -1) continue; + + if (S_ISDIR(st.st_mode)) { + std::string fullpath = directory + "/" + dent->d_name; + if (fullpath != "/sys/devices") { + restorecon_queue_.emplace_back(fullpath); + } + } + } +} + void ColdBoot::RegenerateUevents() { uevent_listener_.RegenerateUevents([this](const Uevent& uevent) { uevent_queue_.emplace_back(uevent); @@ -160,16 +195,13 @@ void ColdBoot::ForkSubProcesses() { if (pid == 0) { UeventHandlerMain(i, num_handler_subprocesses_); + RestoreConHandler(i, num_handler_subprocesses_); } subprocess_pids_.emplace(pid); } } -void ColdBoot::DoRestoreCon() { - selinux_android_restorecon("/sys", SELINUX_ANDROID_RESTORECON_RECURSE); -} - void ColdBoot::WaitForSubProcesses() { // Treat subprocesses that crash or get stuck the same as if ueventd itself has crashed or gets // stuck. @@ -208,9 +240,13 @@ void ColdBoot::Run() { RegenerateUevents(); - ForkSubProcesses(); + selinux_android_restorecon("/sys", 0); + selinux_android_restorecon("/sys/devices", 0); + GenerateRestoreCon("/sys"); + // takes long time for /sys/devices, parallelize it + GenerateRestoreCon("/sys/devices"); - DoRestoreCon(); + ForkSubProcesses(); WaitForSubProcesses();