https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7481bda679eccdf1eba36…
commit 7481bda679eccdf1eba3666e500074dcb966e748
Author: Bișoc George <fraizeraust99(a)gmail.com>
AuthorDate: Sat Mar 28 19:17:10 2020 +0100
Commit: GitHub <noreply(a)github.com>
CommitDate: Sat Mar 28 19:17:10 2020 +0100
[SDK][NDK][PSTYPES] Align the PROCESS_PRIORITY_CLASS structure during compile time (#2478)
CORE-16757
After doing investigations on the priority class structure alignment, it's been revealed that in Windows XP and Server 2003 this PROCESS_PRIORITY_CLASS structure is aligned as a 4-bytes of size hence NtQueryInformationProcess() probes the alignment of user mode arguments buffer output and buffer length with requirement of a ULONG.
As PROCESS_PRIORITY_CLASS was initially aligned as a 1-byte size because both BOOLEAN and UCHAR are just unsigned characters, the compiler may not align such structure and gracefully let the default alignment of such structure as is, 1-byte because an unsigned char has a size of 1 byte. Setting an align attribute to this structure fixes the problem of a potential datatype misalignment which caused GetPriorityClass() to not retrieve the process' priority class properly.
---
sdk/include/ndk/pstypes.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sdk/include/ndk/pstypes.h b/sdk/include/ndk/pstypes.h
index 543afcb618d..219b880368f 100644
--- a/sdk/include/ndk/pstypes.h
+++ b/sdk/include/ndk/pstypes.h
@@ -902,7 +902,7 @@ typedef struct _PROCESS_SESSION_INFORMATION
#endif
-typedef struct _PROCESS_PRIORITY_CLASS
+typedef struct DECLSPEC_ALIGN(4) _PROCESS_PRIORITY_CLASS
{
BOOLEAN Foreground;
UCHAR PriorityClass;
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=fcb156388d88eb6c09498…
commit fcb156388d88eb6c0949890fde6d0efe19f00deb
Author: Bișoc George <fraizeraust99(a)gmail.com>
AuthorDate: Thu Mar 26 12:11:29 2020 +0100
Commit: Thomas Faber <thomas.faber(a)reactos.org>
CommitDate: Sat Mar 28 13:10:44 2020 +0100
[NTDLL_APITEST] Add testcase for process priority class. CORE-16757
Currently the testcase function only addresses the behaviour of getting an
unaligned buffer (either of correct length size or not) for now.
---
.../apitests/ntdll/NtQueryInformationProcess.c | 69 ++++++++++++++++++++++
1 file changed, 69 insertions(+)
diff --git a/modules/rostests/apitests/ntdll/NtQueryInformationProcess.c b/modules/rostests/apitests/ntdll/NtQueryInformationProcess.c
index bdbfc3f726a..e392ead8760 100644
--- a/modules/rostests/apitests/ntdll/NtQueryInformationProcess.c
+++ b/modules/rostests/apitests/ntdll/NtQueryInformationProcess.c
@@ -185,6 +185,74 @@ Test_ProcessTimes(void)
#undef SPIN_TIME
}
+static
+void
+Test_ProcessPriorityClassAlignment(void)
+{
+ NTSTATUS Status;
+ PPROCESS_PRIORITY_CLASS ProcPriority;
+
+ /* Allocate some memory for the priority class structure */
+ ProcPriority = malloc(sizeof(PROCESS_PRIORITY_CLASS));
+ if (ProcPriority == NULL)
+ {
+ skip("Failed to allocate memory for PROCESS_PRIORITY_CLASS!\n");
+ return;
+ }
+
+ /*
+ * Initialize the PriorityClass member to ensure the test won't randomly succeed (if such data is uninitialized).
+ * Filling 85 to the data member makes sure that if the test fails continously then NtQueryInformationProcess()
+ * didn't initialize the structure with data.
+ */
+ RtlFillMemory(&ProcPriority->PriorityClass, sizeof(ProcPriority->PriorityClass), 0x55);
+
+ /* Unaligned buffer -- wrong size */
+ Status = NtQueryInformationProcess(NtCurrentProcess(),
+ ProcessPriorityClass,
+ (PVOID)1,
+ 0,
+ NULL);
+ ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH);
+
+ /* Unaligned buffer -- correct size */
+ Status = NtQueryInformationProcess(NtCurrentProcess(),
+ ProcessPriorityClass,
+ (PVOID)1,
+ sizeof(PROCESS_PRIORITY_CLASS),
+ NULL);
+ ok_hex(Status, STATUS_DATATYPE_MISALIGNMENT);
+
+ /* Unaligned buffer -- wrong size (but this time do with an alignment of 2) */
+ Status = NtQueryInformationProcess(NtCurrentProcess(),
+ ProcessPriorityClass,
+ (PVOID)2,
+ 0,
+ NULL);
+ ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH);
+
+ /* Unaligned buffer -- correct size (but this time do with an alignment of 2) */
+ Status = NtQueryInformationProcess(NtCurrentProcess(),
+ ProcessPriorityClass,
+ (PVOID)2,
+ sizeof(PROCESS_PRIORITY_CLASS),
+ NULL);
+ ok_hex(Status, STATUS_DATATYPE_MISALIGNMENT);
+
+ /* Do not care for the length but expect to return the priority class */
+ Status = NtQueryInformationProcess(NtCurrentProcess(),
+ ProcessPriorityClass,
+ ProcPriority,
+ sizeof(PROCESS_PRIORITY_CLASS),
+ NULL);
+ ok_hex(Status, STATUS_SUCCESS);
+
+ /* Make sure the returned priority class is a valid number (non negative) but also it should be within the PROCESS_PRIORITY_CLASS range */
+ ok(ProcPriority->PriorityClass > PROCESS_PRIORITY_CLASS_INVALID && ProcPriority->PriorityClass <= PROCESS_PRIORITY_CLASS_ABOVE_NORMAL,
+ "Expected a valid number from priority class range but got %d\n", ProcPriority->PriorityClass);
+ free(ProcPriority);
+}
+
START_TEST(NtQueryInformationProcess)
{
NTSTATUS Status;
@@ -193,4 +261,5 @@ START_TEST(NtQueryInformationProcess)
ok_hex(Status, STATUS_SUCCESS);
Test_ProcessTimes();
+ Test_ProcessPriorityClassAlignment();
}