From: Jeffrey Altman Date: Sun, 27 Jan 2013 20:06:09 +0000 (-0500) Subject: Windows: AFSEvaluateTargetByID Sanity Check Result X-Git-Tag: openafs-stable-1_8_0pre1~1583 X-Git-Url: https://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=8099525c4a0251974c0a66c4b72fc26187691f29 Windows: AFSEvaluateTargetByID Sanity Check Result If the file server provides the service with bogus status info and that status info is inconsistent with the allocated fields in the associated ObjectInformationCB and FCB structures, it can result in a BSOD. Perform some basic sanity checks and if an inconsistency is discovered, fail the request. This may result in the inability to access a file/directory but will prevent a BSOD. Change-Id: Iabf66adc5e953dc4ae27ed701148a9ffbf55abcc Reviewed-on: http://gerrit.openafs.org/8994 Tested-by: BuildBot Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- diff --git a/src/WINNT/afsrdr/kernel/lib/AFSCommSupport.cpp b/src/WINNT/afsrdr/kernel/lib/AFSCommSupport.cpp index f8a133a..e7d44f9 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSCommSupport.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSCommSupport.cpp @@ -2787,6 +2787,62 @@ AFSEvaluateTargetByID( IN AFSObjectInfoCB *ObjectInfo, } // + // A BSOD can occur if the pEvalResultCB->FileType is FILE but the + // ObjectInfo->FileType is something else. The same is true for + // pDirEnumEntry->FileType is DIRECTORY. Perform a sanity check + // to ensure consistency. An inconsistent pDirEnumEntry can be + // produced as a result of invalid status info received from a file + // server. If the types are inconsistent or if the type does not + // match the implied type derived from the vnode (odd values are + // directories and even values are other types), prevent the request + // from completing successfully. This may prevent access to the file or + // directory but will prevent a BSOD. + // + + if ( !AFSIsEqualFID( &ObjectInfo->FileId, + &pEvalResultCB->DirEnum.FileId)) + { + + try_return( ntStatus = STATUS_UNSUCCESSFUL); + } + + switch ( pEvalResultCB->DirEnum.FileType) + { + + case AFS_FILE_TYPE_DIRECTORY: + if ( (pEvalResultCB->DirEnum.FileId.Vnode & 0x1) != 0x1) + { + + try_return( ntStatus = STATUS_UNSUCCESSFUL); + } + + if ( ObjectInfo->FileType != AFS_FILE_TYPE_UNKNOWN && + ObjectInfo->FileType != AFS_FILE_TYPE_DIRECTORY) + { + + try_return( ntStatus = STATUS_UNSUCCESSFUL); + } + + break; + + case AFS_FILE_TYPE_FILE: + if ( (pEvalResultCB->DirEnum.FileId.Vnode & 0x1) != 0x0) + { + + try_return( ntStatus = STATUS_UNSUCCESSFUL); + } + + if ( ObjectInfo->FileType != AFS_FILE_TYPE_UNKNOWN && + ObjectInfo->FileType != AFS_FILE_TYPE_FILE) + { + + try_return( ntStatus = STATUS_UNSUCCESSFUL); + } + + break; + } + + // // Validate the parent data version //