changeset 23541:25817ecc6123 stable

avoid possible double free at interpreter exit (bug #51088) * symtab.cc (symbol_table::cleanup): Remove pointer to symbol table from all_instances map before deleting it. * symtab.h (symbol_table::erase_scope): Likewise.
author John W. Eaton <jwe@octave.org>
date Tue, 30 May 2017 12:30:44 -0400
parents 14b61de53028
children 0e4ceda8fbcf 7eba3cd5b6e0
files libinterp/corefcn/symtab.cc libinterp/corefcn/symtab.h
diffstat 2 files changed, 13 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/symtab.cc	Sun May 28 12:01:02 2017 -0400
+++ b/libinterp/corefcn/symtab.cc	Tue May 30 12:30:44 2017 -0400
@@ -1627,15 +1627,19 @@
   clear_all (true);
 
   // Delete all possibly remaining scopes.
-  for (all_instances_iterator iter = all_instances.begin ();
-       iter != all_instances.end (); iter++)
+
+  while (! all_instances.empty ())
     {
-      // First zero the table entry to avoid possible duplicate delete.
+      // Note that deleting a scope may have side effects such as
+      // deleting other scopes.  If another scope is deleted, it may
+      // invalidate ITER, so erase this map element first.
+
+      all_instances_iterator iter = all_instances.begin ();
+
       symbol_table *inst = iter->second;
-      iter->second = 0;
 
-      // Now delete the scope.  Note that there may be side effects, such as
-      // deleting other scopes.
+      all_instances.erase (iter);
+
       delete inst;
     }
 
--- a/libinterp/corefcn/symtab.h	Sun May 28 12:01:02 2017 -0400
+++ b/libinterp/corefcn/symtab.h	Tue May 30 12:30:44 2017 -0400
@@ -1222,10 +1222,12 @@
 
     if (p != all_instances.end ())
       {
-        delete p->second;
+        symbol_table *inst = p->second;
 
         all_instances.erase (p);
 
+        delete inst;
+
         free_scope (scope);
       }
   }