Author: ekohl Date: Sat Jul 25 11:53:16 2015 New Revision: 68571
URL: http://svn.reactos.org/svn/reactos?rev=68571&view=rev Log: [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.
Modified: trunk/reactos/ntoskrnl/ex/sysinfo.c
Modified: trunk/reactos/ntoskrnl/ex/sysinfo.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/sysinfo.c?rev=6... ============================================================================== --- trunk/reactos/ntoskrnl/ex/sysinfo.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ex/sysinfo.c [iso-8859-1] Sat Jul 25 11:53:16 2015 @@ -1065,12 +1065,20 @@ /* 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 @@ { 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; @@ -1639,6 +1650,10 @@
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 @@ { NTSTATUS (* Query) (PVOID,ULONG,PULONG); NTSTATUS (* Set) (PVOID,ULONG); - ULONG Alignment; } QSSI_CALLS;
// QS Query & Set @@ -2316,12 +2330,9 @@ // 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 @@ 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 @@ { KPROCESSOR_MODE PreviousMode; ULONG ResultLength = 0; + ULONG Alignment = TYPE_ALIGNMENT(ULONG); NTSTATUS FStatus = STATUS_NOT_IMPLEMENTED;
PAGED_CODE(); @@ -2414,6 +2426,7 @@
_SEH2_TRY { +#if (NTDDI_VERSION >= NTDDI_VISTA) /* * Check if the request is valid. */ @@ -2421,17 +2434,31 @@ { _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); }
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) {