[prev in list] [next in list] [prev in thread] [next in thread] 

List:       proftpd-committers
Subject:    [ProFTPD-committers] CVS: proftpd/src main.c, 1.336, 1.337 table.c,
From:       TJ Saunders <castaglia () users ! sourceforge ! net>
Date:       2008-05-13 5:41:50
Message-ID: E1JvnGo-00070I-CJ () sc8-pr-cvs1 ! sourceforge ! net
[Download RAW message or body]

Update of /cvsroot/proftp/proftpd/src
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26494/src

Modified Files:
	main.c table.c 
Log Message:

Fix bug where proftpd could enter a recursive loop and eventually run out
of stack memory.  Turns out that if errno is EINTR when pr_signals_handle()
was called, then pr_signals_handle() would call pr_trace_msg(), which
would lead to a call to pr_signals_handle(), which would call pr_trace_msg(),
etc etc.

To deal with this, the Table API now has an internal-use-only functionn,
used by pr_signals_handle(), to indicate whether a signal is currently being
handled or not.  If a signal is being handled, then the Table API code will
not call pr_signals_handle().


Index: main.c
===================================================================
RCS file: /cvsroot/proftp/proftpd/src/main.c,v
retrieving revision 1.336
retrieving revision 1.337
diff -u -r1.336 -r1.337
--- main.c	11 May 2008 20:40:55 -0000	1.336
+++ main.c	13 May 2008 05:41:48 -0000	1.337
@@ -1604,6 +1604,7 @@
  */
 
 void pr_signals_handle(void) {
+  table_handling_signal(TRUE);
 
   if (errno == EINTR &&
       PR_TUNABLE_EINTR_RETRY_INTERVAL > 0) {
@@ -1686,6 +1687,8 @@
       recvd_signal_flags &= ~RECEIVED_SIG_SHUTDOWN;
     }
   }
+
+  table_handling_signal(FALSE);
 }
 
 /* sig_restart occurs in the master daemon when manually "kill -HUP"

Index: table.c
===================================================================
RCS file: /cvsroot/proftp/proftpd/src/table.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- table.c	17 Feb 2008 21:17:34 -0000	1.12
+++ table.c	13 May 2008 05:41:48 -0000	1.13
@@ -63,6 +63,8 @@
   void (*entremove)(pr_table_entry_t **, pr_table_entry_t *);
 };
 
+static int handling_signal = FALSE;
+
 /* Default table callbacks
  */
 
@@ -81,8 +83,10 @@
     unsigned int c = *k;
     k++;
 
-    /* Always handle signals in potentially long-running while loops. */
-    pr_signals_handle();
+    if (!handling_signal) {
+      /* Always handle signals in potentially long-running while loops. */
+      pr_signals_handle();
+    }
 
     i = (i * 33) + c;
   }
@@ -155,7 +159,10 @@
 
     /* Scan to the end of the list. */
     while (i->next != NULL) {
-      pr_signals_handle();
+      if (!handling_signal) {
+        pr_signals_handle();
+      }
+
       i = i->next;
     }
 
@@ -196,7 +203,10 @@
 
     /* Scan to the end of the list. */
     while (i->next != NULL) {
-      pr_signals_handle();
+      if (!handling_signal) {
+        pr_signals_handle();
+      }
+
       i = i->next;
     }
 
@@ -755,8 +765,10 @@
 
     while (ent) {
       int res;
- 
-      pr_signals_handle();
+
+      if (!handling_signal) { 
+        pr_signals_handle();
+      }
 
       res = cb(ent->key->key_data, ent->key->key_datasz, ent->value_data,
         ent->value_datasz, user_data);
@@ -788,7 +800,9 @@
     pr_table_entry_t *e = tab->chains[i];
 
     while (e) {
-      pr_signals_handle();
+      if (!handling_signal) {
+        pr_signals_handle();
+      }
 
       tab_entry_remove(tab, e);
       tab_entry_free(tab, e);
@@ -854,7 +868,9 @@
 
   ent = tab_entry_next(tab);
   while (ent) {
-    pr_signals_handle();
+    if (!handling_signal) {
+      pr_signals_handle();
+    }
 
     if (prev &&
         ent->key == prev->key) {
@@ -1036,7 +1052,9 @@
     pr_table_entry_t *ent = tab->chains[i];
 
     while (ent) {
-      pr_signals_handle();
+      if (!handling_signal) {
+        pr_signals_handle();
+      }
 
       dumpf("[chain %u#%u] '%s' => '%s' (%u)", i, j++, ent->key->key_data,
         ent->value_data, ent->value_datasz);
@@ -1046,3 +1064,14 @@
 
   return;
 }
+
+int table_handling_signal(int bool) {
+  if (bool == TRUE ||
+      bool == FALSE) {
+    handling_signal = bool;
+    return 0;
+  }
+
+  errno = EINVAL;
+  return -1;
+}


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft 
Defy all challenges. Microsoft(R) Visual Studio 2008. 
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
ProFTPD Committers Mailing List
proftpd-committers@proftpd.org
https://lists.sourceforge.net/lists/listinfo/proftp-committers
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic