From 1420874e97918765e98b6e6826aced24b6cebb2e Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Thu, 25 Aug 2022 16:08:35 +0200 Subject: [PATCH] signal: handle SIGUSR1 with signalfd we use internally SIGUSR1 as a hack to force the check of the container processes. commit d91cc4321797eaa84dcfb7863e91632d2fe26861 changed the way some signals are handled but forgot to handle SIGUSR1, so that receiving SIGUSR1 would crash conmon. Closes: https://bugzilla.redhat.com/show_bug.cgi?id=2119072 Signed-off-by: Giuseppe Scrivano --- src/conmon.c | 4 ++-- src/ctr_exit.c | 5 ++--- src/utils.c | 26 ++++++++++++++------------ src/utils.h | 4 ++-- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/conmon.c b/src/conmon.c index 77250fbc..ade1af79 100644 --- a/src/conmon.c +++ b/src/conmon.c @@ -312,9 +312,9 @@ int main(int argc, char *argv[]) .pid_to_handler = pid_to_handler, .exit_status_cache = NULL, }; - int signal_fd = get_signal_descriptor(SIGCHLD); + int signal_fd = get_signal_descriptor(); if (signal_fd < 0) - pexit("Failed to create signalfd for SIGCHLD"); + pexit("Failed to create signalfd"); int signal_fd_tag = g_unix_fd_add(signal_fd, G_IO_IN, on_signalfd_cb, &data); if (opt_exit_command) diff --git a/src/ctr_exit.c b/src/ctr_exit.c index a2eeed7c..9c9d19b4 100644 --- a/src/ctr_exit.c +++ b/src/ctr_exit.c @@ -81,9 +81,8 @@ gboolean on_signalfd_cb(gint fd, G_GNUC_UNUSED GIOCondition condition, gpointer { struct pid_check_data *data = (struct pid_check_data *)user_data; - /* dequeue the signal from the signalfd */ - int sig = dequeue_signal_event(fd); - g_assert_cmpint(sig, ==, SIGCHLD); + /* drop the signal from the signalfd */ + drop_signal_event(fd); check_child_processes(data->pid_to_handler, data->exit_status_cache); return G_SOURCE_CONTINUE; diff --git a/src/utils.c b/src/utils.c index a417035e..e7adc1ba 100644 --- a/src/utils.c +++ b/src/utils.c @@ -61,6 +61,14 @@ static bool retryable_error(int err) } #endif +static void get_signal_descriptor_mask(sigset_t *set) +{ + sigemptyset(set); + sigaddset(set, SIGCHLD); + sigaddset(set, SIGUSR1); + sigprocmask(SIG_BLOCK, set, NULL); +} + ssize_t write_all(int fd, const void *buf, size_t count) { size_t remaining = count; @@ -94,21 +102,18 @@ int set_pdeathsig(int sig) return prctl(PR_SET_PDEATHSIG, sig); } -int get_signal_descriptor(int sig) +int get_signal_descriptor() { sigset_t set; - sigemptyset(&set); - sigaddset(&set, sig); - sigprocmask(SIG_BLOCK, &set, NULL); + get_signal_descriptor_mask(&set); return signalfd(-1, &set, SFD_CLOEXEC); } -int dequeue_signal_event(int fd) +void drop_signal_event(int fd) { struct signalfd_siginfo siginfo; ssize_t s = read(fd, &siginfo, sizeof siginfo); g_assert_cmpint(s, ==, sizeof siginfo); - return siginfo.ssi_signo; } #endif @@ -129,12 +134,10 @@ int set_pdeathsig(int sig) return procctl(P_PID, getpid(), PROC_PDEATHSIG_CTL, &sig); } -int get_signal_descriptor(int sig) +int get_signal_descriptor() { sigset_t set; - sigemptyset(&set); - sigaddset(&set, sig); - sigprocmask(SIG_BLOCK, &set, NULL); + get_signal_descriptor_mask(&set); int kq = kqueue(); fcntl(kq, F_SETFD, FD_CLOEXEC); @@ -146,14 +149,13 @@ int get_signal_descriptor(int sig) return kq; } -int dequeue_signal_event(int kq) +void drop_signal_event(int kq) { struct kevent kev; int n = kevent(kq, NULL, 0, &kev, 1, NULL); if (n != 1) { pexit("failed to read signal event"); } - return kev.ident; } #endif diff --git a/src/utils.h b/src/utils.h index f3cf8534..ee4ec5b2 100644 --- a/src/utils.h +++ b/src/utils.h @@ -229,7 +229,7 @@ int set_subreaper(gboolean enabled); int set_pdeathsig(int sig); -int get_signal_descriptor(int sig); -int dequeue_signal_event(int fd); +int get_signal_descriptor(); +void drop_signal_event(int fd); #endif /* !defined(UTILS_H) */