diff options
author | Heinz Mauelshagen <heinzm@redhat.com> | 2017-04-10 18:16:09 +0200 |
---|---|---|
committer | Heinz Mauelshagen <heinzm@redhat.com> | 2017-04-10 18:16:09 +0200 |
commit | 9a689fb8f0a6b1675a4e819f4837bf2e0269832f (patch) | |
tree | 7d1c8fea66b55062bea339ddbb461cad651f70e0 /lib/misc | |
parent | ef3e1013aa8d7797fa432e2da219255178b8ede3 (diff) | |
download | lvm2-9a689fb8f0a6b1675a4e819f4837bf2e0269832f.tar.gz |
signals: fix SIGINT blocking flaw causing inconsistent metadata
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
Diffstat (limited to 'lib/misc')
-rw-r--r-- | lib/misc/lvm-signal.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/lib/misc/lvm-signal.c b/lib/misc/lvm-signal.c index 7e78407bf..15d8a6f46 100644 --- a/lib/misc/lvm-signal.c +++ b/lib/misc/lvm-signal.c @@ -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. */ |