From e1a5931827dc93c305204f71b37746bad3b6d5e7 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Sun, 3 Mar 2019 09:32:22 +0100 Subject: [PATCH] Parent process might have been killed by signal to child --- CHANGES | 5 +++++ error.c | 29 ++++++++++++++++++++++------- error.h | 1 + test.sh | 5 ++++- xioinitialize.c | 1 + 5 files changed, 33 insertions(+), 8 deletions(-) diff --git a/CHANGES b/CHANGES index 2b35f10..35e24c5 100644 --- a/CHANGES +++ b/CHANGES @@ -21,6 +21,11 @@ corrections: Test: DIAG_FDIN Problem reported by Onur Sentürk. + The socket based mechanism for passing messages and signal information + from signal handler to process could reach and kill the wrong process. + Introduces functions diag_sock_pair(), diag_fork() + Thanks to Darren Zhao for analysing and reporting this problem. + testing: test.sh: Show a warning when phase-1 (insecure phase) of a security test fails diff --git a/error.c b/error.c index 7de3d39..b1ce8f6 100644 --- a/error.c +++ b/error.c @@ -110,15 +110,9 @@ static int diag_sock_recv = -1; static int diag_msg_avail = 0; /* !=0: messages from within signal handler may be waiting */ -static int diag_init(void) { +static int diag_sock_pair(void) { int handlersocks[2]; - if (diaginitialized) { - return 0; - } - diaginitialized = 1; - /* gcc with GNU libc refuses to set this in the initializer */ - diagopts.logfile = stderr; if (socketpair(AF_UNIX, SOCK_DGRAM, 0, handlersocks) < 0) { diag_sock_send = -1; diag_sock_recv = -1; @@ -128,6 +122,19 @@ static int diag_init(void) { diag_sock_recv = handlersocks[0]; return 0; } + +static int diag_init(void) { + if (diaginitialized) { + return 0; + } + diaginitialized = 1; + /* gcc with GNU libc refuses to set this in the initializer */ + diagopts.logfile = stderr; + if (diag_sock_pair() < 0) { + return -1; + } + return 0; +} #define DIAG_INIT ((void)(diaginitialized || diag_init())) @@ -224,6 +231,14 @@ int diag_reserve_fd(int fd) { return 0; } +/* call this after a fork() from the child process to separate master/parent + sockets from child sockets */ +int diag_fork() { + Close(diag_sock_send); + Close(diag_sock_recv); + return diag_sock_pair(); +} + /* Linux and AIX syslog format: Oct 4 17:10:37 hostname socat[52798]: D signal(13, 1) */ diff --git a/error.h b/error.h index d37982f..c6a3048 100644 --- a/error.h +++ b/error.h @@ -237,6 +237,7 @@ extern void diag_set_int(char what, int arg); extern int diag_get_int(char what); extern const char *diag_get_string(char what); extern int diag_reserve_fd(int fd); +extern int diag_fork(void); extern int diag_dup(void); extern int diag_dup2(int newfd); extern void msg(int level, const char *format, ...); diff --git a/test.sh b/test.sh index 9f9787f..8c6590e 100755 --- a/test.sh +++ b/test.sh @@ -5449,7 +5449,10 @@ testserversec () { esac else $PRINTF "$OK\n" - if [ -n "$debug" ]; then cat $te; fi + [ "$VERBOSE" ] && echo " $TRACE $SOCAT $opts $arg echo" + [ "$debug" ] && cat ${te}3 + [ "$VERBOSE" ] && echo " $TRACE $SOCAT $opts - $arg2" + [ "$debug" ] && cat ${te}4 numOK=$((numOK+1)) fi wait diff --git a/xioinitialize.c b/xioinitialize.c index 29d7b03..a2b8cf6 100644 --- a/xioinitialize.c +++ b/xioinitialize.c @@ -178,6 +178,7 @@ int xio_forked_inchild(void) { int result = 0; int i; + diag_fork(); for (i=0; i