From 72b98da684e8a65e3e7e7ec0f1b256f38f3c44e3 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sat, 23 Aug 2025 17:39:44 +0300 Subject: [PATCH] [NTOS:EX] Fix bugs in NtCreateEvent - Validate EventType - Cleanup on failure - Add ASSERTs in KeInitializeEvent and KeInitializeTimerEx --- ntoskrnl/ex/event.c | 72 +++++++++++++++++++++++------------------- ntoskrnl/ke/eventobj.c | 3 +- ntoskrnl/ke/timerobj.c | 1 + 3 files changed, 43 insertions(+), 33 deletions(-) diff --git a/ntoskrnl/ex/event.c b/ntoskrnl/ex/event.c index 27222cb3c4a..64fc2bd3461 100644 --- a/ntoskrnl/ex/event.c +++ b/ntoskrnl/ex/event.c @@ -107,6 +107,13 @@ NtCreateEvent(OUT PHANDLE EventHandle, DPRINT("NtCreateEvent(0x%p, 0x%x, 0x%p)\n", EventHandle, DesiredAccess, ObjectAttributes); + /* Validate the event type */ + if ((EventType != NotificationEvent) && + (EventType != SynchronizationEvent)) + { + return STATUS_INVALID_PARAMETER; + } + /* Check if we were called from user-mode */ if (PreviousMode != KernelMode) { @@ -134,41 +141,42 @@ NtCreateEvent(OUT PHANDLE EventHandle, 0, 0, (PVOID*)&Event); - - /* Check for Success */ - if (NT_SUCCESS(Status)) + if (!NT_SUCCESS(Status)) { - /* Initialize the Event */ - KeInitializeEvent(Event, - EventType, - InitialState); - - /* Insert it */ - Status = ObInsertObject((PVOID)Event, - NULL, - DesiredAccess, - 0, - NULL, - &hEvent); - - /* Check for success */ - if (NT_SUCCESS(Status)) - { - /* Enter SEH for return */ - _SEH2_TRY - { - /* Return the handle to the caller */ - *EventHandle = hEvent; - } - _SEH2_EXCEPT(ExSystemExceptionFilter()) - { - /* Get the exception code */ - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END; - } + DPRINT1("ObCreateObject failed: 0x%X\n", Status); + return Status; } + /* Initialize the Event */ + KeInitializeEvent(Event, EventType, InitialState); + + /* Insert it */ + Status = ObInsertObject((PVOID)Event, + NULL, + DesiredAccess, + 0, + NULL, + &hEvent); + if (!NT_SUCCESS(Status)) + { + DPRINT1("ObInsertObject failed: 0x%X\n", Status); + /* Note: ObInsertObject dereferences Event on failure */ + return Status; + } + + /* Enter SEH for return */ + _SEH2_TRY + { + /* Return the handle to the caller */ + *EventHandle = hEvent; + } + _SEH2_EXCEPT(ExSystemExceptionFilter()) + { + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + /* Return Status */ return Status; } diff --git a/ntoskrnl/ke/eventobj.c b/ntoskrnl/ke/eventobj.c index 69fc558a782..7af3ea180e4 100644 --- a/ntoskrnl/ke/eventobj.c +++ b/ntoskrnl/ke/eventobj.c @@ -37,7 +37,8 @@ KeInitializeEvent(OUT PKEVENT Event, IN BOOLEAN State) { /* Initialize the Dispatcher Header */ - Event->Header.Type = Type; + ASSERT((Type == NotificationEvent) || (Type == SynchronizationEvent)); + Event->Header.Type = EventNotificationObject + Type; //Event->Header.Signalling = FALSE; // fails in kmtest Event->Header.Size = sizeof(KEVENT) / sizeof(ULONG); Event->Header.SignalState = State; diff --git a/ntoskrnl/ke/timerobj.c b/ntoskrnl/ke/timerobj.c index 1c19d03b46e..db39de11267 100644 --- a/ntoskrnl/ke/timerobj.c +++ b/ntoskrnl/ke/timerobj.c @@ -249,6 +249,7 @@ KeInitializeTimerEx(OUT PKTIMER Timer, "NotificationTimer" : "SynchronizationTimer"); /* Initialize the Dispatch Header */ + ASSERT((Type == NotificationTimer) || (Type == SynchronizationTimer)); Timer->Header.Type = TimerNotificationObject + Type; //Timer->Header.TimerControlFlags = 0; // win does not init this field Timer->Header.Hand = sizeof(KTIMER) / sizeof(ULONG);