]> git.pld-linux.org Git - packages/stunnel.git/commitdiff
- security patch from rh -CAN-2002-1563
authormisi3k <misi3k@pld-linux.org>
Fri, 25 Jul 2003 17:55:40 +0000 (17:55 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    stunnel-3.22-sigchld.patch -> 1.1

stunnel-3.22-sigchld.patch [new file with mode: 0644]

diff --git a/stunnel-3.22-sigchld.patch b/stunnel-3.22-sigchld.patch
new file mode 100644 (file)
index 0000000..3955565
--- /dev/null
@@ -0,0 +1,204 @@
+--- stunnel-3.22/client.c      2001-12-23 14:41:32.000000000 -0500
++++ stunnel-3.22/client.c      2003-04-10 14:52:18.000000000 -0400
+@@ -711,6 +711,7 @@
+         if(!options.foreground)
+             dup2(fd[1], 2);
+         closesocket(fd[1]);
++        signal(SIGCHLD, SIG_DFL);
+         if(c->ip) {
+             putenv("LD_PRELOAD=" libdir "/stunnel.so");
+             /* For Tru64 _RLD_LIST is used instead */
+--- stunnel-3.22/stunnel.c     2001-12-20 02:53:54.000000000 -0500
++++ stunnel-3.22/stunnel.c     2003-04-10 15:06:33.000000000 -0400
+@@ -63,6 +63,7 @@
+ void sockerror(char *);
+ void log_error(int, int, char *);
+ static char *my_strerror(int);
++static void child_exited_handler(int, int);
+ #ifdef USE_FORK
+ static void sigchld_handler(int);
+ #endif
+@@ -74,6 +75,7 @@
+ #endif
+ server_options options;
++int signal_pipe[2];
+ #ifdef USE_WIN32
+ /*
+@@ -138,6 +140,10 @@
+     sthreads_init(); /* initialize threads */
+     log(LOG_NOTICE, "%s", stunnel_info());
+     if(options.option & OPT_DAEMON) { /* daemon mode */
++        if(pipe(signal_pipe)) {
++            ioerror("pipe");
++            exit(1);
++        }
+ #ifndef USE_WIN32
+         if(!(options.option & OPT_FOREGROUND))
+             daemonize();
+@@ -165,6 +171,9 @@
+     struct sockaddr_in addr;
+     int addrlen;
+     int max_clients, fds_ulimit=-1;
++    int ready;
++    char c;
++    fd_set read_fds;
+ #if defined HAVE_SYSCONF
+     fds_ulimit=sysconf(_SC_OPEN_MAX);
+@@ -188,7 +197,7 @@
+         log(LOG_ERR, "Memory allocation failed");
+         exit(1);
+     }
+-    max_clients=max_fds>=256 ? max_fds*125/256 : (max_fds-6)/2;
++    max_clients=max_fds>=256 ? max_fds*125/256 : (max_fds-8)/2;
+     log(LOG_NOTICE, "FD_SETSIZE=%d, file ulimit=%d%s -> %d clients allowed",
+         FD_SETSIZE, fds_ulimit, fds_ulimit<0?" (unlimited)":"", max_clients);
+     ls=listen_local();
+@@ -204,8 +213,28 @@
+     while(1) {
+         addrlen=sizeof(addr);
+         do {
+-            s=accept(ls, (struct sockaddr *)&addr, &addrlen);
+-        } while(s<0 && get_last_socket_error()==EINTR);
++            FD_ZERO(&read_fds);
++            FD_SET(ls, &read_fds);
++            FD_SET(signal_pipe[0], &read_fds);
++            ready=select((ls > signal_pipe[0]) ? ls + 1 : signal_pipe[0] + 1,
++                         &read_fds, NULL, NULL, NULL);
++        } while(ready<=0 && get_last_error()==EINTR);
++        /* reap a child which exited, decrementing the client count if we forked it */
++        if(FD_ISSET(signal_pipe[0], &read_fds)) {
++            read(signal_pipe[0], &c, 1);
++#ifdef USE_FORK
++            child_exited_handler(1, 0); /* decrement the client count */
++#else
++            child_exited_handler(0, 1); /* the parent thread already decremented
++                                           the client count */
++#endif
++        }
++        /* if we didn't also have a new connection, go back to waiting */
++        if(!FD_ISSET(ls, &read_fds)) {
++            continue;
++        }
++        /* if we also have a new connection, process it */
++        s=accept(ls, (struct sockaddr *)&addr, &addrlen);
+         if(s<0) {
+             sockerror("accept");
+             continue;
+@@ -574,31 +603,51 @@
+     }
+ }
+-#ifdef USE_FORK
+-static void sigchld_handler(int sig) { /* Dead children detected */
++static void child_exited_handler(int consume_client, int local) { /* Dead children detected */
+     int pid, status;
+ #ifdef HAVE_WAIT_FOR_PID
+     while((pid=wait_for_pid(-1, &status, WNOHANG))>0) {
+-        options.clients--; /* One client less */
+ #else
+     if((pid=wait(&status))>0) {
+-        options.clients--; /* One client less */
+ #endif
++        if(consume_client) {
++            enter_critical_section(CRIT_CLIENTS); /* for multi-cpu machines */
++            options.clients--; /* One client less */
++            leave_critical_section(CRIT_CLIENTS); /* for multi-cpu machines */
++        }
+ #ifdef WIFSIGNALED
+         if(WIFSIGNALED(status)) {
+-            log(LOG_DEBUG, "%s[%d] terminated on signal %d (%d left)",
+-                options.servname, pid, WTERMSIG(status), options.clients);
++            if(local)
++                log(LOG_DEBUG, "Local process %s (PID=%lu) terminated on signal %d",
++                    options.servname, pid, WTERMSIG(status));
++            else
++                log(LOG_DEBUG, "%s[%d] terminated on signal %d (%d left)",
++                    options.servname, pid, WTERMSIG(status), options.clients);
+         } else {
+-            log(LOG_DEBUG, "%s[%d] finished with code %d (%d left)",
+-                options.servname, pid, WEXITSTATUS(status), options.clients);
++            if(local)
++                log(LOG_DEBUG, "Local process %s (PID=%lu) finished with code %d",
++                    options.servname, pid, WEXITSTATUS(status));
++            else
++                log(LOG_DEBUG, "%s[%d] finished with code %d (%d left)",
++                    options.servname, pid, WEXITSTATUS(status),
++                    options.clients);
+         }
+     }
+ #else
+-        log(LOG_DEBUG, "%s[%d] finished with code %d (%d left)",
+-            options.servname, pid, status, options.clients);
++        if(local)
++            log(LOG_DEBUG, "Local process %s (PID=%lu) finished with status %d",
++                options.servname, pid, status);
++        else
++            log(LOG_DEBUG, "%s[%d] finished with code %d (%d left)",
++                options.servname, pid, status, options.clients);
+     }
+ #endif
++}
++
++#ifdef USE_FORK
++static void sigchld_handler(int sig) { /* Dead children detected */
++    write(signal_pipe[1], "", 1);
+     signal(SIGCHLD, sigchld_handler);
+ }
+ #endif
+@@ -606,26 +655,7 @@
+ #ifndef USE_WIN32
+ void local_handler(int sig) { /* Dead of local (-l) process detected */
+-    int pid, status;
+-
+-#ifdef HAVE_WAIT_FOR_PID
+-    while((pid=wait_for_pid(-1, &status, WNOHANG))>0) {
+-#else
+-    if((pid=wait(&status))>0) {
+-#endif
+-#ifdef WIFSIGNALED
+-        if(WIFSIGNALED(status)) {
+-            log(LOG_DEBUG, "Local process %s (PID=%lu) terminated on signal %d",
+-                options.servname, pid, WTERMSIG(status));
+-        } else {
+-            log(LOG_DEBUG, "Local process %s (PID=%lu) finished with code %d",
+-                options.servname, pid, WEXITSTATUS(status));
+-        }
+-#else
+-        log(LOG_DEBUG, "Local process %s (PID=%lu) finished with status %d",
+-            options.servname, pid, status);
+-#endif
+-    }
++    write(signal_pipe[1], "", 1);
+     signal(SIGCHLD, local_handler);
+ }
+--- stunnel-3.22/sthreads.c    2001-11-11 10:06:22.000000000 -0500
++++ stunnel-3.22/sthreads.c    2003-04-10 14:52:18.000000000 -0400
+@@ -180,6 +180,11 @@
+     return 0L;
+ }
++extern int signal_pipe[2];
++static void null_handler(int signum) {
++    signal(SIGCHLD, null_handler);
++}
++
+ int create_client(int ls, int s, void *(*cli)(void *)) {
+     switch(fork()) {
+     case -1:    /* error */
+@@ -187,7 +192,9 @@
+         return -1;
+     case  0:    /* child */
+         closesocket(ls);
+-        signal(SIGCHLD, local_handler);
++        signal(SIGCHLD, null_handler);
++        close(signal_pipe[0]);
++        close(signal_pipe[1]);
+         cli((void *)s);
+         exit(0);
+     default:    /* parent */
This page took 0.057957 seconds and 4 git commands to generate.