shithub: choc

Download patch

ref: 1bcff874c52aca3134cee636178ab5d6272fef58
parent: a915b13e0d0c612c12b8f54132ffa3189375dde5
author: Simon Howard <[email protected]>
date: Sun Apr 26 14:55:43 EDT 2015

Don't read currentthinker->next after Z_Free().

Save the next pointer in the P_RunThinkers() loop when iterating through
thinkers, so that if the current thinker is freed we can still advance
to the next thinker without dereferencing freed memory.

--- a/src/doom/p_tick.c
+++ b/src/doom/p_tick.c
@@ -93,17 +93,19 @@
 //
 void P_RunThinkers (void)
 {
-    thinker_t*	currentthinker;
+    thinker_t *currentthinker, *nextthinker;
 
     currentthinker = thinkercap.next;
     while (currentthinker != &thinkercap)
     {
+        nextthinker = currentthinker->next;
+
 	if ( currentthinker->function.acv == (actionf_v)(-1) )
 	{
 	    // time to remove it
 	    currentthinker->next->prev = currentthinker->prev;
 	    currentthinker->prev->next = currentthinker->next;
-	    Z_Free (currentthinker);
+	    Z_Free(currentthinker);
 	}
 	else
 	{
@@ -110,7 +112,7 @@
 	    if (currentthinker->function.acp1)
 		currentthinker->function.acp1 (currentthinker);
 	}
-	currentthinker = currentthinker->next;
+	currentthinker = nextthinker;
     }
 }
 
--- a/src/heretic/p_tick.c
+++ b/src/heretic/p_tick.c
@@ -110,11 +110,13 @@
 
 void P_RunThinkers(void)
 {
-    thinker_t *currentthinker;
+    thinker_t *currentthinker, *nextthinker;
 
     currentthinker = thinkercap.next;
     while (currentthinker != &thinkercap)
     {
+        nextthinker = currentthinker->next;
+
         if (currentthinker->function == (think_t) - 1)
         {                       // time to remove it
             currentthinker->next->prev = currentthinker->prev;
@@ -126,7 +128,7 @@
             if (currentthinker->function)
                 currentthinker->function(currentthinker);
         }
-        currentthinker = currentthinker->next;
+        currentthinker = nextthinker;
     }
 }
 
--- a/src/hexen/p_tick.c
+++ b/src/hexen/p_tick.c
@@ -86,11 +86,13 @@
 
 static void RunThinkers(void)
 {
-    thinker_t *currentthinker;
+    thinker_t *currentthinker, *nextthinker;
 
     currentthinker = thinkercap.next;
     while (currentthinker != &thinkercap)
     {
+        nextthinker = currentthinker->next;
+
         if (currentthinker->function == (think_t) - 1)
         {                       // Time to remove it
             currentthinker->next->prev = currentthinker->prev;
@@ -101,7 +103,8 @@
         {
             currentthinker->function(currentthinker);
         }
-        currentthinker = currentthinker->next;
+
+        currentthinker = nextthinker;
     }
 }
 
--- a/src/strife/p_tick.c
+++ b/src/strife/p_tick.c
@@ -99,11 +99,13 @@
 //
 void P_RunThinkers (void)
 {
-    thinker_t*  currentthinker;
+    thinker_t *currentthinker, *nextthinker;
 
     currentthinker = thinkercap.next;
     while (currentthinker != &thinkercap)
     {
+        nextthinker = currentthinker->next;
+
         if ( currentthinker->function.acv == (actionf_v)(-1) )
         {
             // time to remove it
@@ -116,7 +118,8 @@
             if (currentthinker->function.acp1)
                 currentthinker->function.acp1 (currentthinker);
         }
-        currentthinker = currentthinker->next;
+
+        currentthinker = nextthinker;
     }
 }