<< | Thread Index | >> ]    [ << | Date Index | >> ]

Subject: Race condition on cipe startup
From: "R. Steve McKown" <rsmckown,AT,yahoo,DOT,com>
Date: Thu, 27 Mar 2003 04:27:46 +0100

I believe I've found a race condition within cipe.  In deamonizing, ciped-cb 
forks a child.  The parent waits for one of two signals: a SIGCHLD indicating 
the forked child exited, or a SIGUSR1 indicating the forked child has brought 
up the tunnel and completed execution of the ip-up script.

If the child exits very quickly, the parent can processes the SIGCHLD event 
via its handler before it reaches execution of pause() in ciped.c line 949.  
The parent blocks in pause() forever because the child has already sent its 
signal, and the child blocks forever as a defunct process waiting for its 
parent to wait() upon it.

We may see this when others haven't because we start multiple cipe tunnels 
simultaneously.  Each ciped-cb allocates its device name dynamically, and we 
see occasional contention (i.e. an error return) at ioctl_alloc in function 
opendev() in file cipe/ciped.c.  This contention causes the forked child to 
exit relatively quickly and so creating the scenario for this race condition 
to be triggered.  Further, we only see this problem on our pentium mmx class 
hardware (NS Geode GXLV-200), and not on faster, PIII class hardware 
(Transmeta TM5400-533).

The patch below, derived against v1.5.4 sources, resolves the problem by 
waiting to process a child exit rather than on a signal event which may have 
already occurred.

--- cipe-1.5.4/cipe/ciped.c.orig        2001-02-11 14:42:39.000000000 -0700
+++ cipe-1.5.4/cipe/ciped.c     2003-03-26 15:24:17.000000000 -0700
@@ -946,10 +946,8 @@
        if (i) {
             /* wait until the child is ready - will send SIGUSR1 */
             while (1) {
-                pause();
-                if (gotsig==SIGCHLD) {
-                    int s;
-                    wait(&s);
+               int s;
+               if (wait(&s)==i) {
                     exit(WIFEXITED(s)?WEXITSTATUS(s):255);
                 }
             }





<< | Thread Index | >> ]    [ << | Date Index | >> ]