]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
journal-file: handle SIGBUS on offlining thread
authorChris Morin <chris.morin2@gmail.com>
Wed, 20 Mar 2019 08:34:23 +0000 (01:34 -0700)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 20 Mar 2019 12:02:04 +0000 (13:02 +0100)
The thread launched in journal_file_set_offline() accesses a memory
mapped file, so it needs to handle SIGBUS. Leave SIGBUS unblocked on the
offlining thread so that it uses the same handler as the main thread.

The result of triggering SIGBUS in a thread where it's blocked is
undefined in Linux. The tested implementations were observed to cause
the default handler to run, taking down the whole journald process.

We can leave SIGBUS unblocked in multiple threads since it's handler is
thread-safe. If SIGBUS is sent to the journald process asynchronously
(i.e. with kill, sigqueue, or raise), either thread handling it will
result in the same behavior: it will install the default handler and
reraise the signal, killing the process.

Fixes: #12042
src/journal/journal-file.c

index e0f06a21bbc4b21c72f795fc882d08d5f1df384b..6a2e80e3c8cf7a98851e0b50f9e5efced77c0d61 100644 (file)
@@ -239,6 +239,9 @@ int journal_file_set_offline(JournalFile *f, bool wait) {
                 int k;
 
                 assert_se(sigfillset(&ss) >= 0);
+                /* Don't block SIGBUS since the offlining thread accesses a memory mapped file.
+                 * Asynchronous SIGBUS signals can safely be handled by either thread. */
+                assert_se(sigdelset(&ss, SIGBUS) >= 0);
 
                 r = pthread_sigmask(SIG_BLOCK, &ss, &saved_ss);
                 if (r > 0)