fixed sporadic data loss on pid reuse

This commit is contained in:
Gerhard Rieger 2012-07-22 17:43:24 +02:00
parent 5b4d970c06
commit f6b2e0b167
4 changed files with 29 additions and 27 deletions

View file

@ -70,6 +70,11 @@ corrections:
development had been aware that localtime() is not thread safe but had
only expected broken messages, not corrupted stack (glibc 2.11.1,
Ubuntu 10.4)
an internal store for child pids was susceptible to pid reuse which
could lead to sporadic data loss when both fork option and exec address
were used. Thanks to Tetsuya Sodo for reporting this problem and
sending a patch
docu mentions option so-bindtodev but correct name is so-bindtodevice.
Thanks to Jim Zimmerman for reporting.

View file

@ -1,5 +1,5 @@
/* source: xioinitialize.c */
/* Copyright Gerhard Rieger 2001-2008 */
/* Copyright Gerhard Rieger 2001-2012 */
/* Published under the GNU General Public License V.2, see file COPYING */
/* this file contains the source for the initialize function */
@ -206,7 +206,11 @@ static int xio_nokill(xiofile_t *sock) {
returns 0 on success or != 0 if an error occurred */
int xio_forked_inchild(void) {
int result = 0;
int i;
for (i=0; i<NUMUNKNOWN; ++i) {
diedunknown[i] = 0;
}
xiodroplocks();
#if WITH_FIPS
if (xio_reset_fips_mode() != 0) {

View file

@ -1,5 +1,5 @@
/* source: xiosigchld.c */
/* Copyright Gerhard Rieger 2001-2008 */
/* Copyright Gerhard Rieger 2001-2012 */
/* Published under the GNU General Public License V.2, see file COPYING */
/* this is the source of the extended child signal handler */
@ -27,11 +27,9 @@ static struct _xiosigchld_child * _xiosigchld_find(pid_t pid);
static struct _xiosigchld_child xio_childpids[XIO_MAXCHILDPIDS];
#if 1 /*!!!*/
/*!! with socat, at most 4 managed children exist */
pid_t diedunknown1; /* child died before it is registered */
pid_t diedunknown2;
pid_t diedunknown3;
pid_t diedunknown4;
/*!! with socat 1, at most 4 managed children existed */
pid_t diedunknown[NUMUNKNOWN]; /* children that died before they were registered */
size_t nextunknown;
#endif
@ -135,21 +133,14 @@ void childdied(int signum
++i;
}
if (i == XIO_MAXSOCK) {
Info2("childdied(%d): cannot identify child %d", signum, pid);
if (diedunknown1 == 0) {
diedunknown1 = pid;
Debug("saving pid in diedunknown1");
} else if (diedunknown2 == 0) {
diedunknown2 = pid;
Debug("saving pid in diedunknown2");
} else if (diedunknown3 == 0) {
diedunknown3 = pid;
Debug("saving pid in diedunknown3");
} else {
diedunknown4 = pid;
Debug("saving pid in diedunknown4");
}
Info2("childdied(%d): cannot identify child %d", signum, pid);
if (nextunknown == NUMUNKNOWN) {
nextunknown = 0;
}
diedunknown[nextunknown++] = pid;
Debug1("saving pid in diedunknown%u",
nextunknown/*sic, for compatibility*/);
}
#else
entry = _xiosigchld_find(pid);
if (entry == NULL) {

View file

@ -1,14 +1,16 @@
/* $Id$ */
/* Copyright Gerhard Rieger 2006 */
/* source: xiosigchld.h */
/* Copyright Gerhard Rieger 2012 */
/* Published under the GNU General Public License V.2, see file COPYING */
#ifndef __xiosigchld_h
#define __xiosigchld_h 1
extern pid_t diedunknown1; /* child died before it is registered */
extern pid_t diedunknown2;
extern pid_t diedunknown3;
extern pid_t diedunknown4;
#define NUMUNKNOWN 4
extern pid_t diedunknown[NUMUNKNOWN]; /* child died before it is registered */
#define diedunknown1 (diedunknown[0])
#define diedunknown2 (diedunknown[1])
#define diedunknown3 (diedunknown[2])
#define diedunknown4 (diedunknown[3])
extern int xiosetsigchild(xiofile_t *xfd, int (*callback)(struct single *));
extern void childdied(int signum