mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 14:53:40 +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;
|
PEPROCESS ClientProcess;
|
||||||
PETHREAD ClientThread;
|
PETHREAD ClientThread;
|
||||||
LARGE_INTEGER SectionOffset;
|
LARGE_INTEGER SectionOffset;
|
||||||
|
CLIENT_ID ClientId;
|
||||||
|
ULONG MessageId;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
LPCTRACE(LPC_COMPLETE_DEBUG,
|
LPCTRACE(LPC_COMPLETE_DEBUG,
|
||||||
"Context: %p. Message: %p. Accept: %lx. Views: %p/%p\n",
|
"Context: %p. Message: %p. Accept: %lx. Views: %p/%p\n",
|
||||||
|
@ -64,22 +66,81 @@ NtAcceptConnectPort(OUT PHANDLE PortHandle,
|
||||||
ClientView,
|
ClientView,
|
||||||
ServerView);
|
ServerView);
|
||||||
|
|
||||||
/* Validate the size of the server view */
|
/* Check if the call comes from user mode */
|
||||||
if ((ServerView) && (ServerView->Length != sizeof(PORT_VIEW)))
|
if (PreviousMode != KernelMode)
|
||||||
{
|
{
|
||||||
/* Invalid size */
|
/* Enter SEH for probing the parameters */
|
||||||
return STATUS_INVALID_PARAMETER;
|
_SEH2_TRY
|
||||||
}
|
{
|
||||||
|
ProbeForWriteHandle(PortHandle);
|
||||||
|
|
||||||
/* Validate the size of the client view */
|
/* Probe the basic ReplyMessage structure */
|
||||||
if ((ClientView) && (ClientView->Length != sizeof(REMOTE_PORT_VIEW)))
|
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 */
|
/* Grab some values */
|
||||||
return STATUS_INVALID_PARAMETER;
|
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 */
|
/* Get the client process and thread */
|
||||||
Status = PsLookupProcessThreadByCid(&ReplyMessage->ClientId,
|
Status = PsLookupProcessThreadByCid(&ClientId,
|
||||||
&ClientProcess,
|
&ClientProcess,
|
||||||
&ClientThread);
|
&ClientThread);
|
||||||
if (!NT_SUCCESS(Status)) return Status;
|
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 */
|
/* Make sure that the client wants a reply, and this is the right one */
|
||||||
if (!(LpcpGetMessageFromThread(ClientThread)) ||
|
if (!(LpcpGetMessageFromThread(ClientThread)) ||
|
||||||
!(ReplyMessage->MessageId) ||
|
!(MessageId) ||
|
||||||
(ClientThread->LpcReplyMessageId != ReplyMessage->MessageId))
|
(ClientThread->LpcReplyMessageId != MessageId))
|
||||||
{
|
{
|
||||||
/* Not the reply asked for, or no reply wanted, fail */
|
/* Not the reply asked for, or no reply wanted, fail */
|
||||||
KeReleaseGuardedMutex(&LpcpLock);
|
KeReleaseGuardedMutex(&LpcpLock);
|
||||||
|
@ -125,8 +186,7 @@ NtAcceptConnectPort(OUT PHANDLE PortHandle,
|
||||||
ConnectMessage->ClientPort = NULL;
|
ConnectMessage->ClientPort = NULL;
|
||||||
KeReleaseGuardedMutex(&LpcpLock);
|
KeReleaseGuardedMutex(&LpcpLock);
|
||||||
|
|
||||||
/* Get the connection information length */
|
/* Check the connection information length */
|
||||||
ConnectionInfoLength = ReplyMessage->u1.s1.DataLength;
|
|
||||||
if (ConnectionInfoLength > ConnectionPort->MaxConnectionInfoLength)
|
if (ConnectionInfoLength > ConnectionPort->MaxConnectionInfoLength)
|
||||||
{
|
{
|
||||||
/* Normalize it since it's too large */
|
/* Normalize it since it's too large */
|
||||||
|
@ -142,10 +202,20 @@ NtAcceptConnectPort(OUT PHANDLE PortHandle,
|
||||||
/* Setup the reply message */
|
/* Setup the reply message */
|
||||||
Message->Request.u2.s2.Type = LPC_REPLY;
|
Message->Request.u2.s2.Type = LPC_REPLY;
|
||||||
Message->Request.u2.s2.DataInfoOffset = 0;
|
Message->Request.u2.s2.DataInfoOffset = 0;
|
||||||
Message->Request.ClientId = ReplyMessage->ClientId;
|
Message->Request.ClientId = ClientId;
|
||||||
Message->Request.MessageId = ReplyMessage->MessageId;
|
Message->Request.MessageId = MessageId;
|
||||||
Message->Request.ClientViewSize = 0;
|
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 */
|
/* At this point, if the caller refused the connection, go to cleanup */
|
||||||
if (!AcceptConnection)
|
if (!AcceptConnection)
|
||||||
|
@ -259,16 +329,30 @@ NtAcceptConnectPort(OUT PHANDLE PortHandle,
|
||||||
goto Cleanup;
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the caller gave a client view */
|
/* Enter SEH to write back the results */
|
||||||
if (ClientView)
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
/* Fill it out */
|
/* Check if the caller gave a client view */
|
||||||
ClientView->ViewBase = ConnectMessage->ClientView.ViewRemoteBase;
|
if (ClientView)
|
||||||
ClientView->ViewSize = ConnectMessage->ClientView.ViewSize;
|
{
|
||||||
}
|
/* 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,
|
LPCTRACE(LPC_COMPLETE_DEBUG,
|
||||||
"Handle: %p. Messages: %p/%p. Ports: %p/%p/%p\n",
|
"Handle: %p. Messages: %p/%p. Ports: %p/%p/%p\n",
|
||||||
Handle,
|
Handle,
|
||||||
|
|
|
@ -49,9 +49,44 @@ LpcpCreatePort(OUT PHANDLE PortHandle,
|
||||||
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
|
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PLPCP_PORT_OBJECT Port;
|
PLPCP_PORT_OBJECT Port;
|
||||||
|
HANDLE Handle;
|
||||||
|
PUNICODE_STRING ObjectName;
|
||||||
|
BOOLEAN NoName;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
LPCTRACE(LPC_CREATE_DEBUG, "Name: %wZ\n", ObjectAttributes->ObjectName);
|
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 */
|
/* Create the Object */
|
||||||
Status = ObCreateObject(PreviousMode,
|
Status = ObCreateObject(PreviousMode,
|
||||||
LpcPortObjectType,
|
LpcPortObjectType,
|
||||||
|
@ -72,7 +107,7 @@ LpcpCreatePort(OUT PHANDLE PortHandle,
|
||||||
InitializeListHead(&Port->LpcReplyChainHead);
|
InitializeListHead(&Port->LpcReplyChainHead);
|
||||||
|
|
||||||
/* Check if we don't have a name */
|
/* Check if we don't have a name */
|
||||||
if (!ObjectAttributes->ObjectName->Buffer)
|
if (NoName)
|
||||||
{
|
{
|
||||||
/* Set up for an unconnected port */
|
/* Set up for an unconnected port */
|
||||||
Port->Flags = LPCP_UNCONNECTED_PORT;
|
Port->Flags = LPCP_UNCONNECTED_PORT;
|
||||||
|
@ -140,10 +175,24 @@ LpcpCreatePort(OUT PHANDLE PortHandle,
|
||||||
PORT_ALL_ACCESS,
|
PORT_ALL_ACCESS,
|
||||||
0,
|
0,
|
||||||
NULL,
|
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 */
|
/* 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;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue