https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2e88e2b90448a8a320fa2…
commit 2e88e2b90448a8a320fa293e95d8766a11a63a53
Author:     Eric Kohl <eric.kohl(a)reactos.org>
AuthorDate: Sun May 2 13:46:22 2021 +0200
Commit:     Eric Kohl <eric.kohl(a)reactos.org>
CommitDate: Sun May 2 13:46:22 2021 +0200
    [NTOS:PS] Rewrite NtSetInformationThread to match NtQueryInformationThread
    The Information length must always be checked before referencing the thread object.
This fixes a test failure.
---
 ntoskrnl/ps/query.c | 149 ++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 127 insertions(+), 22 deletions(-)
diff --git a/ntoskrnl/ps/query.c b/ntoskrnl/ps/query.c
index fa8d201c249..b8598a0b8a0 100644
--- a/ntoskrnl/ps/query.c
+++ b/ntoskrnl/ps/query.c
@@ -2018,7 +2018,6 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
                        IN ULONG ThreadInformationLength)
 {
     PETHREAD Thread;
-    ULONG Access;
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
     NTSTATUS Status;
     HANDLE TokenHandle = NULL;
@@ -2046,23 +2045,6 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
     if (!NT_SUCCESS(Status)) return Status;
 #endif
-    /* Check what class this is */
-    Access = THREAD_SET_INFORMATION;
-    if (ThreadInformationClass == ThreadImpersonationToken)
-    {
-        /* Setting the impersonation token needs a special mask */
-        Access = THREAD_SET_THREAD_TOKEN;
-    }
-
-    /* Reference the thread */
-    Status = ObReferenceObjectByHandle(ThreadHandle,
-                                       Access,
-                                       PsThreadType,
-                                       PreviousMode,
-                                       (PVOID*)&Thread,
-                                       NULL);
-    if (!NT_SUCCESS(Status)) return Status;
-
     /* Check what kind of information class this is */
     switch (ThreadInformationClass)
     {
@@ -2099,8 +2081,21 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
                 break;
             }
+            /* Reference the thread */
+            Status = ObReferenceObjectByHandle(ThreadHandle,
+                                               THREAD_SET_INFORMATION,
+                                               PsThreadType,
+                                               PreviousMode,
+                                               (PVOID*)&Thread,
+                                               NULL);
+            if (!NT_SUCCESS(Status))
+                break;
+
             /* Set the priority */
             KeSetPriorityThread(&Thread->Tcb, Priority);
+
+            /* Dereference the thread */
+            ObDereferenceObject(Thread);
             break;
         case ThreadBasePriority:
@@ -2145,8 +2140,21 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
                 }
             }
+            /* Reference the thread */
+            Status = ObReferenceObjectByHandle(ThreadHandle,
+                                               THREAD_SET_INFORMATION,
+                                               PsThreadType,
+                                               PreviousMode,
+                                               (PVOID*)&Thread,
+                                               NULL);
+            if (!NT_SUCCESS(Status))
+                break;
+
             /* Set the base priority */
             KeSetBasePriorityThread(&Thread->Tcb, Priority);
+
+            /* Dereference the thread */
+            ObDereferenceObject(Thread);
             break;
         case ThreadAffinityMask:
@@ -2180,6 +2188,16 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
                 break;
             }
+            /* Reference the thread */
+            Status = ObReferenceObjectByHandle(ThreadHandle,
+                                               THREAD_SET_INFORMATION,
+                                               PsThreadType,
+                                               PreviousMode,
+                                               (PVOID*)&Thread,
+                                               NULL);
+            if (!NT_SUCCESS(Status))
+                break;
+
             /* Get the process */
             Process = Thread->ThreadsProcess;
@@ -2214,7 +2232,8 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
                 Status = STATUS_PROCESS_IS_TERMINATING;
             }
-            /* Return status */
+            /* Dereference the thread */
+            ObDereferenceObject(Thread);
             break;
         case ThreadImpersonationToken:
@@ -2240,8 +2259,21 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
             }
             _SEH2_END;
+            /* Reference the thread */
+            Status = ObReferenceObjectByHandle(ThreadHandle,
+                                               THREAD_SET_THREAD_TOKEN,
+                                               PsThreadType,
+                                               PreviousMode,
+                                               (PVOID*)&Thread,
+                                               NULL);
+            if (!NT_SUCCESS(Status))
+                break;
+
             /* Assign the actual token */
             Status = PsAssignImpersonationToken(Thread, TokenHandle);
