[ros-diffs] [navaraf] 33428: SEH protect NtReplyWaitReceivePortEx and fix one instance of message type checking to correctly account for kernel LPC messages.

navaraf at svn.reactos.org navaraf at svn.reactos.org
Sun May 11 11:39:27 CEST 2008


Author: navaraf
Date: Sun May 11 04:39:26 2008
New Revision: 33428

URL: http://svn.reactos.org/svn/reactos?rev=33428&view=rev
Log:
SEH protect NtReplyWaitReceivePortEx and fix one instance of message type checking to correctly account for kernel LPC messages.

Modified:
    trunk/reactos/ntoskrnl/lpc/reply.c

Modified: trunk/reactos/ntoskrnl/lpc/reply.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/lpc/reply.c?rev=33428&r1=33427&r2=33428&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/lpc/reply.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/lpc/reply.c [iso-8859-1] Sun May 11 04:39:26 2008
@@ -160,11 +160,14 @@
 {
     PLPCP_PORT_OBJECT Port, ReceivePort, ConnectionPort = NULL;
     KPROCESSOR_MODE PreviousMode = KeGetPreviousMode(), WaitMode = PreviousMode;
-    NTSTATUS Status;
+    NTSTATUS Status = STATUS_SUCCESS;
     PLPCP_MESSAGE Message;
     PETHREAD Thread = PsGetCurrentThread(), WakeupThread;
     PLPCP_CONNECTION_MESSAGE ConnectMessage;
     ULONG ConnectionInfoLength;
+    PORT_MESSAGE CapturedReplyMessage;
+    LARGE_INTEGER CapturedTimeout;
+
     PAGED_CODE();
     LPCTRACE(LPC_REPLY_DEBUG,
              "Handle: %lx. Messages: %p/%p. Context: %p\n",
@@ -173,8 +176,42 @@
              ReceiveMessage,
              PortContext);
 
-    /* If this is a system thread, then let it page out its stack */
-    if (Thread->SystemThread) WaitMode = UserMode;
+    if (KeGetPreviousMode() == UserMode)
+    {
+        _SEH_TRY
+        {
+            if (ReplyMessage != NULL)
+            {
+                ProbeForRead(ReplyMessage, sizeof(PORT_MESSAGE), sizeof(ULONG));
+                RtlCopyMemory(&CapturedReplyMessage, ReplyMessage, sizeof(PORT_MESSAGE));
+                ReplyMessage = &CapturedReplyMessage;
+            }
+
+            if (Timeout != NULL)
+            {
+                ProbeForReadLargeInteger(Timeout);
+                RtlCopyMemory(&CapturedTimeout, Timeout, sizeof(LARGE_INTEGER));
+                Timeout = &CapturedTimeout;
+            }
+
+            if (PortContext != NULL)
+                ProbeForWritePointer(PortContext);
+        }
+        _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+        {
+            Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+
+        /* Bail out if pointer was invalid */
+        if (!NT_SUCCESS(Status))
+            return Status;
+    }
+    else
+    {
+        /* If this is a system thread, then let it page out its stack */
+        if (Thread->SystemThread) WaitMode = UserMode;
+    }
 
     /* Check if caller has a reply message */
     if (ReplyMessage)
@@ -388,68 +425,76 @@
     Thread->LpcReceivedMessageId = Message->Request.MessageId;
     Thread->LpcReceivedMsgIdValid = TRUE;
 
-    /* Check if this was a connection request */
-    if (LpcpGetMessageType(&Message->Request) == LPC_CONNECTION_REQUEST)
-    {
-        /* Get the connection message */
-        ConnectMessage = (PLPCP_CONNECTION_MESSAGE)(Message + 1);
-        LPCTRACE(LPC_REPLY_DEBUG,
-                 "Request Messages: %p/%p\n",
-                 Message,
-                 ConnectMessage);
-
-        /* Get its length */
-        ConnectionInfoLength = Message->Request.u1.s1.DataLength -
-                               sizeof(LPCP_CONNECTION_MESSAGE);
-
-        /* Return it as the receive message */
-        *ReceiveMessage = Message->Request;
-
-        /* Clear our stack variable so the message doesn't get freed */
-        Message = NULL;
-
-        /* Setup the receive message */
-        ReceiveMessage->u1.s1.TotalLength = (CSHORT)(sizeof(LPCP_MESSAGE) +
-                                                     ConnectionInfoLength);
-        ReceiveMessage->u1.s1.DataLength = (CSHORT)ConnectionInfoLength;
-        RtlCopyMemory(ReceiveMessage + 1,
-                      ConnectMessage + 1,
-                      ConnectionInfoLength);
-
-        /* Clear the port context if the caller requested one */
-        if (PortContext) *PortContext = NULL;
-    }
-    else if (Message->Request.u2.s2.Type != LPC_REPLY)
-    {
-        /* Otherwise, this is a new message or event */
-        LPCTRACE(LPC_REPLY_DEBUG,
-                 "Non-Reply Messages: %p/%p\n",
-                 &Message->Request,
-                 (&Message->Request) + 1);
-
-        /* Copy it */
-        LpcpMoveMessage(ReceiveMessage,
-                        &Message->Request,
-                        (&Message->Request) + 1,
-                        0,
-                        NULL);
-
-        /* Return its context */
-        if (PortContext) *PortContext = Message->PortContext;
-
-        /* And check if it has data information */
-        if (Message->Request.u2.s2.DataInfoOffset)
-        {
-            /* It does, save it, and don't free the message below */
-            LpcpSaveDataInfoMessage(Port, Message, 1);
+    _SEH_TRY
+    {
+        /* Check if this was a connection request */
+        if (LpcpGetMessageType(&Message->Request) == LPC_CONNECTION_REQUEST)
+        {
+            /* Get the connection message */
+            ConnectMessage = (PLPCP_CONNECTION_MESSAGE)(Message + 1);
+            LPCTRACE(LPC_REPLY_DEBUG,
+                     "Request Messages: %p/%p\n",
+                     Message,
+                     ConnectMessage);
+
+            /* Get its length */
+            ConnectionInfoLength = Message->Request.u1.s1.DataLength -
+                                   sizeof(LPCP_CONNECTION_MESSAGE);
+
+            /* Return it as the receive message */
+            *ReceiveMessage = Message->Request;
+
+            /* Clear our stack variable so the message doesn't get freed */
             Message = NULL;
-        }
-    }
-    else
-    {
-        /* This is a reply message, should never happen! */
-        ASSERT(FALSE);
-    }
+
+            /* Setup the receive message */
+            ReceiveMessage->u1.s1.TotalLength = (CSHORT)(sizeof(LPCP_MESSAGE) +
+                                                         ConnectionInfoLength);
+            ReceiveMessage->u1.s1.DataLength = (CSHORT)ConnectionInfoLength;
+            RtlCopyMemory(ReceiveMessage + 1,
+                          ConnectMessage + 1,
+                          ConnectionInfoLength);
+
+            /* Clear the port context if the caller requested one */
+            if (PortContext) *PortContext = NULL;
+        }
+        else if (LpcpGetMessageType(&Message->Request) != LPC_REPLY)
+        {
+            /* Otherwise, this is a new message or event */
+            LPCTRACE(LPC_REPLY_DEBUG,
+                     "Non-Reply Messages: %p/%p\n",
+                     &Message->Request,
+                     (&Message->Request) + 1);
+
+            /* Copy it */
+            LpcpMoveMessage(ReceiveMessage,
+                            &Message->Request,
+                            (&Message->Request) + 1,
+                            0,
+                            NULL);
+
+            /* Return its context */
+            if (PortContext) *PortContext = Message->PortContext;
+
+            /* And check if it has data information */
+            if (Message->Request.u2.s2.DataInfoOffset)
+            {
+                /* It does, save it, and don't free the message below */
+                LpcpSaveDataInfoMessage(Port, Message, 1);
+                Message = NULL;
+            }
+        }
+        else
+        {
+            /* This is a reply message, should never happen! */
+            ASSERT(FALSE);
+        }
+    }
+    _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+    {
+        Status = _SEH_GetExceptionCode();
+    }
+    _SEH_END;
 
     /* Check if we have a message pointer here */
     if (Message)



More information about the Ros-diffs mailing list