Author: tkreuzer
Date: Sun May 25 10:21:08 2014
New Revision: 63436
URL:
http://svn.reactos.org/svn/reactos?rev=63436&view=rev
Log:
[NTOSKRNL]
Add SEH to LpcpCreatePort and NtAcceptConnectPort. Based on patches by Aleksander
Andrejevic ([TheFlash])
CORE-7156 #resolve
CORE-7371 #comment SEH still missing in NtSecureConnectPort, NtReplyPort,
NtReplyWaitReceivePortEx, NtRequestPort
Modified:
trunk/reactos/ntoskrnl/lpc/complete.c
trunk/reactos/ntoskrnl/lpc/create.c
Modified: trunk/reactos/ntoskrnl/lpc/complete.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/lpc/complete.c?re…
==============================================================================
--- trunk/reactos/ntoskrnl/lpc/complete.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/lpc/complete.c [iso-8859-1] Sun May 25 10:21:08 2014
@@ -55,6 +55,8 @@
PEPROCESS ClientProcess;
PETHREAD ClientThread;
LARGE_INTEGER SectionOffset;
+ CLIENT_ID ClientId;
+ ULONG MessageId;
PAGED_CODE();
LPCTRACE(LPC_COMPLETE_DEBUG,
"Context: %p. Message: %p. Accept: %lx. Views: %p/%p\n",
@@ -64,22 +66,81 @@
ClientView,
ServerView);
- /* Validate the size of the server view */
- if ((ServerView) && (ServerView->Length != sizeof(PORT_VIEW)))
- {
- /* Invalid size */
- return STATUS_INVALID_PARAMETER;
- }
-
- /* Validate the size of the client view */
- if ((ClientView) && (ClientView->Length != sizeof(REMOTE_PORT_VIEW)))
- {
- /* Invalid size */
- return STATUS_INVALID_PARAMETER;
+ /* Check if the call comes from user mode */
+ if (PreviousMode != KernelMode)
+ {
+ /* Enter SEH for probing the parameters */
+ _SEH2_TRY
+ {
+ ProbeForWriteHandle(PortHandle);
+
+ /* Probe the basic ReplyMessage structure */
+ ProbeForRead(ReplyMessage, sizeof(PORT_MESSAGE), sizeof(ULONG));
+
+ /* Grab some values */
+ ClientId = ReplyMessage->ClientId;
+ MessageId = ReplyMessage->MessageId;
+ ConnectionInfoLength = ReplyMessage->u1.s1.DataLength;
+
+ /* Probe the connection info */
+ ProbeForRead(ReplyMessage + 1, ConnectionInfoLength, 1);
+
+ /* The following parameters are optional */
+ if (ServerView != NULL)
+ {
+ ProbeForWrite(ServerView, sizeof(PORT_VIEW), sizeof(ULONG));
+
+ /* Validate the size of the server view */
+ if (ServerView->Length != sizeof(PORT_VIEW))
+ {
+ /* Invalid size */
+ _SEH2_YIELD(return STATUS_INVALID_PARAMETER);
+ }
+ }
+
+ if (ClientView != NULL)
+ {
+ ProbeForWrite(ClientView, sizeof(REMOTE_PORT_VIEW), sizeof(ULONG));
+
+ /* Validate the size of the client view */
+ if (ClientView->Length != sizeof(REMOTE_PORT_VIEW))
+ {
+ /* Invalid size */
+ _SEH2_YIELD(return STATUS_INVALID_PARAMETER);
+ }
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* There was an exception, return the exception code */
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
+ }
+ else
+ {
+ /* Grab some values */
+ ClientId = ReplyMessage->ClientId;
+ MessageId = ReplyMessage->MessageId;
+ ConnectionInfoLength = ReplyMessage->u1.s1.DataLength;
+
+ /* Validate the size of the server view */
+ if ((ServerView) && (ServerView->Length != sizeof(PORT_VIEW)))
+ {
+ /* Invalid size */
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Validate the size of the client view */
+ if ((ClientView) && (ClientView->Length != sizeof(REMOTE_PORT_VIEW)))
+ {
+ /* Invalid size */
+ return STATUS_INVALID_PARAMETER;
+ }
}
/* Get the client process and thread */
- Status = PsLookupProcessThreadByCid(&ReplyMessage->ClientId,
+ Status = PsLookupProcessThreadByCid(&ClientId,
&ClientProcess,
&ClientThread);
if (!NT_SUCCESS(Status)) return Status;
@@ -89,8 +150,8 @@
/* Make sure that the client wants a reply, and this is the right one */
if (!(LpcpGetMessageFromThread(ClientThread)) ||
- !(ReplyMessage->MessageId) ||
- (ClientThread->LpcReplyMessageId != ReplyMessage->MessageId))
+ !(MessageId) ||
+ (ClientThread->LpcReplyMessageId != MessageId))
{
/* Not the reply asked for, or no reply wanted, fail */
KeReleaseGuardedMutex(&LpcpLock);
@@ -125,8 +186,7 @@
ConnectMessage->ClientPort = NULL;
KeReleaseGuardedMutex(&LpcpLock);
- /* Get the connection information length */
- ConnectionInfoLength = ReplyMessage->u1.s1.DataLength;
+ /* Check the connection information length */
if (ConnectionInfoLength > ConnectionPort->MaxConnectionInfoLength)
{
/* Normalize it since it's too large */
@@ -142,16 +202,26 @@
/* Setup the reply message */
Message->Request.u2.s2.Type = LPC_REPLY;
Message->Request.u2.s2.DataInfoOffset = 0;
- Message->Request.ClientId = ReplyMessage->ClientId;
- Message->Request.MessageId = ReplyMessage->MessageId;
+ Message->Request.ClientId = ClientId;
+ Message->Request.MessageId = MessageId;
Message->Request.ClientViewSize = 0;
- RtlCopyMemory(ConnectMessage + 1, ReplyMessage + 1, ConnectionInfoLength);
+
+ _SEH2_TRY
+ {
+ RtlCopyMemory(ConnectMessage + 1, ReplyMessage + 1, ConnectionInfoLength);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ _SEH2_YIELD(goto Cleanup);
+ }
+ _SEH2_END;
/* At this point, if the caller refused the connection, go to cleanup */
if (!AcceptConnection)
{
DPRINT1("LPC connection was refused\n");
- goto Cleanup;
+ goto Cleanup;
}
/* Otherwise, create the actual port */
@@ -259,16 +329,30 @@
goto Cleanup;
}
- /* Check if the caller gave a client view */
- if (ClientView)
- {
- /* Fill it out */
- ClientView->ViewBase = ConnectMessage->ClientView.ViewRemoteBase;
- ClientView->ViewSize = ConnectMessage->ClientView.ViewSize;
- }
-
- /* Return the handle to user mode */
- *PortHandle = Handle;
+ /* Enter SEH to write back the results */
+ _SEH2_TRY
+ {
+ /* Check if the caller gave a client view */
+ if (ClientView)
+ {
+ /* Fill it out */
+ ClientView->ViewBase = ConnectMessage->ClientView.ViewRemoteBase;
+ ClientView->ViewSize = ConnectMessage->ClientView.ViewSize;
+ }
+
+ /* Return the handle to user mode */
+ *PortHandle = Handle;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Cleanup and return the exception code */
+ ObCloseHandle(Handle, UserMode);
+ ObDereferenceObject(ServerPort);
+ Status = _SEH2_GetExceptionCode();
+ _SEH2_YIELD(goto Cleanup);
+ }
+ _SEH2_END;
+
LPCTRACE(LPC_COMPLETE_DEBUG,
"Handle: %p. Messages: %p/%p. Ports: %p/%p/%p\n",
Handle,
Modified: trunk/reactos/ntoskrnl/lpc/create.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/lpc/create.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/lpc/create.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/lpc/create.c [iso-8859-1] Sun May 25 10:21:08 2014
@@ -49,8 +49,43 @@
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
NTSTATUS Status;
PLPCP_PORT_OBJECT Port;
+ HANDLE Handle;
+ PUNICODE_STRING ObjectName;
+ BOOLEAN NoName;
PAGED_CODE();
LPCTRACE(LPC_CREATE_DEBUG, "Name: %wZ\n",
ObjectAttributes->ObjectName);
+
+ /* Check if the call comes from user mode */
+ if (PreviousMode != KernelMode)
+ {
+ _SEH2_TRY
+ {
+ /* Probe the PortHandle */
+ ProbeForWriteHandle(PortHandle);
+
+ /* Probe the ObjectAttributes */
+ ProbeForRead(ObjectAttributes, sizeof(OBJECT_ATTRIBUTES), sizeof(ULONG));
+
+ /* Get the object name and probe the unicode string */
+ ObjectName = ObjectAttributes->ObjectName;
+ ProbeForRead(ObjectName, sizeof(UNICODE_STRING), 1);
+
+ /* Check if we have no name */
+ NoName = (ObjectName->Buffer == NULL) || (ObjectName->Length == 0);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Return the exception code */
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
+ }
+ else
+ {
+ /* Check if we have no name */
+ NoName = (ObjectAttributes->ObjectName->Buffer == NULL) ||
+ (ObjectAttributes->ObjectName->Length == 0);
+ }
/* Create the Object */
Status = ObCreateObject(PreviousMode,
@@ -72,7 +107,7 @@
InitializeListHead(&Port->LpcReplyChainHead);
/* Check if we don't have a name */
- if (!ObjectAttributes->ObjectName->Buffer)
+ if (NoName)
{
/* Set up for an unconnected port */
Port->Flags = LPCP_UNCONNECTED_PORT;
@@ -140,10 +175,24 @@
PORT_ALL_ACCESS,
0,
NULL,
- PortHandle);
+ &Handle);
+ if (NT_SUCCESS(Status))
+ {
+ _SEH2_TRY
+ {
+ /* Write back the handle, pointer was already probed */
+ *PortHandle = Handle;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ ObCloseHandle(Handle, UserMode);
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+ }
/* Return success or the error */
- LPCTRACE(LPC_CREATE_DEBUG, "Port: %p. Handle: %p\n", Port, *PortHandle);
+ LPCTRACE(LPC_CREATE_DEBUG, "Port: %p. Handle: %p\n", Port, Handle);
return Status;
}