From d03a382228a4817c64b0479db82e025c777a8acc Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sat, 25 Jul 2015 11:53:16 +0000 Subject: [PATCH] [NTOSKRNL] NtQuerySystemInformation: - Windows Vista and later: Check the information class before probing the buffer. - Pre-Vista Windows: Check the information class after probing the buffer. - Pre-Vista Windows: Fixed the aligment check for invalid information classes. - Pre-Vista Windows: The SystemFlagsInformation and SystemKernelDebuggerInformation classes return no required length in case of an error. This fixes all ntdll_apitest:NtSystemInformation fails. svn path=/trunk/; revision=68571 --- reactos/ntoskrnl/ex/sysinfo.c | 49 +++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/reactos/ntoskrnl/ex/sysinfo.c b/reactos/ntoskrnl/ex/sysinfo.c index 4187fc2614a..0d30d5978a1 100644 --- a/reactos/ntoskrnl/ex/sysinfo.c +++ b/reactos/ntoskrnl/ex/sysinfo.c @@ -1065,12 +1065,20 @@ QSI_DEF(SystemProcessorPerformanceInformation) /* Class 9 - Flags Information */ QSI_DEF(SystemFlagsInformation) { +#if (NTDDI_VERSION >= NTDDI_VISTA) + *ReqSize = sizeof(SYSTEM_FLAGS_INFORMATION); +#endif + if (sizeof(SYSTEM_FLAGS_INFORMATION) != Size) { - *ReqSize = sizeof(SYSTEM_FLAGS_INFORMATION); - return (STATUS_INFO_LENGTH_MISMATCH); + return STATUS_INFO_LENGTH_MISMATCH; } + ((PSYSTEM_FLAGS_INFORMATION) Buffer)->Flags = NtGlobalFlag; +#if (NTDDI_VERSION < NTDDI_VISTA) + *ReqSize = sizeof(SYSTEM_FLAGS_INFORMATION); +#endif + return STATUS_SUCCESS; } @@ -1631,7 +1639,10 @@ QSI_DEF(SystemKernelDebuggerInformation) { PSYSTEM_KERNEL_DEBUGGER_INFORMATION skdi = (PSYSTEM_KERNEL_DEBUGGER_INFORMATION) Buffer; +#if (NTDDI_VERSION >= NTDDI_VISTA) *ReqSize = sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION); +#endif + if (Size < sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION)) { return STATUS_INFO_LENGTH_MISMATCH; @@ -1640,6 +1651,10 @@ QSI_DEF(SystemKernelDebuggerInformation) skdi->KernelDebuggerEnabled = KD_DEBUGGER_ENABLED; skdi->KernelDebuggerNotPresent = KD_DEBUGGER_NOT_PRESENT; +#if (NTDDI_VERSION < NTDDI_VISTA) + *ReqSize = sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION); +#endif + return STATUS_SUCCESS; } @@ -2308,7 +2323,6 @@ struct _QSSI_CALLS { NTSTATUS (* Query) (PVOID,ULONG,PULONG); NTSTATUS (* Set) (PVOID,ULONG); - ULONG Alignment; } QSSI_CALLS; // QS Query & Set @@ -2316,12 +2330,9 @@ struct _QSSI_CALLS // XS Set // XX unknown behaviour // -#define SI_QS(n) {QSI_USE(n),SSI_USE(n),TYPE_ALIGNMENT(ULONG)} -#define SI_QX(n) {QSI_USE(n),NULL,TYPE_ALIGNMENT(ULONG)} -#define SI_XS(n) {NULL,SSI_USE(n),TYPE_ALIGNMENT(ULONG)} -#define SI_QS_ALIGN(n,a) {QSI_USE(n),SSI_USE(n),a} -#define SI_QX_ALIGN(n,a) {QSI_USE(n),NULL,a} -#define SI_XS_ALIGN(n,a) {NULL,SSI_USE(n),a} +#define SI_QS(n) {QSI_USE(n),SSI_USE(n)} +#define SI_QX(n) {QSI_USE(n),NULL} +#define SI_XS(n) {NULL,SSI_USE(n)} #define SI_XX(n) {NULL,NULL} static @@ -2363,7 +2374,7 @@ CallQS [] = SI_QX(SystemCrashDumpInformation), SI_QX(SystemExceptionInformation), SI_QX(SystemCrashDumpStateInformation), - SI_QX_ALIGN(SystemKernelDebuggerInformation, TYPE_ALIGNMENT(BOOLEAN)), + SI_QX(SystemKernelDebuggerInformation), SI_QX(SystemContextSwitchInformation), SI_QS(SystemRegistryQuotaInformation), SI_XS(SystemExtendServiceTableInformation), @@ -2406,6 +2417,7 @@ NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInformationClass, { KPROCESSOR_MODE PreviousMode; ULONG ResultLength = 0; + ULONG Alignment = TYPE_ALIGNMENT(ULONG); NTSTATUS FStatus = STATUS_NOT_IMPLEMENTED; PAGED_CODE(); @@ -2414,6 +2426,7 @@ NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInformationClass, _SEH2_TRY { +#if (NTDDI_VERSION >= NTDDI_VISTA) /* * Check if the request is valid. */ @@ -2421,11 +2434,15 @@ NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInformationClass, { _SEH2_YIELD(return STATUS_INVALID_INFO_CLASS); } +#endif if (PreviousMode != KernelMode) { /* SystemKernelDebuggerInformation needs only BOOLEAN alignment */ - ProbeForWrite(SystemInformation, Length, CallQS[SystemInformationClass].Alignment); + if (SystemInformationClass == SystemKernelDebuggerInformation) + Alignment = TYPE_ALIGNMENT(BOOLEAN); + + ProbeForWrite(SystemInformation, Length, Alignment); if (UnsafeResultLength != NULL) ProbeForWriteUlong(UnsafeResultLength); } @@ -2433,6 +2450,16 @@ NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInformationClass, if (UnsafeResultLength) *UnsafeResultLength = 0; +#if (NTDDI_VERSION < NTDDI_VISTA) + /* + * Check if the request is valid. + */ + if (SystemInformationClass >= MAX_SYSTEM_INFO_CLASS) + { + _SEH2_YIELD(return STATUS_INVALID_INFO_CLASS); + } +#endif + if (NULL != CallQS [SystemInformationClass].Query) { /*