From 1bd17464473a2ea7dd1e1c5abef50fa3f30a56b5 Mon Sep 17 00:00:00 2001 From: Suren Baghdasaryan Date: Thu, 31 Mar 2022 21:18:20 -0700 Subject: [PATCH] init: Treat failure to create a process group as fatal During process startup, system creates a process group and places the new process in it. If process group creation fails for some reason, the new child process will stay in its parent's group. This poses danger when the child is being frozen because the whole group is affected and its parent is being frozen as well. Fix this by treating group creation failure as a fatal error which would prevent the app from starting. Bug: 227395690 Test: fake group creation failure and confirm service failure to start Signed-off-by: Suren Baghdasaryan Change-Id: I83261bef803751759c7fd709bf1ccd33ccad3a0b --- init/service.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/init/service.cpp b/init/service.cpp index 2ebf87eb1..077477a15 100644 --- a/init/service.cpp +++ b/init/service.cpp @@ -491,10 +491,15 @@ void Service::RunService(const std::optional& override_mount_nam // Wait until the cgroups have been created and until the cgroup controllers have been // activated. - if (std::byte byte; read((*pipefd)[0], &byte, 1) < 0) { + char byte = 0; + if (read((*pipefd)[0], &byte, 1) < 0) { PLOG(ERROR) << "failed to read from notification channel"; } pipefd.reset(); + if (!byte) { + LOG(FATAL) << "Service '" << name_ << "' failed to start due to a fatal error"; + _exit(EXIT_FAILURE); + } if (task_profiles_.size() > 0 && !SetTaskProfiles(getpid(), task_profiles_)) { LOG(ERROR) << "failed to set task profiles"; @@ -647,9 +652,14 @@ Result Service::Start() { limit_percent_ != -1 || !limit_property_.empty(); errno = -createProcessGroup(proc_attr_.uid, pid_, use_memcg); if (errno != 0) { - PLOG(ERROR) << "createProcessGroup(" << proc_attr_.uid << ", " << pid_ - << ") failed for service '" << name_ << "'"; - } else if (use_memcg) { + if (char byte = 0; write((*pipefd)[1], &byte, 1) < 0) { + return ErrnoError() << "sending notification failed"; + } + return Error() << "createProcessGroup(" << proc_attr_.uid << ", " << pid_ + << ") failed for service '" << name_ << "'"; + } + + if (use_memcg) { ConfigureMemcg(); } @@ -657,7 +667,7 @@ Result Service::Start() { LmkdRegister(name_, proc_attr_.uid, pid_, oom_score_adjust_); } - if (write((*pipefd)[1], "", 1) < 0) { + if (char byte = 1; write((*pipefd)[1], &byte, 1) < 0) { return ErrnoError() << "sending notification failed"; }