sys: rename: capture correct security context

This commit is contained in:
Bill Zissimopoulos 2016-12-12 13:20:42 -08:00
parent 4b024ebe74
commit 6de998ff98

View File

@ -122,7 +122,7 @@ enum
//RequestFileNode = 0, //RequestFileNode = 0,
RequestDeviceObject = 1, RequestDeviceObject = 1,
/* Rename */ /* Rename */
RequestAccessToken = 2, RequestSubjectContextOrAccessToken = 2,
RequestProcess = 3, RequestProcess = 3,
}; };
@ -1153,6 +1153,7 @@ static NTSTATUS FspFsvolSetRenameInformation(
NTSTATUS Result; NTSTATUS Result;
PFILE_OBJECT FileObject = IrpSp->FileObject; PFILE_OBJECT FileObject = IrpSp->FileObject;
PFILE_OBJECT TargetFileObject = IrpSp->Parameters.SetFile.FileObject; PFILE_OBJECT TargetFileObject = IrpSp->Parameters.SetFile.FileObject;
BOOLEAN ReplaceIfExists = IrpSp->Parameters.SetFile.ReplaceIfExists;
PFILE_RENAME_INFORMATION Info = (PFILE_RENAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer; PFILE_RENAME_INFORMATION Info = (PFILE_RENAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
ULONG Length = IrpSp->Parameters.SetFile.Length; ULONG Length = IrpSp->Parameters.SetFile.Length;
FSP_FILE_NODE *FileNode = FileObject->FsContext; FSP_FILE_NODE *FileNode = FileObject->FsContext;
@ -1164,6 +1165,7 @@ static NTSTATUS FspFsvolSetRenameInformation(
UNICODE_STRING NewFileName; UNICODE_STRING NewFileName;
PUINT8 NewFileNameBuffer; PUINT8 NewFileNameBuffer;
BOOLEAN AppendBackslash; BOOLEAN AppendBackslash;
PSECURITY_SUBJECT_CONTEXT SecuritySubjectContext = 0;
ASSERT(FileNode == FileDesc->FileNode); ASSERT(FileNode == FileDesc->FileNode);
@ -1296,10 +1298,23 @@ retry:
} }
} }
/* capture the security context */
if (ReplaceIfExists)
{
SecuritySubjectContext = FspAlloc(sizeof *SecuritySubjectContext);
if (0 == SecuritySubjectContext)
{
Result = STATUS_INSUFFICIENT_RESOURCES;
goto unlock_exit;
}
SeCaptureSubjectContext(SecuritySubjectContext);
}
FspFsvolDeviceFileRenameSetOwner(FsvolDeviceObject, Request); FspFsvolDeviceFileRenameSetOwner(FsvolDeviceObject, Request);
FspFileNodeSetOwner(FileNode, Full, Request); FspFileNodeSetOwner(FileNode, Full, Request);
FspIopRequestContext(Request, RequestFileNode) = FileNode; FspIopRequestContext(Request, RequestFileNode) = FileNode;
FspIopRequestContext(Request, RequestDeviceObject) = FsvolDeviceObject; FspIopRequestContext(Request, RequestDeviceObject) = FsvolDeviceObject;
FspIopRequestContext(Request, RequestSubjectContextOrAccessToken) = SecuritySubjectContext;
return FSP_STATUS_IOQ_POST; return FSP_STATUS_IOQ_POST;
@ -1491,32 +1506,36 @@ NTSTATUS FspFsvolSetInformationPrepare(
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
if (FileRenameInformation != IrpSp->Parameters.SetFile.FileInformationClass || if (FileRenameInformation != IrpSp->Parameters.SetFile.FileInformationClass ||
!IrpSp->Parameters.SetFile.ReplaceIfExists) 0 == FspIopRequestContext(Request, RequestSubjectContextOrAccessToken))
return STATUS_SUCCESS; return STATUS_SUCCESS;
NTSTATUS Result; NTSTATUS Result;
SECURITY_SUBJECT_CONTEXT SecuritySubjectContext; PSECURITY_SUBJECT_CONTEXT SecuritySubjectContext;
SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService; SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
SECURITY_CLIENT_CONTEXT SecurityClientContext; SECURITY_CLIENT_CONTEXT SecurityClientContext;
HANDLE UserModeAccessToken; HANDLE UserModeAccessToken;
PEPROCESS Process; PEPROCESS Process;
SecuritySubjectContext = FspIopRequestContext(Request, RequestSubjectContextOrAccessToken);
/* duplicate the subject context access token into an impersonation token */ /* duplicate the subject context access token into an impersonation token */
SecurityQualityOfService.Length = sizeof SecurityQualityOfService; SecurityQualityOfService.Length = sizeof SecurityQualityOfService;
SecurityQualityOfService.ImpersonationLevel = SecurityIdentification; SecurityQualityOfService.ImpersonationLevel = SecurityIdentification;
SecurityQualityOfService.ContextTrackingMode = SECURITY_STATIC_TRACKING; SecurityQualityOfService.ContextTrackingMode = SECURITY_STATIC_TRACKING;
SecurityQualityOfService.EffectiveOnly = FALSE; SecurityQualityOfService.EffectiveOnly = FALSE;
SeCaptureSubjectContext(&SecuritySubjectContext); SeLockSubjectContext(SecuritySubjectContext);
SeLockSubjectContext(&SecuritySubjectContext); Result = SeCreateClientSecurityFromSubjectContext(SecuritySubjectContext,
Result = SeCreateClientSecurityFromSubjectContext(&SecuritySubjectContext,
&SecurityQualityOfService, FALSE, &SecurityClientContext); &SecurityQualityOfService, FALSE, &SecurityClientContext);
SeUnlockSubjectContext(&SecuritySubjectContext); SeUnlockSubjectContext(SecuritySubjectContext);
SeReleaseSubjectContext(&SecuritySubjectContext);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return Result; return Result;
ASSERT(TokenImpersonation == SeTokenType(SecurityClientContext.ClientToken)); ASSERT(TokenImpersonation == SeTokenType(SecurityClientContext.ClientToken));
SeReleaseSubjectContext(SecuritySubjectContext);
FspFree(SecuritySubjectContext);
FspIopRequestContext(Request, RequestSubjectContextOrAccessToken) = 0;
/* get a user-mode handle to the impersonation token */ /* get a user-mode handle to the impersonation token */
Result = ObOpenObjectByPointer(SecurityClientContext.ClientToken, Result = ObOpenObjectByPointer(SecurityClientContext.ClientToken,
0, 0, TOKEN_QUERY, *SeTokenObjectType, UserMode, &UserModeAccessToken); 0, 0, TOKEN_QUERY, *SeTokenObjectType, UserMode, &UserModeAccessToken);
@ -1529,7 +1548,7 @@ NTSTATUS FspFsvolSetInformationPrepare(
ObReferenceObject(Process); ObReferenceObject(Process);
/* send the user-mode handle to the user-mode file system */ /* send the user-mode handle to the user-mode file system */
FspIopRequestContext(Request, RequestAccessToken) = UserModeAccessToken; FspIopRequestContext(Request, RequestSubjectContextOrAccessToken) = UserModeAccessToken;
FspIopRequestContext(Request, RequestProcess) = Process; FspIopRequestContext(Request, RequestProcess) = Process;
Request->Req.SetInformation.Info.Rename.AccessToken = (UINT_PTR)UserModeAccessToken; Request->Req.SetInformation.Info.Rename.AccessToken = (UINT_PTR)UserModeAccessToken;
@ -1595,7 +1614,7 @@ static VOID FspFsvolSetInformationRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, P
FSP_FILE_NODE *FileNode = Context[RequestFileNode]; FSP_FILE_NODE *FileNode = Context[RequestFileNode];
PDEVICE_OBJECT FsvolDeviceObject = Context[RequestDeviceObject]; PDEVICE_OBJECT FsvolDeviceObject = Context[RequestDeviceObject];
HANDLE AccessToken = Context[RequestAccessToken]; PVOID SubjectContextOrAccessToken = Context[RequestSubjectContextOrAccessToken];
PEPROCESS Process = Context[RequestProcess]; PEPROCESS Process = Context[RequestProcess];
if (0 != FileNode) if (0 != FileNode)
@ -1604,8 +1623,9 @@ static VOID FspFsvolSetInformationRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, P
if (0 != FsvolDeviceObject) if (0 != FsvolDeviceObject)
FspFsvolDeviceFileRenameReleaseOwner(FsvolDeviceObject, Request); FspFsvolDeviceFileRenameReleaseOwner(FsvolDeviceObject, Request);
if (0 != AccessToken) if (0 != SubjectContextOrAccessToken && 0 != Process)
{ {
HANDLE AccessToken = SubjectContextOrAccessToken;
KAPC_STATE ApcState; KAPC_STATE ApcState;
BOOLEAN Attach; BOOLEAN Attach;
@ -1627,6 +1647,13 @@ static VOID FspFsvolSetInformationRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, P
ObDereferenceObject(Process); ObDereferenceObject(Process);
} }
else if (0 != SubjectContextOrAccessToken)
{
PSECURITY_SUBJECT_CONTEXT SecuritySubjectContext = SubjectContextOrAccessToken;
SeReleaseSubjectContext(SecuritySubjectContext);
FspFree(SecuritySubjectContext);
}
} }
NTSTATUS FspQueryInformation( NTSTATUS FspQueryInformation(