From fd470e87cc5920cde00c83e653a52c83cecbb04d Mon Sep 17 00:00:00 2001 From: Tom Cherry Date: Mon, 16 Mar 2020 10:17:05 -0700 Subject: [PATCH] init: use a no-op signal handler instead of SIG_IGN for SIGPIPE We want to ignore SIGPIPE within init, but if we use SIG_IGN, that would be inherited by child processes through exec(), which we do not want to have happen. We instead set up a real signal handler with a no-op handler function, that will ignore SIGPIPE within init, but will not be inherited across exec(). This fixes c29c2baa6907 ("init: Add support for native service registration with lmkd"), when SIG_IGN was introduced. Note that we caught this issue before shipping a release with that change, so the major motivation here is to not cause a behavior change in init. Bug: 151581751 Test: children of init that don't explicitly block SIGPIPE exit when sent SIGPIPE Test: children of init that do explicitly block SIGPIPE do not exit when sent SIGPIPE Test: init does not exit when sent SIGPIPE Test: init exits when sent SIGABRT Change-Id: Ieda8555fd03836bcd672a422fe673a8369ad9beb --- init/init.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/init/init.cpp b/init/init.cpp index b29dfa3f6..4289dcf72 100644 --- a/init/init.cpp +++ b/init/init.cpp @@ -713,8 +713,15 @@ int SecondStageMain(int argc, char** argv) { InitKernelLogging(argv); LOG(INFO) << "init second stage started!"; - // Will handle EPIPE at the time of write by checking the errno - signal(SIGPIPE, SIG_IGN); + // Init should not crash because of a dependence on any other process, therefore we ignore + // SIGPIPE and handle EPIPE at the call site directly. Note that setting a signal to SIG_IGN + // is inherited across exec, but custom signal handlers are not. Since we do not want to + // ignore SIGPIPE for child processes, we set a no-op function for the signal handler instead. + { + struct sigaction action = {.sa_flags = SA_RESTART}; + action.sa_handler = [](int) {}; + sigaction(SIGPIPE, &action, nullptr); + } // Set init and its forked children's oom_adj. if (auto result =