From 5cb56337b200c2968787310961a5d3c1192a71eb Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Mon, 24 Jan 2005 23:59:30 +0000 Subject: [PATCH] some more parameter checks in IoCreateFile() svn path=/trunk/; revision=13259 --- reactos/include/ddk/iodef.h | 3 +- reactos/ntoskrnl/io/create.c | 132 +++++++++++++++++++++++++---------- 2 files changed, 97 insertions(+), 38 deletions(-) diff --git a/reactos/include/ddk/iodef.h b/reactos/include/ddk/iodef.h index b7de74992f9..31a24cf34cf 100644 --- a/reactos/include/ddk/iodef.h +++ b/reactos/include/ddk/iodef.h @@ -163,7 +163,8 @@ enum /* * IoCreateFile options */ -#define IO_NO_PARAMETER_CHECKING 0x100 +#define IO_NO_PARAMETER_CHECKING 0x0100 +#define IO_CHECK_CREATE_PARAMETERS 0x0200 /* * Possible flags for the device object flags diff --git a/reactos/ntoskrnl/io/create.c b/reactos/ntoskrnl/io/create.c index 8742c41c3fd..f82fd5b7ade 100644 --- a/reactos/ntoskrnl/io/create.c +++ b/reactos/ntoskrnl/io/create.c @@ -337,13 +337,15 @@ IoCreateFile(OUT PHANDLE FileHandle, IN ULONG Options) { PFILE_OBJECT FileObject; - NTSTATUS Status; PIRP Irp; PIO_STACK_LOCATION StackLoc; IO_SECURITY_CONTEXT SecurityContext; - KPROCESSOR_MODE PreviousMode; + KPROCESSOR_MODE AccessMode; HANDLE LocalFileHandle; IO_STATUS_BLOCK LocalIoStatusBlock; + LARGE_INTEGER SafeAllocationSize; + PVOID SystemEaBuffer = NULL; + NTSTATUS Status = STATUS_SUCCESS; DPRINT("IoCreateFile(FileHandle %x, DesiredAccess %x, " "ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n", @@ -357,12 +359,79 @@ IoCreateFile(OUT PHANDLE FileHandle, LocalFileHandle = 0; - PreviousMode = ExGetPreviousMode(); + if(Options & IO_NO_PARAMETER_CHECKING) + AccessMode = KernelMode; + else + AccessMode = ExGetPreviousMode(); + + if(AccessMode != KernelMode) + { + _SEH_TRY + { + ProbeForWrite(FileHandle, + sizeof(HANDLE), + sizeof(ULONG)); + ProbeForWrite(IoStatusBlock, + sizeof(IO_STATUS_BLOCK), + sizeof(ULONG)); + if(AllocationSize != NULL) + { + ProbeForRead(AllocationSize, + sizeof(LARGE_INTEGER), + sizeof(ULONG)); + SafeAllocationSize = *AllocationSize; + } + else + SafeAllocationSize.QuadPart = 0; - Status = ObCreateObject(0 == (Options & IO_NO_PARAMETER_CHECKING) ? PreviousMode : KernelMode, + if(EaBuffer != NULL && EaLength > 0) + { + ProbeForRead(EaBuffer, + EaLength, + sizeof(ULONG)); + + /* marshal EaBuffer */ + SystemEaBuffer = ExAllocatePool(NonPagedPool, + EaLength); + if(SystemEaBuffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + _SEH_LEAVE; + } + + RtlCopyMemory(SystemEaBuffer, + EaBuffer, + EaLength); + } + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + } + else + { + if(AllocationSize != NULL) + SafeAllocationSize = *AllocationSize; + else + SafeAllocationSize.QuadPart = 0; + + if(EaBuffer != NULL && EaLength > 0) + { + SystemEaBuffer = EaBuffer; + } + } + + if(Options & IO_CHECK_CREATE_PARAMETERS) + { + DPRINT1("FIXME: IO_CHECK_CREATE_PARAMETERS not yet supported!\n"); + } + + Status = ObCreateObject(AccessMode, IoFileObjectType, ObjectAttributes, - PreviousMode, + AccessMode, NULL, sizeof(FILE_OBJECT), 0, @@ -426,16 +495,13 @@ IoCreateFile(OUT PHANDLE FileHandle, //trigger FileObject/Event dereferencing Irp->Tail.Overlay.OriginalFileObject = FileObject; - Irp->RequestorMode = PreviousMode; + Irp->RequestorMode = AccessMode; Irp->UserIosb = &LocalIoStatusBlock; - Irp->AssociatedIrp.SystemBuffer = EaBuffer; + Irp->AssociatedIrp.SystemBuffer = SystemEaBuffer; Irp->Tail.Overlay.AuxiliaryBuffer = NULL; Irp->Tail.Overlay.Thread = PsGetCurrentThread(); Irp->UserEvent = &FileObject->Event; - if (AllocationSize) - { - Irp->Overlay.AllocationSize = *AllocationSize; - } + Irp->Overlay.AllocationSize = SafeAllocationSize; /* * Get the stack location for the new @@ -458,7 +524,7 @@ IoCreateFile(OUT PHANDLE FileHandle, StackLoc->Parameters.Create.Options |= (CreateDisposition << 24); StackLoc->Parameters.Create.FileAttributes = (USHORT)FileAttributes; StackLoc->Parameters.Create.ShareAccess = (USHORT)ShareAccess; - StackLoc->Parameters.Create.EaLength = EaLength; + StackLoc->Parameters.Create.EaLength = SystemEaBuffer != NULL ? EaLength : 0; break; case CreateFileTypeNamedPipe: @@ -492,7 +558,7 @@ IoCreateFile(OUT PHANDLE FileHandle, { KeWaitForSingleObject(&FileObject->Event, Executive, - PreviousMode, + AccessMode, FALSE, NULL); Status = LocalIoStatusBlock.Status; @@ -507,32 +573,24 @@ IoCreateFile(OUT PHANDLE FileHandle, } else { - if (KernelMode == PreviousMode || 0 != (Options & IO_NO_PARAMETER_CHECKING)) - { - *FileHandle = LocalFileHandle; - *IoStatusBlock = LocalIoStatusBlock; - } - else - { - _SEH_TRY - { - ProbeForWrite(FileHandle, - sizeof(HANDLE), - sizeof(ULONG)); - *FileHandle = LocalFileHandle; - ProbeForWrite(IoStatusBlock, - sizeof(IO_STATUS_BLOCK), - sizeof(ULONG)); - *IoStatusBlock = LocalIoStatusBlock; - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - } + _SEH_TRY + { + *FileHandle = LocalFileHandle; + *IoStatusBlock = LocalIoStatusBlock; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; } + /* cleanup EABuffer if captured */ + if(AccessMode != KernelMode && SystemEaBuffer != NULL) + { + ExFreePool(SystemEaBuffer); + } + ASSERT_IRQL(PASSIVE_LEVEL); DPRINT("Finished IoCreateFile() (*FileHandle) %x\n", (*FileHandle));