From d35164370a8e799ed35f7f23670ddee02dc87f50 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Sun, 28 Jun 2015 13:12:13 -0400 Subject: [PATCH] Windows: Move GetAuthenticationId to Worker Thread When PsReferenceImpersonationToken(), PsReferencePrimaryToken(), and SeQueryInformationToken() are called in the kernel from a user process thread the restrictions on the userland process still apply. Since we do not want to be restricted we must obtain the token and query the token information from a SYSTEM thread. This change restructures the AFSGetAuthenticationId() process to queue a synchronous task to the worker thread. This should address the problem that has been seen during system boot when the Group Policy Service attempts to query, remove or create a drive letter mapping. Change-Id: Ib8772e185aa1e4e52979ec847bbc18a9878bcaca Reviewed-on: http://gerrit.openafs.org/11909 Tested-by: BuildBot Reviewed-by: Jeffrey Altman --- src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp | 112 ++++++++++++++++-- .../kernel/lib/AFSNetworkProviderSupport.cpp | 47 ++++---- src/WINNT/afsrdr/kernel/lib/AFSWorker.cpp | 26 +++- .../afsrdr/kernel/lib/Include/AFSCommon.h | 11 +- .../afsrdr/kernel/lib/Include/AFSDefines.h | 4 +- .../afsrdr/kernel/lib/Include/AFSStructs.h | 12 +- 6 files changed, 170 insertions(+), 42 deletions(-) diff --git a/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp b/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp index 5ad8fe66b..0081fb304 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. - * Copyright (c) 2009, 2010, 2011, 2012, 2013 Your File System, Inc. + * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2015 Your File System, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -7700,8 +7700,100 @@ try_exit: return; } -LARGE_INTEGER -AFSGetAuthenticationId() +NTSTATUS +AFSGetAuthenticationId( OUT LARGE_INTEGER *pliAuthId) +{ + AFSWorkItem *pWorkItem = NULL; + NTSTATUS ntStatus; + + __try + { + + RtlZeroMemory( pliAuthId, sizeof(LARGE_INTEGER)); + + pWorkItem = (AFSWorkItem *) AFSExAllocatePoolWithTag( NonPagedPool, + sizeof(AFSWorkItem), + AFS_WORK_ITEM_TAG); + if (NULL == pWorkItem) + { + + AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER, + AFS_TRACE_LEVEL_ERROR, + "AFSGetAuthenticationId Failed to allocate work item\n")); + + try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES ); + } + + RtlZeroMemory( pWorkItem, + sizeof(AFSWorkItem)); + + pWorkItem->Size = sizeof( AFSWorkItem); + + pWorkItem->RequestType = AFS_WORK_GET_AUTH_ID; + + pWorkItem->RequestFlags = AFS_SYNCHRONOUS_REQUEST; + + KeInitializeEvent(&pWorkItem->Event, + NotificationEvent, + FALSE); + + pWorkItem->Specific.GetAuthId.peProcess = PsGetCurrentProcess(); + + pWorkItem->Specific.GetAuthId.peThread = PsGetCurrentThread(); + + AFSDbgTrace(( AFS_SUBSYSTEM_WORKER_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSGetAuthenticationId Workitem %p\n", + pWorkItem)); + + ntStatus = AFSQueueWorkerRequest( pWorkItem); + +try_exit: + + if( NT_SUCCESS( ntStatus)) + { + + *pliAuthId = pWorkItem->Specific.GetAuthId.AuthId; + + ntStatus = pWorkItem->Status; + + AFSDbgTrace(( AFS_SUBSYSTEM_WORKER_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSGetAuthenticationId Request complete Status %08lX\n", + ntStatus)); + } + else { + + AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "AFSGetAuthenticationId Failed to queue request Status %08lX\n", + ntStatus)); + } + + if( pWorkItem != NULL) + { + + AFSExFreePoolWithTag( pWorkItem, + AFS_WORK_ITEM_TAG); + } + } + __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) ) + { + + AFSDbgTrace(( 0, + 0, + "EXCEPTION - AFSGetAuthenticationId\n")); + + AFSDumpTraceFilesFnc(); + } + + return ntStatus; +} + +NTSTATUS +AFSPerformGetAuthId( IN PEPROCESS peProcess, + IN PETHREAD peThread, + OUT LARGE_INTEGER *outAuthId) { LARGE_INTEGER liAuthId = {0,0}; @@ -7716,7 +7808,7 @@ AFSGetAuthenticationId() __Enter { - hToken = PsReferenceImpersonationToken( PsGetCurrentThread(), + hToken = PsReferenceImpersonationToken( peThread, &bCopyOnOpen, &bEffectiveOnly, &stImpersonationLevel); @@ -7724,14 +7816,14 @@ AFSGetAuthenticationId() if( hToken == NULL) { - hToken = PsReferencePrimaryToken( PsGetCurrentProcess()); + hToken = PsReferencePrimaryToken( peProcess); if( hToken == NULL) { AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER, AFS_TRACE_LEVEL_ERROR, - "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n")); + "AFSPerformGetAuthId Failed to retrieve impersonation or primary token\n")); try_return( ntStatus); } @@ -7748,7 +7840,7 @@ AFSGetAuthenticationId() AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER, AFS_TRACE_LEVEL_ERROR, - "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n", + "AFSPerformGetAuthId Failed to retrieve information Status %08lX\n", ntStatus)); try_return( ntStatus); @@ -7759,7 +7851,7 @@ AFSGetAuthenticationId() AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER, AFS_TRACE_LEVEL_VERBOSE, - "AFSGetAuthenticationId Successfully retrieved authentication ID %I64X\n", + "AFSPerformGetAuthId Successfully retrieved authentication ID %I64X\n", liAuthId.QuadPart)); try_exit: @@ -7784,9 +7876,11 @@ try_exit: ExFreePool( pTokenInfo); // Allocated by SeQueryInformationToken } + + *outAuthId = liAuthId; } - return liAuthId; + return ntStatus; } void diff --git a/src/WINNT/afsrdr/kernel/lib/AFSNetworkProviderSupport.cpp b/src/WINNT/afsrdr/kernel/lib/AFSNetworkProviderSupport.cpp index 37f6175d1..8921d2960 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSNetworkProviderSupport.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSNetworkProviderSupport.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. - * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * Copyright (c) 2009, 2010, 2011, 2015 Your File System, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -61,16 +61,17 @@ AFSAddConnection( IN AFSNetworkProviderConnectionCB *ConnectCB, if( ConnectCB->AuthenticationId.QuadPart == 0) { - ConnectCB->AuthenticationId = AFSGetAuthenticationId(); + ntStatus = AFSGetAuthenticationId(&ConnectCB->AuthenticationId); - if ( ConnectCB->AuthenticationId.QuadPart == 0) + if ( !NT_SUCCESS( ntStatus)) { AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER, AFS_TRACE_LEVEL_ERROR, - "AFSAddConnection Unable to retrieve authentication id\n")); + "AFSAddConnection Unable to retrieve authentication id %08lX\n", + ntStatus)); - return STATUS_ACCESS_DENIED; + return ntStatus; } AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER, @@ -436,16 +437,17 @@ AFSCancelConnection( IN AFSNetworkProviderConnectionCB *ConnectCB, if( ConnectCB->AuthenticationId.QuadPart == 0) { - ConnectCB->AuthenticationId = AFSGetAuthenticationId(); + ntStatus = AFSGetAuthenticationId(&ConnectCB->AuthenticationId); - if ( ConnectCB->AuthenticationId.QuadPart == 0) + if ( !NT_SUCCESS( ntStatus)) { AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER, AFS_TRACE_LEVEL_ERROR, - "AFSCancelConnection Unable to retrieve authentication id\n")); + "AFSCancelConnection Unable to retrieve authentication id %08lX\n", + ntStatus)); - return STATUS_ACCESS_DENIED; + return ntStatus; } AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER, @@ -571,16 +573,17 @@ AFSGetConnection( IN AFSNetworkProviderConnectionCB *ConnectCB, if( ConnectCB->AuthenticationId.QuadPart == 0) { - ConnectCB->AuthenticationId = AFSGetAuthenticationId(); + ntStatus = AFSGetAuthenticationId(&ConnectCB->AuthenticationId); - if ( ConnectCB->AuthenticationId.QuadPart == 0) + if ( !NT_SUCCESS( ntStatus)) { AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER, AFS_TRACE_LEVEL_ERROR, - "AFSGetConnection Unable to retrieve authentication id\n")); + "AFSGetConnection Unable to retrieve authentication id %08lX\n", + ntStatus)); - return STATUS_ACCESS_DENIED; + return ntStatus; } AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER, @@ -721,16 +724,17 @@ AFSListConnections( IN OUT AFSNetworkProviderConnectionCB *ConnectCB, if( ConnectCB->AuthenticationId.QuadPart == 0) { - ConnectCB->AuthenticationId = AFSGetAuthenticationId(); + ntStatus = AFSGetAuthenticationId(&ConnectCB->AuthenticationId); - if ( ConnectCB->AuthenticationId.QuadPart == 0) + if ( !NT_SUCCESS( ntStatus)) { AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER, AFS_TRACE_LEVEL_ERROR, - "AFSListConnections Unable to retrieve authentication id\n")); + "AFSListConnection Unable to retrieve authentication id %08lX\n", + ntStatus)); - return STATUS_ACCESS_DENIED; + return ntStatus; } AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER, @@ -1508,16 +1512,17 @@ AFSGetConnectionInfo( IN AFSNetworkProviderConnectionCB *ConnectCB, if( ConnectCB->AuthenticationId.QuadPart == 0) { - ConnectCB->AuthenticationId = AFSGetAuthenticationId(); + ntStatus = AFSGetAuthenticationId(&ConnectCB->AuthenticationId); - if ( ConnectCB->AuthenticationId.QuadPart == 0) + if ( !NT_SUCCESS( ntStatus)) { AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER, AFS_TRACE_LEVEL_ERROR, - "AFSGetConnectionInfo Unable to retrieve authentication id\n")); + "AFSGetConnectionInfo Unable to retrieve authentication id %08lX\n", + ntStatus)); - return STATUS_ACCESS_DENIED; + return ntStatus; } AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER, diff --git a/src/WINNT/afsrdr/kernel/lib/AFSWorker.cpp b/src/WINNT/afsrdr/kernel/lib/AFSWorker.cpp index 53354138a..ee43f05a3 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSWorker.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSWorker.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. - * Copyright (c) 2009, 2010, 2011, 2012, 2013 Your File System, Inc. + * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2015 Your File System, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -708,7 +708,7 @@ AFSWorkerThread( IN PVOID Context) else { - freeWorkItem = TRUE; + freeWorkItem = !(pWorkItem->RequestFlags & AFS_SYNCHRONOUS_REQUEST); // // Switch on the type of work item to process @@ -755,19 +755,26 @@ AFSWorkerThread( IN PVOID Context) AFSPerformObjectInvalidate( pWorkItem->Specific.Invalidate.ObjectInfo, pWorkItem->Specific.Invalidate.InvalidateReason); - freeWorkItem = TRUE; - break; } case AFS_WORK_START_IOS: { - freeWorkItem = TRUE; - break; } + case AFS_WORK_GET_AUTH_ID: + { + + pWorkItem->Status = + AFSPerformGetAuthId( pWorkItem->Specific.GetAuthId.peProcess, + pWorkItem->Specific.GetAuthId.peThread, + &pWorkItem->Specific.GetAuthId.AuthId); + + break; + } + default: AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING, @@ -784,6 +791,13 @@ AFSWorkerThread( IN PVOID Context) AFSExFreePoolWithTag( pWorkItem, AFS_WORK_ITEM_TAG); } + else + { + + KeSetEvent( &pWorkItem->Event, + 0, + FALSE); + } ntStatus = STATUS_SUCCESS; } diff --git a/src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h b/src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h index d81f2884c..509894f90 100644 --- a/src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h +++ b/src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. - * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * Copyright (c) 2009, 2010, 2011, 2015 Your File System, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -1370,8 +1370,13 @@ void AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo, IN AFSDirectoryCB *DirEntry); -LARGE_INTEGER -AFSGetAuthenticationId( void); +NTSTATUS +AFSGetAuthenticationId( OUT LARGE_INTEGER *pliAuthId); + +NTSTATUS +AFSPerformGetAuthId( IN PEPROCESS peProcess, + IN PETHREAD peThread, + OUT LARGE_INTEGER *outAuthId); void AFSUnwindFileInfo( IN AFSFcb *Fcb, diff --git a/src/WINNT/afsrdr/kernel/lib/Include/AFSDefines.h b/src/WINNT/afsrdr/kernel/lib/Include/AFSDefines.h index 3547e8cfa..517b8e512 100644 --- a/src/WINNT/afsrdr/kernel/lib/Include/AFSDefines.h +++ b/src/WINNT/afsrdr/kernel/lib/Include/AFSDefines.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. - * Copyright (c) 2009, 2010, 2011, 2014 Your File System, Inc. + * Copyright (c) 2009, 2010, 2011, 2014, 2015 Your File System, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -110,7 +110,7 @@ NTSTATUS // Worker Thread codes // -#define AFS_WORK_UNUSED_1 0x0001 +#define AFS_WORK_GET_AUTH_ID 0x0001 #define AFS_WORK_FLUSH_FCB 0x0002 #define AFS_WORK_UNUSED_3 0x0003 #define AFS_WORK_UNUSED_4 0x0004 diff --git a/src/WINNT/afsrdr/kernel/lib/Include/AFSStructs.h b/src/WINNT/afsrdr/kernel/lib/Include/AFSStructs.h index f881e7509..9251ed355 100644 --- a/src/WINNT/afsrdr/kernel/lib/Include/AFSStructs.h +++ b/src/WINNT/afsrdr/kernel/lib/Include/AFSStructs.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. - * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * Copyright (c) 2009, 2010, 2011, 2015 Your File System, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -666,6 +666,16 @@ typedef struct _AFS_WORK_ITEM } Invalidate; + struct + { + PETHREAD peThread; + + PEPROCESS peProcess; + + LARGE_INTEGER AuthId; + + } GetAuthId; + struct { char Context[ 1]; -- 2.39.5