From: Jeffrey Altman Date: Sat, 4 Feb 2012 22:26:02 +0000 (-0500) Subject: Windows: Avoid race during PIOCtl DirNode allocation X-Git-Tag: upstream/1.8.0_pre1^2~2779 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=39d152810de9adfa89acb994506d0b9d368395f2;p=packages%2Fo%2Fopenafs.git Windows: Avoid race during PIOCtl DirNode allocation 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 Tested-by: Jeffrey Altman Reviewed-by: Jeffrey Altman --- diff --git a/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp b/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp index 93a37fa5a..ec9a0253b 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp @@ -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)