From c62f93a168f85ffdee223b4b96584daaaef05e75 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Fri, 12 Aug 2022 12:33:32 +0200 Subject: [PATCH] error.c: signal handler messages socket pair is disabled in Filan --- CHANGES | 4 ++++ error.c | 31 ++++++++++++++++++++++++++----- filan_main.c | 1 + 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/CHANGES b/CHANGES index 31ba206..8b56ae1 100644 --- a/CHANGES +++ b/CHANGES @@ -40,6 +40,10 @@ Corrections: ctype(3) functions need there arguments to be unsigned char. Thanks to Taylor R Campbell for sending a patch. + Filan library uses Socats diag/error message system and therefore had + always the signal handler messages socket pair open. This fix avoids + this socketpair in standalone Filan. + Porting: OpenSSL, at least 1.1 on Ubuntu, crashed with SIGSEGV under certain conditions: client connection to server with certificate with empty diff --git a/error.c b/error.c index c0a829b..2fad6c2 100644 --- a/error.c +++ b/error.c @@ -37,6 +37,7 @@ struct diag_opts { int exitstatus; /* pass signal number to error exit */ bool withhostname; /* in custom logs add hostname */ char *hostname; + bool signalsafe; } ; @@ -44,7 +45,7 @@ static void _diag_exit(int status); struct diag_opts diagopts = - { NULL, E_ERROR, E_ERROR, 0, NULL, LOG_DAEMON, false, 0 } ; + { NULL, E_ERROR, E_ERROR, 0, NULL, LOG_DAEMON, false, 0, false, NULL, true } ; static void msg2( #if HAVE_CLOCK_GETTIME @@ -134,8 +135,10 @@ static int diag_init(void) { diaginitialized = 1; /* gcc with GNU libc refuses to set this in the initializer */ diagopts.logfile = stderr; - if (diag_sock_pair() < 0) { - return -1; + if (diagopts.signalsafe) { + if (diag_sock_pair() < 0) { + return -1; + } } return 0; } @@ -143,6 +146,16 @@ static int diag_init(void) { void diag_set(char what, const char *arg) { + switch (what) { + case 'I': + if (diagopts.signalsafe) { + if (diag_sock_send >= 0) { Close(diag_sock_send); diag_sock_send = -1; } + if (diag_sock_recv >= 0) { Close(diag_sock_recv); diag_sock_recv = -1; } + } + diagopts.signalsafe = false; + return; + } + DIAG_INIT; switch (what) { const struct wordent *keywd; @@ -240,7 +253,10 @@ int diag_reserve_fd(int fd) { int diag_fork() { Close(diag_sock_send); Close(diag_sock_recv); - return diag_sock_pair(); + if (diagopts.signalsafe) { + return diag_sock_pair(); + } + return 0; } /* Linux and AIX syslog format: @@ -281,7 +297,7 @@ void msg(int level, const char *format, ...) { diag_dgram.level = level; diag_dgram.exitcode = diagopts.exitstatus; vsnprintf_r(diag_dgram.text, sizeof(diag_dgram.text), format, ap); - if (diag_in_handler && !diag_immediate_msg) { + if (diagopts.signalsafe && diag_in_handler && !diag_immediate_msg) { send(diag_sock_send, &diag_dgram, sizeof(diag_dgram)-TEXTLEN + strlen(diag_dgram.text)+1, 0 /* for canonical reasons */ #ifdef MSG_DONTWAIT @@ -399,6 +415,11 @@ static void _msg(int level, const char *buff, const char *syslp) { void diag_flush(void) { struct diag_dgram recv_dgram; char exitmsg[20]; + + if (!diagopts.signalsafe) { + return; + } + while (recv(diag_sock_recv, &recv_dgram, sizeof(recv_dgram)-1, 0 /* for canonical reasons */ #ifdef MSG_DONTWAIT diff --git a/filan_main.c b/filan_main.c index d19e7b6..5e8ccca 100644 --- a/filan_main.c +++ b/filan_main.c @@ -32,6 +32,7 @@ int main(int argc, const char *argv[]) { const char *outfname = NULL; unsigned long fildes; + diag_set('I', false); diag_set('p', strchr(argv[0], '/') ? strrchr(argv[0], '/')+1 : argv[0]); arg1 = argv+1; --argc;