Windows: AFSInvalidateObject can overwrite input param
authorJeffrey Altman <jaltman@your-file-system.com>
Mon, 26 Mar 2012 15:10:36 +0000 (11:10 -0400)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Wed, 28 Mar 2012 04:08:56 +0000 (21:08 -0700)
AFSInvalidateObject() must not be called with an AFSObjectInformationCB
pointer variable that it is not safe to overwrite as the function sets
the input value to NULL if the invalidation is going to be performed
asynchronously in a worker thread.

In AFSEnumerateDirectory(), the following call took place:

  AFSInvalidateObject( &pDirNode->ObjectInformation,
                       AFS_INVALIDATE_DATA_VERSION);

which requires a worker thread to process.  As a result, the
ObjectInformation pointer was being set to NULL which detached the
AFSObjectInformationCB from the AFSDirectoryCB.  That in turn produced
an execption in AFSLocateName() which resulted in a resource not being
freed that in turn produced a deadlock.

Change-Id: Id30e84cf96b69156d648e3b452e7e03390559c43
Reviewed-on: http://gerrit.openafs.org/6962
Reviewed-by: Jeffrey Altman <jaltman@secure-endpoints.com>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Tested-by: Jeffrey Altman <jaltman@secure-endpoints.com>

src/WINNT/afsrdr/kernel/lib/AFSCommSupport.cpp
src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp

index 1f684d0..9afcdf9 100644 (file)
@@ -303,8 +303,19 @@ AFSEnumerateDirectory( IN GUID *AuthGroup,
                         if( pDirNode->ObjectInformation->DataVersion.QuadPart != pCurrentDirEntry->DataVersion.QuadPart)
                         {
 
-                            AFSInvalidateObject( &pDirNode->ObjectInformation,
-+                                                 AFS_INVALIDATE_DATA_VERSION);
+                            LONG lCount;
+                            AFSObjectInfoCB *pObjectInfo = pDirNode->ObjectInformation;
+
+                            lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+
+                            AFSInvalidateObject( &pObjectInfo,
+                                                 AFS_INVALIDATE_DATA_VERSION);
+
+                            if( pObjectInfo != NULL)
+                            {
+
+                                lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
+                            }
                         }
                         else
                         {
@@ -748,6 +759,7 @@ AFSVerifyDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB,
     AFSObjectInfoCB *pObjectInfo = NULL;
     ULONGLONG ullIndex = 0;
     UNICODE_STRING uniGUID;
+    LONG lCount;
 
     __Enter
     {
@@ -1058,8 +1070,16 @@ AFSVerifyDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB,
                         if( pObjectInfo->DataVersion.QuadPart != pCurrentDirEntry->DataVersion.QuadPart)
                         {
 
+                            lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+
                             AFSInvalidateObject( &pObjectInfo,
                                                  AFS_INVALIDATE_DATA_VERSION);
+
+                            if( pObjectInfo != NULL)
+                            {
+
+                                lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
+                            }
                         }
                         else
                         {
index fbdfa31..80a1b4c 100644 (file)
@@ -2481,13 +2481,17 @@ AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
             AFSInvalidateObject( &pCurrentObject,
                                  Reason);
 
-            lCount = InterlockedDecrement( &pCurrentObject->ObjectReferenceCount);
+            if ( pCurrentObject)
+            {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSInvalidateVolumeObjects Decrement count on object %08lX Cnt %d\n",
-                          pCurrentObject,
-                          lCount);
+                lCount = InterlockedDecrement( &pCurrentObject->ObjectReferenceCount);
+
+                AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSInvalidateVolumeObjects Decrement count on object %08lX Cnt %d\n",
+                              pCurrentObject,
+                              lCount);
+            }
         }
 
         //