Windows: Avoid race during PIOCtl DirNode allocation
authorJeffrey Altman <jaltman@your-file-system.com>
Sat, 4 Feb 2012 22:26:02 +0000 (17:26 -0500)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 6 Feb 2012 07:22:21 +0000 (23:22 -0800)
Use InterlockedCompareExchangePointer to assign the DirNode to
ObjectInfo->Specific.Directory.PIOCtlDirectoryCB.  Otherwise,
one thread could race with another thread when allocating the
pioctl object.

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

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

index 93a37fa..ec9a025 100644 (file)
@@ -5552,6 +5552,7 @@ AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ObjectInfo)
     AFSDirectoryCB *pDirNode = NULL;
     ULONG ulEntryLength = 0;
     AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
+    LONG lCount;
 
     __Enter
     {
@@ -5633,11 +5634,33 @@ AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ObjectInfo)
         pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
                                                                        TRUE);
 
-        ObjectInfo->Specific.Directory.PIOCtlDirectoryCB = pDirNode;
+        if ( InterlockedCompareExchangePointer( (PVOID *)&ObjectInfo->Specific.Directory.PIOCtlDirectoryCB, pDirNode, NULL) != NULL)
+        {
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_WARNING,
+                          "AFSInitPIOCtlDirectoryCB Raced PIOCtlDirectoryCB %08lX pFcb %08lX\n",
+                          ObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
+                          pDirNode);
+
+            //
+            // Increment the open reference and handle on the node
+            //
+
+            lCount = InterlockedIncrement( &pDirNode->ObjectInformation->ObjectReferenceCount);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSInitPIOCtlDirectoryCB Increment count on Object %08lX Cnt %d\n",
+                          pDirNode->ObjectInformation,
+                          lCount);
+
+            try_return( ntStatus = STATUS_REPARSE);
+        }
 
 try_exit:
 
-        if ( !NT_SUCCESS( ntStatus))
+        if ( ntStatus != STATUS_SUCCESS)
         {
 
             if ( pDirNode != NULL)