Loading fs_mgr/libsnapshot/snapshot_test.cpp +12 −0 Original line number Diff line number Diff line Loading @@ -3072,6 +3072,18 @@ int main(int argc, char** argv) { ::testing::AddGlobalTestEnvironment(new ::android::snapshot::SnapshotTestEnvironment()); gflags::ParseCommandLineFlags(&argc, &argv, false); // During incremental flashing, snapshot updates are in progress. // // When snapshot update is in-progress, snapuserd daemon // will be up and running. These tests will start and stop the daemon // thereby interfering with the update and snapshot-merge progress. // Hence, wait until the update is complete. auto sm = android::snapshot::SnapshotManager::New(); while (sm->IsUserspaceSnapshotUpdateInProgress()) { LOG(INFO) << "Snapshot update is in progress. Waiting..."; std::this_thread::sleep_for(std::chrono::milliseconds(1000)); } bool vab_legacy = false; if (FLAGS_force_mode == "vab-legacy") { vab_legacy = true; Loading init/README.md +11 −0 Original line number Diff line number Diff line Loading @@ -369,6 +369,17 @@ runs the service. `setenv <name> <value>` > Set the environment variable _name_ to _value_ in the launched process. `shared_kallsyms` > If set, init will behave as if the service specified "file /proc/kallsyms r", except the service will receive a duplicate of a single fd that init saved during early second\_stage. This fd retains address visibility even after the systemwide kptr\_restrict sysctl is set to its steady state on Android. The ability to read from this fd is still constrained by selinux permissions, which need to be granted separately and are gated by a neverallow. Because of performance gotchas of concurrent use of this shared fd, all uses need to coordinate via provisional flock(LOCK\_EX) locks on separately opened /proc/kallsyms fds (since locking requires distinct open file descriptions). `shutdown <shutdown_behavior>` > Set shutdown behavior of the service process. When this is not specified, the service is killed during shutdown process by using SIGTERM and SIGKILL. Loading init/init.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -1055,6 +1055,14 @@ int SecondStageMain(int argc, char** argv) { } } // This needs to happen before SetKptrRestrictAction, as we are trying to // open /proc/kallsyms while still being allowed to see the full addresses // (since init holds CAP_SYSLOG, and Linux boots with kptr_restrict=0). The // address visibility through the saved fd (more specifically, the backing // open file description) will then be remembered by the kernel for the rest // of its lifetime, even after we raise the kptr_restrict. Service::OpenAndSaveStaticKallsymsFd(); am.QueueBuiltinAction(SetupCgroupsAction, "SetupCgroups"); am.QueueBuiltinAction(SetKptrRestrictAction, "SetKptrRestrict"); am.QueueBuiltinAction(TestPerfEventSelinuxAction, "TestPerfEventSelinux"); Loading init/service.cpp +38 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ #include <android-base/scopeguard.h> #include <android-base/stringprintf.h> #include <android-base/strings.h> #include <cutils/android_get_control_file.h> #include <cutils/sockets.h> #include <processgroup/processgroup.h> #include <selinux/selinux.h> Loading Loading @@ -672,6 +673,14 @@ Result<void> Service::Start() { } } if (shared_kallsyms_file_) { if (auto result = CreateSharedKallsymsFd(); result.ok()) { descriptors.emplace_back(std::move(*result)); } else { LOG(INFO) << "Could not obtain a copy of /proc/kallsyms: " << result.error(); } } pid_t pid = -1; if (namespaces_.flags) { pid = clone(nullptr, nullptr, namespaces_.flags | SIGCHLD, nullptr); Loading Loading @@ -835,6 +844,35 @@ unique_fd Service::CreateSigchldFd() { return unique_fd(signalfd(-1, &mask, SFD_CLOEXEC)); } void Service::OpenAndSaveStaticKallsymsFd() { Result<Descriptor> result = CreateSharedKallsymsFd(); if (!result.ok()) { LOG(ERROR) << result.error(); } } // This function is designed to be called in two situations: // 1) early during second_stage init, to open and save the shared fd as a // static (see OpenAndSaveStaticKallsymsFd). // 2) whenever a service requesting a copy of the fd is being started, at which // point it will get a duplicated copy of the static fd. Result<Descriptor> Service::CreateSharedKallsymsFd() { static constexpr char kallsyms_path[] = "/proc/kallsyms"; static int static_fd = open(kallsyms_path, O_RDONLY | O_NONBLOCK | O_CLOEXEC); if (static_fd < 0) { return ErrnoError() << "failed to open " << kallsyms_path; } unique_fd fd{fcntl(static_fd, F_DUPFD_CLOEXEC, /*min_fd=*/3)}; if (fd < 0) { return ErrnoError() << "failed fcntl(F_DUPFD_CLOEXEC)"; } // Use the same environment variable as if the service specified // "file /proc/kallsyms r". return Descriptor(std::string(ANDROID_FILE_ENV_PREFIX) + kallsyms_path, std::move(fd)); } void Service::SetStartedInFirstStage(pid_t pid) { LOG(INFO) << "adding first-stage service '" << name_ << "'..."; Loading init/service.h +3 −0 Original line number Diff line number Diff line Loading @@ -158,6 +158,7 @@ class Service { static int sigchld_fd = CreateSigchldFd().release(); return sigchld_fd; } static void OpenAndSaveStaticKallsymsFd(); private: void NotifyStateChange(const std::string& new_state) const; Loading @@ -171,6 +172,7 @@ class Service { InterprocessFifo setsid_finished); void SetMountNamespace(); static ::android::base::unique_fd CreateSigchldFd(); static Result<Descriptor> CreateSharedKallsymsFd(); static unsigned long next_start_order_; static bool is_exec_service_running_; Loading @@ -188,6 +190,7 @@ class Service { std::optional<std::string> fatal_reboot_target_; // reboot target of fatal handler bool was_last_exit_ok_ = true; // true if the service never exited, or exited with status code 0 bool shared_kallsyms_file_ = false; // pass the service a pre-opened fd to /proc/kallsyms std::optional<CapSet> capabilities_; ProcessAttributes proc_attr_; Loading Loading
fs_mgr/libsnapshot/snapshot_test.cpp +12 −0 Original line number Diff line number Diff line Loading @@ -3072,6 +3072,18 @@ int main(int argc, char** argv) { ::testing::AddGlobalTestEnvironment(new ::android::snapshot::SnapshotTestEnvironment()); gflags::ParseCommandLineFlags(&argc, &argv, false); // During incremental flashing, snapshot updates are in progress. // // When snapshot update is in-progress, snapuserd daemon // will be up and running. These tests will start and stop the daemon // thereby interfering with the update and snapshot-merge progress. // Hence, wait until the update is complete. auto sm = android::snapshot::SnapshotManager::New(); while (sm->IsUserspaceSnapshotUpdateInProgress()) { LOG(INFO) << "Snapshot update is in progress. Waiting..."; std::this_thread::sleep_for(std::chrono::milliseconds(1000)); } bool vab_legacy = false; if (FLAGS_force_mode == "vab-legacy") { vab_legacy = true; Loading
init/README.md +11 −0 Original line number Diff line number Diff line Loading @@ -369,6 +369,17 @@ runs the service. `setenv <name> <value>` > Set the environment variable _name_ to _value_ in the launched process. `shared_kallsyms` > If set, init will behave as if the service specified "file /proc/kallsyms r", except the service will receive a duplicate of a single fd that init saved during early second\_stage. This fd retains address visibility even after the systemwide kptr\_restrict sysctl is set to its steady state on Android. The ability to read from this fd is still constrained by selinux permissions, which need to be granted separately and are gated by a neverallow. Because of performance gotchas of concurrent use of this shared fd, all uses need to coordinate via provisional flock(LOCK\_EX) locks on separately opened /proc/kallsyms fds (since locking requires distinct open file descriptions). `shutdown <shutdown_behavior>` > Set shutdown behavior of the service process. When this is not specified, the service is killed during shutdown process by using SIGTERM and SIGKILL. Loading
init/init.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -1055,6 +1055,14 @@ int SecondStageMain(int argc, char** argv) { } } // This needs to happen before SetKptrRestrictAction, as we are trying to // open /proc/kallsyms while still being allowed to see the full addresses // (since init holds CAP_SYSLOG, and Linux boots with kptr_restrict=0). The // address visibility through the saved fd (more specifically, the backing // open file description) will then be remembered by the kernel for the rest // of its lifetime, even after we raise the kptr_restrict. Service::OpenAndSaveStaticKallsymsFd(); am.QueueBuiltinAction(SetupCgroupsAction, "SetupCgroups"); am.QueueBuiltinAction(SetKptrRestrictAction, "SetKptrRestrict"); am.QueueBuiltinAction(TestPerfEventSelinuxAction, "TestPerfEventSelinux"); Loading
init/service.cpp +38 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ #include <android-base/scopeguard.h> #include <android-base/stringprintf.h> #include <android-base/strings.h> #include <cutils/android_get_control_file.h> #include <cutils/sockets.h> #include <processgroup/processgroup.h> #include <selinux/selinux.h> Loading Loading @@ -672,6 +673,14 @@ Result<void> Service::Start() { } } if (shared_kallsyms_file_) { if (auto result = CreateSharedKallsymsFd(); result.ok()) { descriptors.emplace_back(std::move(*result)); } else { LOG(INFO) << "Could not obtain a copy of /proc/kallsyms: " << result.error(); } } pid_t pid = -1; if (namespaces_.flags) { pid = clone(nullptr, nullptr, namespaces_.flags | SIGCHLD, nullptr); Loading Loading @@ -835,6 +844,35 @@ unique_fd Service::CreateSigchldFd() { return unique_fd(signalfd(-1, &mask, SFD_CLOEXEC)); } void Service::OpenAndSaveStaticKallsymsFd() { Result<Descriptor> result = CreateSharedKallsymsFd(); if (!result.ok()) { LOG(ERROR) << result.error(); } } // This function is designed to be called in two situations: // 1) early during second_stage init, to open and save the shared fd as a // static (see OpenAndSaveStaticKallsymsFd). // 2) whenever a service requesting a copy of the fd is being started, at which // point it will get a duplicated copy of the static fd. Result<Descriptor> Service::CreateSharedKallsymsFd() { static constexpr char kallsyms_path[] = "/proc/kallsyms"; static int static_fd = open(kallsyms_path, O_RDONLY | O_NONBLOCK | O_CLOEXEC); if (static_fd < 0) { return ErrnoError() << "failed to open " << kallsyms_path; } unique_fd fd{fcntl(static_fd, F_DUPFD_CLOEXEC, /*min_fd=*/3)}; if (fd < 0) { return ErrnoError() << "failed fcntl(F_DUPFD_CLOEXEC)"; } // Use the same environment variable as if the service specified // "file /proc/kallsyms r". return Descriptor(std::string(ANDROID_FILE_ENV_PREFIX) + kallsyms_path, std::move(fd)); } void Service::SetStartedInFirstStage(pid_t pid) { LOG(INFO) << "adding first-stage service '" << name_ << "'..."; Loading
init/service.h +3 −0 Original line number Diff line number Diff line Loading @@ -158,6 +158,7 @@ class Service { static int sigchld_fd = CreateSigchldFd().release(); return sigchld_fd; } static void OpenAndSaveStaticKallsymsFd(); private: void NotifyStateChange(const std::string& new_state) const; Loading @@ -171,6 +172,7 @@ class Service { InterprocessFifo setsid_finished); void SetMountNamespace(); static ::android::base::unique_fd CreateSigchldFd(); static Result<Descriptor> CreateSharedKallsymsFd(); static unsigned long next_start_order_; static bool is_exec_service_running_; Loading @@ -188,6 +190,7 @@ class Service { std::optional<std::string> fatal_reboot_target_; // reboot target of fatal handler bool was_last_exit_ok_ = true; // true if the service never exited, or exited with status code 0 bool shared_kallsyms_file_ = false; // pass the service a pre-opened fd to /proc/kallsyms std::optional<CapSet> capabilities_; ProcessAttributes proc_attr_; Loading