fixed sporadic data loss on pid reuse

This commit is contained in:
Gerhard Rieger 2011-11-18 18:07:39 +01:00
parent 976d6f0b75
commit 49c0505298
4 changed files with 25 additions and 23 deletions

View file

@ -44,6 +44,11 @@ corrections:
only expected broken messages, not corrupted stack (glibc 2.11.1, only expected broken messages, not corrupted stack (glibc 2.11.1,
Ubuntu 10.4) 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
####################### V 1.7.1.3: ####################### V 1.7.1.3:
security: security:

12
xio.h
View file

@ -1,5 +1,5 @@
/* source: xio.h */ /* source: xio.h */
/* Copyright Gerhard Rieger 2001-2009 */ /* Copyright Gerhard Rieger 2001-2011 */
/* Published under the GNU General Public License V.2, see file COPYING */ /* Published under the GNU General Public License V.2, see file COPYING */
#ifndef __xio_h_included #ifndef __xio_h_included
@ -402,10 +402,12 @@ extern int xioopenhelp(FILE *of, int level);
/* must be outside function for use by childdied handler */ /* must be outside function for use by childdied handler */
extern xiofile_t *sock1, *sock2; extern xiofile_t *sock1, *sock2;
extern pid_t diedunknown1; /* child died before it is registered */ #define NUMUNKNOWN 4
extern pid_t diedunknown2; extern pid_t diedunknown[NUMUNKNOWN]; /* child died before it is registered */
extern pid_t diedunknown3; #define diedunknown1 (diedunknown[0])
extern pid_t diedunknown4; #define diedunknown2 (diedunknown[1])
#define diedunknown3 (diedunknown[2])
#define diedunknown4 (diedunknown[3])
extern int xiosetsigchild(xiofile_t *xfd, int (*callback)(struct single *)); extern int xiosetsigchild(xiofile_t *xfd, int (*callback)(struct single *));
extern int xiosetchilddied(void); extern int xiosetchilddied(void);

View file

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

View file

@ -1,5 +1,5 @@
/* source: xiosigchld.c */ /* source: xiosigchld.c */
/* Copyright Gerhard Rieger 2001-2008 */ /* Copyright Gerhard Rieger 2001-2011 */
/* Published under the GNU General Public License V.2, see file COPYING */ /* Published under the GNU General Public License V.2, see file COPYING */
/* this is the source of the extended child signal handler */ /* this is the source of the extended child signal handler */
@ -10,10 +10,8 @@
/*!! with socat, at most 4 exec children exist */ /*!! with socat, at most 4 exec children exist */
pid_t diedunknown1; /* child died before it is registered */ pid_t diedunknown[NUMUNKNOWN]; /* children that died before they were registered */
pid_t diedunknown2; size_t nextunknown;
pid_t diedunknown3;
pid_t diedunknown4;
/* register for a xio filedescriptor a callback (handler). /* register for a xio filedescriptor a callback (handler).
@ -114,19 +112,12 @@ void childdied(int signum) {
} }
if (i == XIO_MAXSOCK) { if (i == XIO_MAXSOCK) {
Info2("childdied(%d): cannot identify child %d", signum, pid); Info2("childdied(%d): cannot identify child %d", signum, pid);
if (diedunknown1 == 0) { if (nextunknown == NUMUNKNOWN) {
diedunknown1 = pid; nextunknown = 0;
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");
} }
diedunknown[nextunknown++] = pid;
Debug1("saving pid in diedunknown%u",
nextunknown/*sic, for compatibility*/);
} }
if (WIFEXITED(status)) { if (WIFEXITED(status)) {