From b467714b33c6c132b38cbeb37c4f0d0b90d9f8f7 Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Thu, 24 May 2018 20:29:48 +0200 Subject: [PATCH 1/2] tree-wide: s/sigprocmask/pthread_sigmask()/g The behavior of sigprocmask() is unspecified in multi-threaded programs. Let's use pthread_sigmask() instead. Signed-off-by: Christian Brauner --- src/lxc/cmd/lxc_init.c | 7 ++++--- src/lxc/cmd/lxc_monitord.c | 3 ++- src/lxc/start.c | 9 +++++---- src/lxc/terminal.c | 7 ++++--- src/lxc/utils.c | 3 ++- 5 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/lxc/cmd/lxc_init.c b/src/lxc/cmd/lxc_init.c index c673bc60a..2f0303451 100644 --- a/src/lxc/cmd/lxc_init.c +++ b/src/lxc/cmd/lxc_init.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -266,7 +267,7 @@ int main(int argc, char *argv[]) if (ret < 0) exit(EXIT_FAILURE); - ret = sigprocmask(SIG_SETMASK, &mask, &omask); + ret = pthread_sigmask(SIG_SETMASK, &mask, &omask); if (ret < 0) exit(EXIT_FAILURE); @@ -340,7 +341,7 @@ int main(int argc, char *argv[]) } } - ret = sigprocmask(SIG_SETMASK, &omask, NULL); + ret = pthread_sigmask(SIG_SETMASK, &omask, NULL); if (ret < 0) { SYSERROR("Failed to set signal mask"); exit(EXIT_FAILURE); @@ -368,7 +369,7 @@ int main(int argc, char *argv[]) if (ret < 0) exit(EXIT_FAILURE); - ret = sigprocmask(SIG_SETMASK, &omask, NULL); + ret = pthread_sigmask(SIG_SETMASK, &omask, NULL); if (ret < 0) { SYSERROR("Failed to set signal mask"); exit(EXIT_FAILURE); diff --git a/src/lxc/cmd/lxc_monitord.c b/src/lxc/cmd/lxc_monitord.c index 99f2bdb8b..3b17b67d4 100644 --- a/src/lxc/cmd/lxc_monitord.c +++ b/src/lxc/cmd/lxc_monitord.c @@ -24,6 +24,7 @@ #define _GNU_SOURCE #include #include +#include #include #include #include @@ -386,7 +387,7 @@ int main(int argc, char *argv[]) sigdelset(&mask, SIGSEGV) || sigdelset(&mask, SIGBUS) || sigdelset(&mask, SIGTERM) || - sigprocmask(SIG_BLOCK, &mask, NULL)) { + pthread_sigmask(SIG_BLOCK, &mask, NULL)) { SYSERROR("Failed to set signal mask."); exit(EXIT_FAILURE); } diff --git a/src/lxc/start.c b/src/lxc/start.c index f4f8e520c..ba737d239 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -314,7 +315,7 @@ static int setup_signal_fd(sigset_t *oldmask) return -EBADF; } - ret = sigprocmask(SIG_BLOCK, &mask, oldmask); + ret = pthread_sigmask(SIG_BLOCK, &mask, oldmask); if (ret < 0) { SYSERROR("Failed to set signal mask"); return -EBADF; @@ -860,7 +861,7 @@ int lxc_init(const char *name, struct lxc_handler *handler) return 0; out_restore_sigmask: - sigprocmask(SIG_SETMASK, &handler->oldmask, NULL); + pthread_sigmask(SIG_SETMASK, &handler->oldmask, NULL); out_delete_tty: lxc_delete_tty(&conf->ttys); out_aborting: @@ -986,7 +987,7 @@ void lxc_fini(const char *name, struct lxc_handler *handler) } /* Reset mask set by setup_signal_fd. */ - ret = sigprocmask(SIG_SETMASK, &handler->oldmask, NULL); + ret = pthread_sigmask(SIG_SETMASK, &handler->oldmask, NULL); if (ret < 0) WARN("%s - Failed to restore signal mask", strerror(errno)); @@ -1064,7 +1065,7 @@ static int do_start(void *data) goto out_warn_father; } - ret = sigprocmask(SIG_SETMASK, &handler->oldmask, NULL); + ret = pthread_sigmask(SIG_SETMASK, &handler->oldmask, NULL); if (ret < 0) { SYSERROR("Failed to set signal mask"); goto out_warn_father; diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c index 7d69a67e2..234ad672e 100644 --- a/src/lxc/terminal.c +++ b/src/lxc/terminal.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -172,7 +173,7 @@ struct lxc_terminal_state *lxc_terminal_signal_init(int srcfd, int dstfd) goto on_error; } - ret = sigprocmask(SIG_BLOCK, &mask, &ts->oldmask); + ret = pthread_sigmask(SIG_BLOCK, &mask, &ts->oldmask); if (ret < 0) { WARN("Failed to block signals"); goto on_error; @@ -181,7 +182,7 @@ struct lxc_terminal_state *lxc_terminal_signal_init(int srcfd, int dstfd) ts->sigfd = signalfd(-1, &mask, SFD_CLOEXEC); if (ts->sigfd < 0) { WARN("Failed to create signal fd"); - sigprocmask(SIG_SETMASK, &ts->oldmask, NULL); + (void)pthread_sigmask(SIG_SETMASK, &ts->oldmask, NULL); goto on_error; } @@ -206,7 +207,7 @@ void lxc_terminal_signal_fini(struct lxc_terminal_state *ts) if (ts->sigfd >= 0) { close(ts->sigfd); - if (sigprocmask(SIG_SETMASK, &ts->oldmask, NULL) < 0) + if (pthread_sigmask(SIG_SETMASK, &ts->oldmask, NULL) < 0) WARN("%s - Failed to restore signal mask", strerror(errno)); } diff --git a/src/lxc/utils.c b/src/lxc/utils.c index 2669a4d4b..82403dfc6 100644 --- a/src/lxc/utils.c +++ b/src/lxc/utils.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -495,7 +496,7 @@ struct lxc_popen_FILE *lxc_popen(const char *command) if (ret < 0) _exit(EXIT_FAILURE); - ret = sigprocmask(SIG_UNBLOCK, &mask, NULL); + ret = pthread_sigmask(SIG_UNBLOCK, &mask, NULL); if (ret < 0) _exit(EXIT_FAILURE); From eabf1ea9cd66d99470214cd01486b7a56519d695 Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Thu, 24 May 2018 20:45:29 +0200 Subject: [PATCH 2/2] utils: fix task_blocking_signal() sscanf() skips whitespace anyway so don't account for tabs in case the file layout changes. Signed-off-by: Christian Brauner --- src/lxc/lxccontainer.c | 5 ++--- src/lxc/utils.c | 17 ++++++++--------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 16182332c..02c7e09a9 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -2000,11 +2000,10 @@ static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout) return true; /* Detect whether we should send SIGRTMIN + 3 (e.g. systemd). */ - if (task_blocking_signal(pid, (SIGRTMIN + 3))) - haltsignal = (SIGRTMIN + 3); - if (c->lxc_conf && c->lxc_conf->haltsignal) haltsignal = c->lxc_conf->haltsignal; + else if (task_blocking_signal(pid, (SIGRTMIN + 3))) + haltsignal = (SIGRTMIN + 3); /* Add a new state client before sending the shutdown signal so that we * don't miss a state. diff --git a/src/lxc/utils.c b/src/lxc/utils.c index 82403dfc6..4d9eea87e 100644 --- a/src/lxc/utils.c +++ b/src/lxc/utils.c @@ -1814,17 +1814,16 @@ int lxc_count_file_lines(const char *fn) /* Check whether a signal is blocked by a process. */ /* /proc/pid-to-str/status\0 = (5 + 21 + 7 + 1) */ -#define __PROC_STATUS_LEN (5 + (LXC_NUMSTRLEN64) + 7 + 1) +#define __PROC_STATUS_LEN (6 + (LXC_NUMSTRLEN64) + 7 + 1) bool task_blocking_signal(pid_t pid, int signal) { - bool bret = false; - char *line = NULL; + int ret; + char status[__PROC_STATUS_LEN]; + FILE *f; long unsigned int sigblk = 0; size_t n = 0; - int ret; - FILE *f; - - char status[__PROC_STATUS_LEN]; + bool bret = false; + char *line = NULL; ret = snprintf(status, __PROC_STATUS_LEN, "/proc/%d/status", pid); if (ret < 0 || ret >= __PROC_STATUS_LEN) @@ -1835,10 +1834,10 @@ bool task_blocking_signal(pid_t pid, int signal) return bret; while (getline(&line, &n, f) != -1) { - if (strncmp(line, "SigBlk:\t", 8)) + if (strncmp(line, "SigBlk:", 7)) continue; - if (sscanf(line + 8, "%lx", &sigblk) != 1) + if (sscanf(line + 7, "%lx", &sigblk) != 1) goto out; }