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 <surenb@google.com>
Change-Id: I83261bef803751759c7fd709bf1ccd33ccad3a0b
This commit is contained in:
Suren Baghdasaryan 2022-03-31 21:18:20 -07:00
parent 6948bbf62c
commit 1bd1746447
1 changed files with 15 additions and 5 deletions

View File

@ -491,10 +491,15 @@ void Service::RunService(const std::optional<MountNamespace>& 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<void> 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<void> 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";
}