mirror of
https://github.com/reactos/reactos.git
synced 2024-10-06 09:24:11 +00:00
[NtUser]
- This fixes use after free linking in the message system. See CORE-9173. Dedicated to Thomas Faber. svn path=/trunk/; revision=66309
This commit is contained in:
parent
b4899bb982
commit
2ff860c8f1
|
@ -789,8 +789,7 @@ co_MsqDispatchOneSentMessage(PTHREADINFO pti)
|
||||||
|
|
||||||
/* insert it to the list of messages that are currently dispatched by this
|
/* insert it to the list of messages that are currently dispatched by this
|
||||||
message queue */
|
message queue */
|
||||||
InsertTailList(&pti->LocalDispatchingMessagesHead,
|
InsertTailList(&pti->LocalDispatchingMessagesHead, &Message->ListEntry);
|
||||||
&Message->ListEntry);
|
|
||||||
|
|
||||||
ClearMsgBitsMask(pti, Message->QS_Flags);
|
ClearMsgBitsMask(pti, Message->QS_Flags);
|
||||||
|
|
||||||
|
@ -866,7 +865,7 @@ co_MsqDispatchOneSentMessage(PTHREADINFO pti)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove the message from the dispatching list if needed, so lock the sender's message queue */
|
/* remove the message from the dispatching list if needed, so lock the sender's message queue */
|
||||||
if (Message->ptiSender)
|
if (Message->ptiSender && !(Message->ptiSender->TIF_flags & TIF_INCLEANUP))
|
||||||
{
|
{
|
||||||
if (Message->DispatchingListEntry.Flink != NULL)
|
if (Message->DispatchingListEntry.Flink != NULL)
|
||||||
{
|
{
|
||||||
|
@ -953,8 +952,8 @@ MsqRemoveWindowMessagesFromQueue(PWND Window)
|
||||||
ListHead = &pti->SentMessagesListHead;
|
ListHead = &pti->SentMessagesListHead;
|
||||||
while (CurrentEntry != ListHead)
|
while (CurrentEntry != ListHead)
|
||||||
{
|
{
|
||||||
SentMessage = CONTAINING_RECORD(CurrentEntry, USER_SENT_MESSAGE,
|
SentMessage = CONTAINING_RECORD(CurrentEntry, USER_SENT_MESSAGE, ListEntry);
|
||||||
ListEntry);
|
|
||||||
if(SentMessage->Msg.hwnd == Window->head.h)
|
if(SentMessage->Msg.hwnd == Window->head.h)
|
||||||
{
|
{
|
||||||
TRACE("Notify the sender and remove a message from the queue that had not been dispatched\n");
|
TRACE("Notify the sender and remove a message from the queue that had not been dispatched\n");
|
||||||
|
@ -1187,6 +1186,7 @@ co_MsqSendMessage(PTHREADINFO ptirec,
|
||||||
Message->CompletionEvent = NULL;
|
Message->CompletionEvent = NULL;
|
||||||
Message->Result = NULL;
|
Message->Result = NULL;
|
||||||
RemoveEntryList(&Message->ListEntry);
|
RemoveEntryList(&Message->ListEntry);
|
||||||
|
RemoveEntryList(&Message->DispatchingListEntry);
|
||||||
ClearMsgBitsMask(ptirec, Message->QS_Flags);
|
ClearMsgBitsMask(ptirec, Message->QS_Flags);
|
||||||
ExFreePoolWithTag(Message, TAG_USRMSG);
|
ExFreePoolWithTag(Message, TAG_USRMSG);
|
||||||
break;
|
break;
|
||||||
|
@ -1194,29 +1194,7 @@ co_MsqSendMessage(PTHREADINFO ptirec,
|
||||||
Entry = Entry->Flink;
|
Entry = Entry->Flink;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove from the local dispatching list so the other thread knows,
|
|
||||||
it can't pass a result and it must not set the completion event anymore */
|
|
||||||
Entry = pti->DispatchingMessagesHead.Flink;
|
|
||||||
while (Entry != &pti->DispatchingMessagesHead)
|
|
||||||
{
|
|
||||||
if ((PUSER_SENT_MESSAGE) CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, DispatchingListEntry)
|
|
||||||
== Message)
|
|
||||||
{
|
|
||||||
/* We can access Message here, it's secure because the sender's message is locked
|
|
||||||
and the message has definitely not yet been destroyed, otherwise it would
|
|
||||||
have been removed from this list by the dispatching routine right after
|
|
||||||
dispatching the message */
|
|
||||||
Message->CompletionEvent = NULL;
|
|
||||||
Message->Result = NULL;
|
|
||||||
RemoveEntryList(&Message->DispatchingListEntry);
|
|
||||||
Message->DispatchingListEntry.Flink = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Entry = Entry->Flink;
|
|
||||||
}
|
|
||||||
|
|
||||||
TRACE("MsqSendMessage (blocked) timed out 1 Status %p\n",WaitStatus);
|
TRACE("MsqSendMessage (blocked) timed out 1 Status %p\n",WaitStatus);
|
||||||
|
|
||||||
}
|
}
|
||||||
// Receiving thread passed on and left us hanging with issues still pending.
|
// Receiving thread passed on and left us hanging with issues still pending.
|
||||||
if ( WaitStatus == STATUS_WAIT_1 )
|
if ( WaitStatus == STATUS_WAIT_1 )
|
||||||
|
@ -1272,6 +1250,7 @@ co_MsqSendMessage(PTHREADINFO ptirec,
|
||||||
Message->CompletionEvent = NULL;
|
Message->CompletionEvent = NULL;
|
||||||
Message->Result = NULL;
|
Message->Result = NULL;
|
||||||
RemoveEntryList(&Message->ListEntry);
|
RemoveEntryList(&Message->ListEntry);
|
||||||
|
RemoveEntryList(&Message->DispatchingListEntry);
|
||||||
ClearMsgBitsMask(ptirec, Message->QS_Flags);
|
ClearMsgBitsMask(ptirec, Message->QS_Flags);
|
||||||
ExFreePoolWithTag(Message, TAG_USRMSG);
|
ExFreePoolWithTag(Message, TAG_USRMSG);
|
||||||
break;
|
break;
|
||||||
|
@ -1279,27 +1258,6 @@ co_MsqSendMessage(PTHREADINFO ptirec,
|
||||||
Entry = Entry->Flink;
|
Entry = Entry->Flink;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove from the local dispatching list so the other thread knows,
|
|
||||||
it can't pass a result and it must not set the completion event anymore */
|
|
||||||
Entry = pti->DispatchingMessagesHead.Flink;
|
|
||||||
while (Entry != &pti->DispatchingMessagesHead)
|
|
||||||
{
|
|
||||||
if ((PUSER_SENT_MESSAGE) CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, DispatchingListEntry)
|
|
||||||
== Message)
|
|
||||||
{
|
|
||||||
/* We can access Message here, it's secure because the sender's message is locked
|
|
||||||
and the message has definitely not yet been destroyed, otherwise it would
|
|
||||||
have been removed from this list by the dispatching routine right after
|
|
||||||
dispatching the message */
|
|
||||||
Message->CompletionEvent = NULL;
|
|
||||||
Message->Result = NULL;
|
|
||||||
RemoveEntryList(&Message->DispatchingListEntry);
|
|
||||||
Message->DispatchingListEntry.Flink = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Entry = Entry->Flink;
|
|
||||||
}
|
|
||||||
|
|
||||||
TRACE("MsqSendMessage timed out 2 Status %p\n",WaitStatus);
|
TRACE("MsqSendMessage timed out 2 Status %p\n",WaitStatus);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -1375,12 +1333,7 @@ MsqPostMessage(PTHREADINFO pti,
|
||||||
|
|
||||||
MessageQueue = pti->MessageQueue;
|
MessageQueue = pti->MessageQueue;
|
||||||
|
|
||||||
if (dwQEvent)
|
if (!HardwareMessage)
|
||||||
{
|
|
||||||
ERR("Post Msg; System Qeued Event Message!\n");
|
|
||||||
InsertHeadList(&pti->PostedMessagesListHead, &Message->ListEntry);
|
|
||||||
}
|
|
||||||
else if (!HardwareMessage)
|
|
||||||
{
|
{
|
||||||
InsertTailList(&pti->PostedMessagesListHead, &Message->ListEntry);
|
InsertTailList(&pti->PostedMessagesListHead, &Message->ListEntry);
|
||||||
}
|
}
|
||||||
|
@ -2122,8 +2075,7 @@ MsqCleanupThreadMsgs(PTHREADINFO pti)
|
||||||
while (!IsListEmpty(&pti->PostedMessagesListHead))
|
while (!IsListEmpty(&pti->PostedMessagesListHead))
|
||||||
{
|
{
|
||||||
CurrentEntry = RemoveHeadList(&pti->PostedMessagesListHead);
|
CurrentEntry = RemoveHeadList(&pti->PostedMessagesListHead);
|
||||||
CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE,
|
CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE, ListEntry);
|
||||||
ListEntry);
|
|
||||||
MsqDestroyMessage(CurrentMessage);
|
MsqDestroyMessage(CurrentMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2131,8 +2083,7 @@ MsqCleanupThreadMsgs(PTHREADINFO pti)
|
||||||
while (!IsListEmpty(&pti->SentMessagesListHead))
|
while (!IsListEmpty(&pti->SentMessagesListHead))
|
||||||
{
|
{
|
||||||
CurrentEntry = RemoveHeadList(&pti->SentMessagesListHead);
|
CurrentEntry = RemoveHeadList(&pti->SentMessagesListHead);
|
||||||
CurrentSentMessage = CONTAINING_RECORD(CurrentEntry, USER_SENT_MESSAGE,
|
CurrentSentMessage = CONTAINING_RECORD(CurrentEntry, USER_SENT_MESSAGE, ListEntry);
|
||||||
ListEntry);
|
|
||||||
|
|
||||||
TRACE("Notify the sender and remove a message from the queue that had not been dispatched\n");
|
TRACE("Notify the sender and remove a message from the queue that had not been dispatched\n");
|
||||||
/* Only if the message has a sender was the message in the DispatchingList */
|
/* Only if the message has a sender was the message in the DispatchingList */
|
||||||
|
@ -2163,8 +2114,7 @@ MsqCleanupThreadMsgs(PTHREADINFO pti)
|
||||||
while (!IsListEmpty(&pti->LocalDispatchingMessagesHead))
|
while (!IsListEmpty(&pti->LocalDispatchingMessagesHead))
|
||||||
{
|
{
|
||||||
CurrentEntry = RemoveHeadList(&pti->LocalDispatchingMessagesHead);
|
CurrentEntry = RemoveHeadList(&pti->LocalDispatchingMessagesHead);
|
||||||
CurrentSentMessage = CONTAINING_RECORD(CurrentEntry, USER_SENT_MESSAGE,
|
CurrentSentMessage = CONTAINING_RECORD(CurrentEntry, USER_SENT_MESSAGE, ListEntry);
|
||||||
ListEntry);
|
|
||||||
|
|
||||||
/* remove the message from the dispatching list */
|
/* remove the message from the dispatching list */
|
||||||
if(CurrentSentMessage->DispatchingListEntry.Flink != NULL)
|
if(CurrentSentMessage->DispatchingListEntry.Flink != NULL)
|
||||||
|
@ -2194,8 +2144,7 @@ MsqCleanupThreadMsgs(PTHREADINFO pti)
|
||||||
while (! IsListEmpty(&pti->DispatchingMessagesHead))
|
while (! IsListEmpty(&pti->DispatchingMessagesHead))
|
||||||
{
|
{
|
||||||
CurrentEntry = RemoveHeadList(&pti->DispatchingMessagesHead);
|
CurrentEntry = RemoveHeadList(&pti->DispatchingMessagesHead);
|
||||||
CurrentSentMessage = CONTAINING_RECORD(CurrentEntry, USER_SENT_MESSAGE,
|
CurrentSentMessage = CONTAINING_RECORD(CurrentEntry, USER_SENT_MESSAGE, DispatchingListEntry);
|
||||||
DispatchingListEntry);
|
|
||||||
CurrentSentMessage->CompletionEvent = NULL;
|
CurrentSentMessage->CompletionEvent = NULL;
|
||||||
CurrentSentMessage->Result = NULL;
|
CurrentSentMessage->Result = NULL;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue