summaryrefslogtreecommitdiff
path: root/lib/misc
diff options
context:
space:
mode:
authorHeinz Mauelshagen <heinzm@redhat.com>2017-04-10 18:16:09 +0200
committerHeinz Mauelshagen <heinzm@redhat.com>2017-04-10 18:16:09 +0200
commit9a689fb8f0a6b1675a4e819f4837bf2e0269832f (patch)
tree7d1c8fea66b55062bea339ddbb461cad651f70e0 /lib/misc
parentef3e1013aa8d7797fa432e2da219255178b8ede3 (diff)
downloadlvm2-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.c8
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. */