Bug #1957: Out of bounds std::vector accesses in NDMeshStreamer 41/5041/4
authorVenkatasubrahmanian Narayanan <vn7@illinois.edu>
Tue, 26 Mar 2019 18:00:47 +0000 (13:00 -0500)
committerEvan Ramos <evan@hpccharm.com>
Fri, 5 Apr 2019 03:28:44 +0000 (22:28 -0500)
Fixed issue where NDMeshStreamer accessed elements out of bounds of
some internal std::vectors. The problem was triggered when the
checkForCompletedStages() method was invoked after all the stages had
been completed, and was exposed by the address sanitizer. An extra
check has been added to cover that case.

Change-Id: Ia8f42260544f80833c1718e13f24345b53b71186

src/libs/ck-libs/NDMeshStreamer/NDMeshStreamer.h

index 3de3c6c2f8f60e93da0daf999c3082374adb6e6b..b54089772e22f10c1f363ca4b9ab931a23b1390f 100644 (file)
@@ -250,9 +250,31 @@ public:
       checkForCompletedStages();
     }
   }
+  inline bool checkAllStagesCompleted() {
+    //checks if all stages have been completed
+    //if so, it resets the periodic flushing
+    if (myCompletionStatus_.stageIndex == finalCompletionStage) { //has already completed all stages
+#ifdef CMK_TRAM_VERBOSE_OUTPUT
+      CkPrintf("[%d] All done. Reducing to final callback ...\n", myIndex_);
+#endif
+      CkAssert(numDataItemsBuffered_ == 0);
+      isPeriodicFlushEnabled_ = false;
+      if (!userCallback_.isInvalid()) {
+        this->contribute(userCallback_);
+        userCallback_ = CkCallback();
+      }
+      return true;
+    }
+    else {
+      return false;
+    }
+  }
 
   inline void checkForCompletedStages() {
     int &currentStage = myCompletionStatus_.stageIndex;
+    if (checkAllStagesCompleted()) { //has already completed all stages
+      return;
+    }
     while (cntFinished_[currentStage] == myCompletionStatus_.numContributors &&
            cntMsgExpected_[currentStage] == cntMsgReceived_[currentStage]) {
 #ifdef CMK_TRAM_VERBOSE_OUTPUT
@@ -263,16 +285,7 @@ public:
                cntMsgReceived_[currentStage]);
 #endif
       myRouter_.updateCompletionProgress(myCompletionStatus_);
-      if (myCompletionStatus_.stageIndex == finalCompletionStage) {
-#ifdef CMK_TRAM_VERBOSE_OUTPUT
-        CkPrintf("[%d] All done. Reducing to final callback ...\n", myIndex_);
-#endif
-        CkAssert(numDataItemsBuffered_ == 0);
-        isPeriodicFlushEnabled_ = false;
-        if (!userCallback_.isInvalid()) {
-          this->contribute(userCallback_);
-          userCallback_ = CkCallback();
-        }
+      if (checkAllStagesCompleted()) { //has already completed all stages
         return;
       }
       else {