From 6bb0014be2c3ea5ca411bf349fb3987c5d496c40 Mon Sep 17 00:00:00 2001 From: Vaibhav Kamra Date: Thu, 23 Feb 2012 09:58:07 -0800 Subject: [PATCH] Windows: Redirector opens must set a valid FsContext A successful open must have FileObject->FsContext set to a structure with a valid/initialized FSRTL_ADVANCED_FCB_HEADER object. Not having this breaks assumptions in the kernel. Patchset edited by Jeffrey Altman Change-Id: I70c9045bfa02c54074c015e6e871ead63efb6769 Reviewed-on: http://gerrit.openafs.org/6782 Tested-by: BuildBot Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- .../afsrdr/common/AFSRedirCommonDefines.h | 1 + .../afsrdr/common/AFSRedirCommonStructs.h | 2 + src/WINNT/afsrdr/kernel/fs/AFSCleanup.cpp | 7 +- src/WINNT/afsrdr/kernel/fs/AFSClose.cpp | 6 +- src/WINNT/afsrdr/kernel/fs/AFSCreate.cpp | 7 + src/WINNT/afsrdr/kernel/fs/AFSFileInfo.cpp | 13 +- src/WINNT/afsrdr/kernel/fs/AFSRDRSupport.cpp | 215 +++++++++++++++++- src/WINNT/afsrdr/kernel/fs/AFSSecurity.cpp | 12 +- .../afsrdr/kernel/fs/Include/AFSCommon.h | 6 + 9 files changed, 250 insertions(+), 19 deletions(-) diff --git a/src/WINNT/afsrdr/common/AFSRedirCommonDefines.h b/src/WINNT/afsrdr/common/AFSRedirCommonDefines.h index b3a8177d9..ff0f15b1e 100644 --- a/src/WINNT/afsrdr/common/AFSRedirCommonDefines.h +++ b/src/WINNT/afsrdr/common/AFSRedirCommonDefines.h @@ -147,6 +147,7 @@ #define AFS_SYMBOLIC_LINK_FCB 0x000C #define AFS_SPECIAL_SHARE_FCB 0x000D #define AFS_DFS_LINK_FCB 0x000E +#define AFS_REDIRECTOR_FCB 0x000F #define AFS_INVALID_FCB 0x00FF diff --git a/src/WINNT/afsrdr/common/AFSRedirCommonStructs.h b/src/WINNT/afsrdr/common/AFSRedirCommonStructs.h index 2dcf80a91..6adfad8b3 100644 --- a/src/WINNT/afsrdr/common/AFSRedirCommonStructs.h +++ b/src/WINNT/afsrdr/common/AFSRedirCommonStructs.h @@ -428,6 +428,8 @@ typedef struct _AFS_DEVICE_EXTENSION ULONG DeviceFlags; + AFSFcb* Fcb; + union { diff --git a/src/WINNT/afsrdr/kernel/fs/AFSCleanup.cpp b/src/WINNT/afsrdr/kernel/fs/AFSCleanup.cpp index 5209873b0..0402dacd4 100644 --- a/src/WINNT/afsrdr/kernel/fs/AFSCleanup.cpp +++ b/src/WINNT/afsrdr/kernel/fs/AFSCleanup.cpp @@ -124,7 +124,7 @@ AFSCommonCleanup( IN PDEVICE_OBJECT DeviceObject, PFILE_OBJECT pFileObject = NULL; AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; BOOLEAN bCompleteRequest = TRUE; - + AFSFcb* pFcb = NULL; __Enter { @@ -134,7 +134,10 @@ AFSCommonCleanup( IN PDEVICE_OBJECT DeviceObject, pFileObject = pIrpSp->FileObject; - if( pIrpSp->FileObject->FsContext == NULL) + pFcb = (AFSFcb*) pIrpSp->FileObject->FsContext; + + if( pFcb == NULL || + pFcb->Header.NodeTypeCode == AFS_REDIRECTOR_FCB) { // diff --git a/src/WINNT/afsrdr/kernel/fs/AFSClose.cpp b/src/WINNT/afsrdr/kernel/fs/AFSClose.cpp index 159dd115f..93ae387ea 100644 --- a/src/WINNT/afsrdr/kernel/fs/AFSClose.cpp +++ b/src/WINNT/afsrdr/kernel/fs/AFSClose.cpp @@ -97,6 +97,7 @@ AFSCommonClose( IN PDEVICE_OBJECT DeviceObject, IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp); AFSDeviceExt *pDeviceExt = NULL; AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + AFSFcb* pFcb = NULL; __Enter { @@ -105,7 +106,10 @@ AFSCommonClose( IN PDEVICE_OBJECT DeviceObject, pIrpSp = IoGetCurrentIrpStackLocation( Irp); - if( pIrpSp->FileObject->FsContext == NULL) + pFcb = (AFSFcb*) pIrpSp->FileObject->FsContext; + + if( pFcb == NULL || + pFcb->Header.NodeTypeCode == AFS_REDIRECTOR_FCB) { AFSCompleteRequest( Irp, ntStatus); diff --git a/src/WINNT/afsrdr/kernel/fs/AFSCreate.cpp b/src/WINNT/afsrdr/kernel/fs/AFSCreate.cpp index 2401b5366..55d741855 100644 --- a/src/WINNT/afsrdr/kernel/fs/AFSCreate.cpp +++ b/src/WINNT/afsrdr/kernel/fs/AFSCreate.cpp @@ -244,13 +244,20 @@ AFSOpenRedirector( IN PIRP Irp) NTSTATUS ntStatus = STATUS_SUCCESS; FILE_OBJECT *pFileObject = NULL; IO_STACK_LOCATION *pIrpSp; + AFSDeviceExt* pDeviceExt = + (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension; __Enter { pIrpSp = IoGetCurrentIrpStackLocation( Irp); + pFileObject = pIrpSp->FileObject; + pFileObject->FsContext = (PVOID) pDeviceExt->Fcb; + + ASSERT(pFileObject->FsContext != NULL); + // // Return the open result for this file // diff --git a/src/WINNT/afsrdr/kernel/fs/AFSFileInfo.cpp b/src/WINNT/afsrdr/kernel/fs/AFSFileInfo.cpp index 74bbad317..cc3c950fd 100644 --- a/src/WINNT/afsrdr/kernel/fs/AFSFileInfo.cpp +++ b/src/WINNT/afsrdr/kernel/fs/AFSFileInfo.cpp @@ -58,7 +58,7 @@ AFSQueryFileInfo( IN PDEVICE_OBJECT DeviceObject, NTSTATUS ntStatus = STATUS_SUCCESS; IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp); AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; - + AFSFcb* pFcb = NULL; __try { @@ -73,7 +73,10 @@ AFSQueryFileInfo( IN PDEVICE_OBJECT DeviceObject, try_return( ntStatus); } - if( pIrpSp->FileObject->FsContext == NULL) + pFcb = (AFSFcb*) pIrpSp->FileObject->FsContext; + + if( pFcb == NULL || + pFcb->Header.NodeTypeCode == AFS_REDIRECTOR_FCB) { // @@ -155,6 +158,7 @@ AFSSetFileInfo( IN PDEVICE_OBJECT DeviceObject, AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension; AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp); + AFSFcb* pFcb = NULL; __try { @@ -170,7 +174,10 @@ AFSSetFileInfo( IN PDEVICE_OBJECT DeviceObject, try_return( ntStatus); } - if( pIrpSp->FileObject->FsContext == NULL) + pFcb = (AFSFcb*) pIrpSp->FileObject->FsContext; + + if( pFcb == NULL || + pFcb->Header.NodeTypeCode == AFS_REDIRECTOR_FCB) { // diff --git a/src/WINNT/afsrdr/kernel/fs/AFSRDRSupport.cpp b/src/WINNT/afsrdr/kernel/fs/AFSRDRSupport.cpp index 93354a82f..31d1e3442 100644 --- a/src/WINNT/afsrdr/kernel/fs/AFSRDRSupport.cpp +++ b/src/WINNT/afsrdr/kernel/fs/AFSRDRSupport.cpp @@ -114,6 +114,19 @@ AFSInitRDRDevice() ExInitializeResourceLite( &pDeviceExt->Specific.RDR.ProviderListLock); + ntStatus = AFSInitRdrFcb( &pDeviceExt->Fcb); + + if ( !NT_SUCCESS(ntStatus)) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "AFSInitRDRDevice AFSInitRdrFcb failure %08lX\n", + ntStatus); + + try_return( ntStatus); + } + // // Clear the initializing bit // @@ -160,6 +173,12 @@ AFSInitRDRDevice() } } + // + // Good to go, all registered and ready to start receiving requests + // + +try_exit: + if( !NT_SUCCESS( ntStatus)) { @@ -181,17 +200,6 @@ AFSInitRDRDevice() try_return( ntStatus); } - - // - // Good to go, all registered and ready to start receiving requests - // - -try_exit: - - if( !NT_SUCCESS( ntStatus)) - { - - } } return ntStatus; @@ -714,6 +722,14 @@ try_exit: AFSDumpFileLocation.Buffer = NULL; } + if ( pDevExt->Fcb != NULL) + { + + AFSRemoveRdrFcb( &pDevExt->Fcb); + + pDevExt = NULL; + } + AFSUnloadLibrary( TRUE); } } @@ -787,7 +803,184 @@ AFSCloseRedirector() AFSDumpFileLocation.Buffer = NULL; } + + if ( pDevExt->Fcb != NULL) + { + + AFSRemoveRdrFcb( &pDevExt->Fcb); + + pDevExt->Fcb = NULL; + } + } return ntStatus; } + +// +// Function: AFSInitRdrFcb +// +// Description: +// +// This function performs Redirector Fcb initialization +// +// Return: +// +// A status is returned for the function +// + +NTSTATUS +AFSInitRdrFcb( OUT AFSFcb **RdrFcb) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSFcb *pFcb = NULL; + AFSNonPagedFcb *pNPFcb = NULL; + IO_STATUS_BLOCK stIoStatus = {0,0}; + AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension; + + __Enter + { + + // + // Initialize the root fcb + // + + pFcb = (AFSFcb *)AFSExAllocatePoolWithTag( PagedPool, + sizeof( AFSFcb), + AFS_FCB_ALLOCATION_TAG); + + if( pFcb == NULL) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "AFSInitRdrFcb Failed to allocate the root fcb\n"); + + try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); + } + + RtlZeroMemory( pFcb, + sizeof( AFSFcb)); + + pFcb->Header.NodeByteSize = sizeof( AFSFcb); + pFcb->Header.NodeTypeCode = AFS_REDIRECTOR_FCB; + + pNPFcb = (AFSNonPagedFcb *)AFSExAllocatePoolWithTag( NonPagedPool, + sizeof( AFSNonPagedFcb), + AFS_FCB_NP_ALLOCATION_TAG); + + if( pNPFcb == NULL) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "AFSInitRdrFcb Failed to allocate the non-paged fcb\n"); + + try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); + } + + RtlZeroMemory( pNPFcb, + sizeof( AFSNonPagedFcb)); + + pNPFcb->Size = sizeof( AFSNonPagedFcb); + + pNPFcb->Type = AFS_NON_PAGED_FCB; + + // + // OK, initialize the entry + // + + ExInitializeFastMutex( &pNPFcb->AdvancedHdrMutex); + + FsRtlSetupAdvancedHeader( &pFcb->Header, &pNPFcb->AdvancedHdrMutex); + + ExInitializeResourceLite( &pNPFcb->Resource); + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSInitRootFcb Acquiring Fcb lock %08lX EXCL %08lX\n", + &pNPFcb->Resource, + PsGetCurrentThread()); + + ExInitializeResourceLite( &pNPFcb->PagingResource); + + pFcb->Header.Resource = &pNPFcb->Resource; + + pFcb->Header.PagingIoResource = &pNPFcb->PagingResource; + + pFcb->NPFcb = pNPFcb; + + if ( InterlockedCompareExchangePointer( (PVOID *)RdrFcb, pFcb, NULL) != NULL) + { + + try_return( ntStatus = STATUS_REPARSE); + } + +try_exit: + + if( ntStatus != STATUS_SUCCESS) + { + + if( pFcb != NULL) + { + + AFSRemoveRdrFcb( &pFcb); + } + } + } + + return ntStatus; +} + +// +// Function: AFSRemoveRdrFcb +// +// Description: +// +// This function performs Redirector Fcb removal/deallocation +// +// Return: +// +// void. +// + +void +AFSRemoveRdrFcb( IN OUT AFSFcb **RdrFcb) +{ + AFSFcb *pFcb = NULL; + + pFcb = (AFSFcb *) InterlockedCompareExchangePointer( (PVOID *)RdrFcb, NULL, (PVOID)(*RdrFcb)); + + if ( pFcb == NULL) + { + + return; + } + + if( pFcb->NPFcb != NULL) + { + + // + // Now the resource + // + + ExDeleteResourceLite( &pFcb->NPFcb->Resource); + + ExDeleteResourceLite( &pFcb->NPFcb->PagingResource); + + // + // The non paged region + // + + AFSExFreePool( pFcb->NPFcb); + } + + // + // And the Fcb itself + // + + AFSExFreePool( pFcb); + + return; +} diff --git a/src/WINNT/afsrdr/kernel/fs/AFSSecurity.cpp b/src/WINNT/afsrdr/kernel/fs/AFSSecurity.cpp index bb4380644..b4a33e310 100644 --- a/src/WINNT/afsrdr/kernel/fs/AFSSecurity.cpp +++ b/src/WINNT/afsrdr/kernel/fs/AFSSecurity.cpp @@ -46,6 +46,7 @@ AFSSetSecurity( IN PDEVICE_OBJECT DeviceObject, NTSTATUS ntStatus = STATUS_NOT_SUPPORTED; IO_STACK_LOCATION *pIrpSp; AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + AFSFcb* pFcb = NULL; pIrpSp = IoGetCurrentIrpStackLocation( Irp); @@ -68,7 +69,10 @@ AFSSetSecurity( IN PDEVICE_OBJECT DeviceObject, try_return( ntStatus); } - if( pIrpSp->FileObject->FsContext == NULL) + pFcb = (AFSFcb*) pIrpSp->FileObject->FsContext; + + if( pFcb == NULL || + pFcb->Header.NodeTypeCode == AFS_REDIRECTOR_FCB) { // @@ -135,6 +139,7 @@ AFSQuerySecurity( IN PDEVICE_OBJECT DeviceObject, NTSTATUS ntStatus = STATUS_NOT_SUPPORTED; IO_STACK_LOCATION *pIrpSp; AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + AFSFcb* pFcb = NULL; pIrpSp = IoGetCurrentIrpStackLocation( Irp); @@ -157,7 +162,10 @@ AFSQuerySecurity( IN PDEVICE_OBJECT DeviceObject, try_return( ntStatus); } - if( pIrpSp->FileObject->FsContext == NULL) + pFcb = (AFSFcb*) pIrpSp->FileObject->FsContext; + + if( pFcb == NULL || + pFcb->Header.NodeTypeCode == AFS_REDIRECTOR_FCB) { // diff --git a/src/WINNT/afsrdr/kernel/fs/Include/AFSCommon.h b/src/WINNT/afsrdr/kernel/fs/Include/AFSCommon.h index 6ab3472a9..c4b98191a 100644 --- a/src/WINNT/afsrdr/kernel/fs/Include/AFSCommon.h +++ b/src/WINNT/afsrdr/kernel/fs/Include/AFSCommon.h @@ -204,6 +204,12 @@ AFSControlDeviceCreate( IN PIRP Irp); NTSTATUS AFSOpenRedirector( IN PIRP Irp); +NTSTATUS +AFSInitRdrFcb( OUT AFSFcb **RdrFcb); + +void +AFSRemoveRdrFcb( IN OUT AFSFcb **RdrFcb); + // // AFSClose.cpp Prototypes // -- 2.39.5