Skip to content

Commit ebf1757

Browse files
committed
BUG/MINOR: wdt/debug: avoid signal re-entrance between debugger and watchdog
As seen in issue haproxy#2860, there are some situations where a watchdog could trigger during the debug signal handler, and where similarly the debug signal handler may trigger during the wdt handler. This is really bad because it could trigger some deadlocks inside inner libc code such as dladdr() or backtrace() since the code will not protect against re- entrance but only against concurrent accesses. A first attempt was made using ha_sigmask() but that's not always very convenient because the second handler is called immediately after unblocking the signal and before returning, leaving signal cascades in backtrace. Instead, let's mark which signals to block at registration time. Here we're blocking wdt/dbg for both signals, and optionally SIGRTMAX if DEBUG_DEV is used as that one may also be used in this case. This should be backported at least to 3.1.
1 parent 0b56839 commit ebf1757

2 files changed

Lines changed: 14 additions & 0 deletions

File tree

src/debug.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2481,6 +2481,13 @@ static int init_debug()
24812481
sa.sa_handler = NULL;
24822482
sa.sa_sigaction = debug_handler;
24832483
sigemptyset(&sa.sa_mask);
2484+
#ifdef WDTSIG
2485+
sigaddset(&sa.sa_mask, WDTSIG);
2486+
#endif
2487+
sigaddset(&sa.sa_mask, DEBUGSIG);
2488+
#if defined(DEBUG_DEV)
2489+
sigaddset(&sa.sa_mask, SIGRTMAX);
2490+
#endif
24842491
sa.sa_flags = SA_SIGINFO;
24852492
sigaction(DEBUGSIG, &sa, NULL);
24862493

src/wdt.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,13 @@ int init_wdt()
263263
sa.sa_handler = NULL;
264264
sa.sa_sigaction = wdt_handler;
265265
sigemptyset(&sa.sa_mask);
266+
sigaddset(&sa.sa_mask, WDTSIG);
267+
#ifdef DEBUGSIG
268+
sigaddset(&sa.sa_mask, DEBUGSIG);
269+
#endif
270+
#if defined(DEBUG_DEV)
271+
sigaddset(&sa.sa_mask, SIGRTMAX);
272+
#endif
266273
sa.sa_flags = SA_SIGINFO;
267274
sigaction(WDTSIG, &sa, NULL);
268275
return ERR_NONE;

0 commit comments

Comments
 (0)