Parent process might have been killed by signal to child

This commit is contained in:
Gerhard Rieger 2019-03-03 09:32:22 +01:00
parent 9f5abda361
commit e1a5931827
5 changed files with 33 additions and 8 deletions

View file

@ -21,6 +21,11 @@ corrections:
Test: DIAG_FDIN Test: DIAG_FDIN
Problem reported by Onur Sentürk. 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: testing:
test.sh: Show a warning when phase-1 (insecure phase) of a security test.sh: Show a warning when phase-1 (insecure phase) of a security
test fails test fails

29
error.c
View file

@ -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_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]; 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) { if (socketpair(AF_UNIX, SOCK_DGRAM, 0, handlersocks) < 0) {
diag_sock_send = -1; diag_sock_send = -1;
diag_sock_recv = -1; diag_sock_recv = -1;
@ -128,6 +122,19 @@ static int diag_init(void) {
diag_sock_recv = handlersocks[0]; diag_sock_recv = handlersocks[0];
return 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())) #define DIAG_INIT ((void)(diaginitialized || diag_init()))
@ -224,6 +231,14 @@ int diag_reserve_fd(int fd) {
return 0; 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: /* Linux and AIX syslog format:
Oct 4 17:10:37 hostname socat[52798]: D signal(13, 1) Oct 4 17:10:37 hostname socat[52798]: D signal(13, 1)
*/ */

View file

@ -237,6 +237,7 @@ extern void diag_set_int(char what, int arg);
extern int diag_get_int(char what); extern int diag_get_int(char what);
extern const char *diag_get_string(char what); extern const char *diag_get_string(char what);
extern int diag_reserve_fd(int fd); extern int diag_reserve_fd(int fd);
extern int diag_fork(void);
extern int diag_dup(void); extern int diag_dup(void);
extern int diag_dup2(int newfd); extern int diag_dup2(int newfd);
extern void msg(int level, const char *format, ...); extern void msg(int level, const char *format, ...);

View file

@ -5449,7 +5449,10 @@ testserversec () {
esac esac
else else
$PRINTF "$OK\n" $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)) numOK=$((numOK+1))
fi fi
wait wait

View file

@ -178,6 +178,7 @@ int xio_forked_inchild(void) {
int result = 0; int result = 0;
int i; int i;
diag_fork();
for (i=0; i<NUMUNKNOWN; ++i) { for (i=0; i<NUMUNKNOWN; ++i) {
diedunknown[i] = 0; diedunknown[i] = 0;
} }