Windows: Redirector opens must set a valid FsContext
authorVaibhav Kamra <vkamra@maginatics.com>
Thu, 23 Feb 2012 17:58:07 +0000 (09:58 -0800)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Fri, 24 Feb 2012 22:37:29 +0000 (14:37 -0800)
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 <jaltman@your-file-system.com>

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

src/WINNT/afsrdr/common/AFSRedirCommonDefines.h
src/WINNT/afsrdr/common/AFSRedirCommonStructs.h
src/WINNT/afsrdr/kernel/fs/AFSCleanup.cpp
src/WINNT/afsrdr/kernel/fs/AFSClose.cpp
src/WINNT/afsrdr/kernel/fs/AFSCreate.cpp
src/WINNT/afsrdr/kernel/fs/AFSFileInfo.cpp
src/WINNT/afsrdr/kernel/fs/AFSRDRSupport.cpp
src/WINNT/afsrdr/kernel/fs/AFSSecurity.cpp
src/WINNT/afsrdr/kernel/fs/Include/AFSCommon.h

index b3a8177..ff0f15b 100644 (file)
 #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
 
index 2dcf80a..6adfad8 100644 (file)
@@ -428,6 +428,8 @@ typedef struct _AFS_DEVICE_EXTENSION
 
     ULONG           DeviceFlags;
 
+    AFSFcb*         Fcb;
+
     union
     {
 
index 5209873..0402dac 100644 (file)
@@ -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)
         {
 
             //
index 159dd11..93ae387 100644 (file)
@@ -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);
index 2401b53..55d7418 100644 (file)
@@ -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
         //
index 74bbad3..cc3c950 100644 (file)
@@ -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)
         {
 
             //
index 93354a8..31d1e34 100644 (file)
@@ -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;
+}
index bb43806..b4a33e3 100644 (file)
@@ -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)
         {
 
             //
index 6ab3472..c4b9819 100644 (file)
@@ -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
 //