mirror of
https://github.com/reactos/reactos.git
synced 2025-05-16 15:50:24 +00:00
[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 svn path=/trunk/; revision=63436
This commit is contained in:
parent
59af32287d
commit
ce1a5160ec
2 changed files with 162 additions and 29 deletions
|
@ -55,6 +55,8 @@ NtAcceptConnectPort(OUT PHANDLE PortHandle,
|
|||
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 @@ NtAcceptConnectPort(OUT PHANDLE PortHandle,
|
|||
ClientView,
|
||||
ServerView);
|
||||
|
||||
/* Validate the size of the server view */
|
||||
if ((ServerView) && (ServerView->Length != sizeof(PORT_VIEW)))
|
||||
/* Check if the call comes from user mode */
|
||||
if (PreviousMode != KernelMode)
|
||||
{
|
||||
/* Invalid size */
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
/* Enter SEH for probing the parameters */
|
||||
_SEH2_TRY
|
||||
{
|
||||
ProbeForWriteHandle(PortHandle);
|
||||
|
||||
/* Validate the size of the client view */
|
||||
if ((ClientView) && (ClientView->Length != sizeof(REMOTE_PORT_VIEW)))
|
||||
/* 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
|
||||
{
|
||||
/* Invalid size */
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
/* 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 @@ NtAcceptConnectPort(OUT PHANDLE PortHandle,
|
|||
|
||||
/* 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 @@ NtAcceptConnectPort(OUT PHANDLE PortHandle,
|
|||
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 @@ NtAcceptConnectPort(OUT PHANDLE PortHandle,
|
|||
/* 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 @@ NtAcceptConnectPort(OUT PHANDLE PortHandle,
|
|||
goto Cleanup;
|
||||
}
|
||||
|
||||
/* Check if the caller gave a client view */
|
||||
if (ClientView)
|
||||
/* Enter SEH to write back the results */
|
||||
_SEH2_TRY
|
||||
{
|
||||
/* Fill it out */
|
||||
ClientView->ViewBase = ConnectMessage->ClientView.ViewRemoteBase;
|
||||
ClientView->ViewSize = ConnectMessage->ClientView.ViewSize;
|
||||
}
|
||||
/* 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;
|
||||
|
||||
/* Return the handle to user mode */
|
||||
*PortHandle = Handle;
|
||||
LPCTRACE(LPC_COMPLETE_DEBUG,
|
||||
"Handle: %p. Messages: %p/%p. Ports: %p/%p/%p\n",
|
||||
Handle,
|
||||
|
|
|
@ -49,9 +49,44 @@ LpcpCreatePort(OUT PHANDLE PortHandle,
|
|||
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,
|
||||
LpcPortObjectType,
|
||||
|
@ -72,7 +107,7 @@ LpcpCreatePort(OUT PHANDLE PortHandle,
|
|||
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 @@ LpcpCreatePort(OUT PHANDLE PortHandle,
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue