[Cmake-commits] CMake branch, next, updated. v3.5.0-637-g7be32f8

Brad King brad.king at kitware.com
Wed Mar 23 16:13:49 EDT 2016


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, next has been updated
       via  7be32f82c882299e113b13da869459f7988d9a0d (commit)
       via  7731042579ce2ee99e2eed184a79ae8629e04612 (commit)
      from  ac8c02adc3ac2cb6596600af6d1f92e39eca99ab (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=7be32f82c882299e113b13da869459f7988d9a0d
commit 7be32f82c882299e113b13da869459f7988d9a0d
Merge: ac8c02a 7731042
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Wed Mar 23 16:13:48 2016 -0400
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Wed Mar 23 16:13:48 2016 -0400

    Merge topic 'fix-variable_watch-reallocation' into next
    
    77310425 Avoid use-after-free when a variable watch is executed


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=7731042579ce2ee99e2eed184a79ae8629e04612
commit 7731042579ce2ee99e2eed184a79ae8629e04612
Author:     Yves Frederix <yves.frederix at gmail.com>
AuthorDate: Wed Mar 23 10:37:51 2016 +0100
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Wed Mar 23 15:42:56 2016 -0400

    Avoid use-after-free when a variable watch is executed
    
    Re-lookup a variable value when an associated VariableWatch is executed
    in cmMakefile::GetDefinition.
    
    This fixes a problem with 'dep' sometimes becoming invalid due to memory
    reallocation inside an std::vector. In this case, the problem was that
    if the call to VariableAccessed actually executed a callback function,
    the internal state of the makefile has changed due to the associated
    function scope being pushed. This in turn implies that a new
    cmDefinitions instance was pushed in cmMakefile::VarTree. As
    cmLinkedTree is based on an std::vector, this push can have triggered
    reallocation of its internal memory buffer. However, as the value of
    'def', which was computed on method entry, actually points to a property
    of one of the cmDefinitions instances in cmMakefile::VarTree,
    reallocation can invalidate the value of 'def' so that it cannot simply
    be returned at the end of the function. The solution implemented here is
    to simply lookup the value of 'def' again.

diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 950b247..600c985 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -2531,15 +2531,22 @@ const char* cmMakefile::GetDefinition(const std::string& name) const
   cmVariableWatch* vv = this->GetVariableWatch();
   if ( vv && !this->SuppressWatches )
     {
-    if ( def )
-      {
-      vv->VariableAccessed(name, cmVariableWatch::VARIABLE_READ_ACCESS,
-        def, this);
-      }
-    else
-      {
+    bool const watch_function_executed =
       vv->VariableAccessed(name,
-          cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS, def, this);
+                           def ? cmVariableWatch::VARIABLE_READ_ACCESS
+                           : cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS,
+                           def, this);
+
+    if (watch_function_executed)
+      {
+      // A callback was executed and may have caused re-allocation of the
+      // variable storage.  Look it up again for now.
+      // FIXME: Refactor variable storage to avoid this problem.
+      def = this->StateSnapshot.GetDefinition(name);
+      if(!def)
+        {
+        def = this->GetState()->GetInitializedCacheValue(name);
+        }
       }
     }
 #endif
diff --git a/Source/cmVariableWatch.cxx b/Source/cmVariableWatch.cxx
index 57dde31..a200718 100644
--- a/Source/cmVariableWatch.cxx
+++ b/Source/cmVariableWatch.cxx
@@ -96,7 +96,7 @@ void cmVariableWatch::RemoveWatch(const std::string& variable,
     }
 }
 
-void  cmVariableWatch::VariableAccessed(const std::string& variable,
+bool  cmVariableWatch::VariableAccessed(const std::string& variable,
                                         int access_type,
                                         const char* newValue,
                                         const cmMakefile* mf) const
@@ -112,5 +112,7 @@ void  cmVariableWatch::VariableAccessed(const std::string& variable,
       (*it)->Method(variable, access_type, (*it)->ClientData,
         newValue, mf);
       }
+    return true;
     }
+  return false;
 }
diff --git a/Source/cmVariableWatch.h b/Source/cmVariableWatch.h
index 0ca4a55..2f082af 100644
--- a/Source/cmVariableWatch.h
+++ b/Source/cmVariableWatch.h
@@ -42,7 +42,7 @@ public:
   /**
    * This method is called when variable is accessed
    */
-  void VariableAccessed(const std::string& variable, int access_type,
+  bool VariableAccessed(const std::string& variable, int access_type,
     const char* newValue, const cmMakefile* mf) const;
 
   /**

-----------------------------------------------------------------------

Summary of changes:
 Source/cmMakefile.cxx      |   23 +++++++++++++++--------
 Source/cmVariableWatch.cxx |    4 +++-
 Source/cmVariableWatch.h   |    2 +-
 3 files changed, 19 insertions(+), 10 deletions(-)


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list