+
+            /* Dereference the thread */
+            ObDereferenceObject(Thread);
             break;
         case ThreadQuerySetWin32StartAddress:
@@ -2267,8 +2299,21 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
             }
             _SEH2_END;
+            /* Reference the thread */
+            Status = ObReferenceObjectByHandle(ThreadHandle,
+                                               THREAD_SET_INFORMATION,
+                                               PsThreadType,
+                                               PreviousMode,
+                                               (PVOID*)&Thread,
+                                               NULL);
+            if (!NT_SUCCESS(Status))
+                break;
+
             /* Set the address */
             Thread->Win32StartAddress = Address;
+
+            /* Dereference the thread */
+            ObDereferenceObject(Thread);
             break;
         case ThreadIdealProcessor:
@@ -2302,6 +2347,16 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
                 break;
             }
+            /* Reference the thread */
+            Status = ObReferenceObjectByHandle(ThreadHandle,
+                                               THREAD_SET_INFORMATION,
+                                               PsThreadType,
+                                               PreviousMode,
+                                               (PVOID*)&Thread,
+                                               NULL);
+            if (!NT_SUCCESS(Status))
+                break;
+
             /* Set the ideal */
             Status = KeSetIdealProcessorThread(&Thread->Tcb,
                                                (CCHAR)IdealProcessor);
@@ -2317,6 +2372,8 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
                 ExReleaseRundownProtection(&Thread->RundownProtect);
             }
+            /* Dereference the thread */
+            ObDereferenceObject(Thread);
             break;
         case ThreadPriorityBoost:
@@ -2342,8 +2399,21 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
             }
             _SEH2_END;
+            /* Reference the thread */
+            Status = ObReferenceObjectByHandle(ThreadHandle,
+                                               THREAD_SET_INFORMATION,
+                                               PsThreadType,
+                                               PreviousMode,
+                                               (PVOID*)&Thread,
+                                               NULL);
+            if (!NT_SUCCESS(Status))
+                break;
+
             /* Call the kernel */
             KeSetDisableBoostThread(&Thread->Tcb, (BOOLEAN)DisableBoost);
+
+            /* Dereference the thread */
+            ObDereferenceObject(Thread);
             break;
         case ThreadZeroTlsCell:
@@ -2377,6 +2447,16 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
                 break;
             }
+            /* Reference the thread */
+            Status = ObReferenceObjectByHandle(ThreadHandle,
+                                               THREAD_SET_INFORMATION,
+                                               PsThreadType,
+                                               PreviousMode,
+                                               (PVOID*)&Thread,
+                                               NULL);
+            if (!NT_SUCCESS(Status))
+                break;
+
             /* Get the process */
             Process = Thread->ThreadsProcess;
@@ -2421,7 +2501,8 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
                 ProcThread = PsGetNextProcessThread(Process, ProcThread);
             }
-            /* All done */
+            /* Dereference the thread */
+            ObDereferenceObject(Thread);
             break;
         case ThreadBreakOnTermination:
@@ -2455,6 +2536,16 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
                 break;
             }
+            /* Reference the thread */
+            Status = ObReferenceObjectByHandle(ThreadHandle,
+                                               THREAD_SET_INFORMATION,
+                                               PsThreadType,
+                                               PreviousMode,
+                                               (PVOID*)&Thread,
+                                               NULL);
+            if (!NT_SUCCESS(Status))
+                break;
+
             /* Set or clear the flag */
             if (Break)
             {
@@ -2464,6 +2555,9 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
             {
                 PspClearCrossThreadFlag(Thread, CT_BREAK_ON_TERMINATION_BIT);
             }
+
+            /* Dereference the thread */
+            ObDereferenceObject(Thread);
             break;
         case ThreadHideFromDebugger:
@@ -2475,8 +2569,21 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
                 break;
             }
+            /* Reference the thread */
+            Status = ObReferenceObjectByHandle(ThreadHandle,
+                                               THREAD_SET_INFORMATION,
+                                               PsThreadType,
+                                               PreviousMode,
+                                               (PVOID*)&Thread,
+                                               NULL);
+            if (!NT_SUCCESS(Status))
+                break;
+
             /* Set the flag */
             PspSetCrossThreadFlag(Thread, CT_HIDE_FROM_DEBUGGER_BIT);
+
+            /* Dereference the thread */
+            ObDereferenceObject(Thread);
             break;
         default:
@@ -2485,8 +2592,6 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
             Status = STATUS_NOT_IMPLEMENTED;
     }
-    /* Dereference and return status */
-    ObDereferenceObject(Thread);
     return Status;
 }