]> sourceware.org Git - lvm2.git/commitdiff
signals: fix SIGINT blocking flaw causing inconsistent metadata
authorHeinz Mauelshagen <heinzm@redhat.com>
Mon, 10 Apr 2017 16:16:09 +0000 (18:16 +0200)
committerHeinz Mauelshagen <heinzm@redhat.com>
Mon, 10 Apr 2017 16:16:09 +0000 (18:16 +0200)
SIGINT isn't blocked properly after a sigint_allow(),
sigint_restore() cycle leading to illicit interruptable
metadata updates.  These can leave corrupted metadata behind.

Issues addressed in this commit:

sigint_allow() fails to set _oldmasked[] members properly due
to an offset by one bug on indexing the members of the array.

It bails out prematurely comparing to MAX_SIGINTS causing nesting
depths to be one less than MAX_SIGINTS.  Fix the comparision.

Correct the related comparison flaw in sigint_restore().

Initialize all sig_atomic_t variables consequently.

Resolves: rhbz1440766

lib/misc/lvm-signal.c

index 7e78407bfd8395019a0e33234a8826f988e8eca4..15d8a6f46a9e19610112537e1294553882383116 100644 (file)
@@ -22,7 +22,7 @@
 static sigset_t _oldset;
 static int _signals_blocked = 0;
 static volatile sig_atomic_t _sigint_caught = 0;
-static volatile sig_atomic_t _handler_installed;
+static volatile sig_atomic_t _handler_installed = 0;
 
 /* Support 3 level nesting, increase if needed more */
 #define MAX_SIGINTS 3
@@ -67,7 +67,7 @@ void sigint_allow(void)
         * Do not overwrite the backed-up handler data -
         * just increase nesting count.
         */
-       if (++_handler_installed >= MAX_SIGINTS)
+       if (++_handler_installed > MAX_SIGINTS)
                return;
 
        /* Grab old sigaction for SIGINT: shall not fail. */
@@ -85,7 +85,7 @@ void sigint_allow(void)
        if (sigprocmask(0, NULL, &sigs))
                log_sys_debug("sigprocmask", "");
 
-       if ((_oldmasked[_handler_installed] = sigismember(&sigs, SIGINT))) {
+       if ((_oldmasked[_handler_installed - 1] = sigismember(&sigs, SIGINT))) {
                sigdelset(&sigs, SIGINT);
                if (sigprocmask(SIG_SETMASK, &sigs, NULL))
                        log_sys_debug("sigprocmask", "SIG_SETMASK");
@@ -98,7 +98,7 @@ void sigint_restore(void)
                return;
 
        if (!_handler_installed ||
-           --_handler_installed >= MAX_SIGINTS)
+           --_handler_installed > MAX_SIGINTS)
                return;
 
        /* Nesting count went below MAX_SIGINTS. */
This page took 0.038535 seconds and 5 git commands to generate.