[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
This commit is contained in:
Eric Kohl 2015-07-25 11:53:16 +00:00
parent 4a1740bc9e
commit d03a382228

View file

@ -1065,12 +1065,20 @@ QSI_DEF(SystemProcessorPerformanceInformation)
/* Class 9 - Flags Information */ /* Class 9 - Flags Information */
QSI_DEF(SystemFlagsInformation) QSI_DEF(SystemFlagsInformation)
{ {
#if (NTDDI_VERSION >= NTDDI_VISTA)
*ReqSize = sizeof(SYSTEM_FLAGS_INFORMATION);
#endif
if (sizeof(SYSTEM_FLAGS_INFORMATION) != Size) 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; ((PSYSTEM_FLAGS_INFORMATION) Buffer)->Flags = NtGlobalFlag;
#if (NTDDI_VERSION < NTDDI_VISTA)
*ReqSize = sizeof(SYSTEM_FLAGS_INFORMATION);
#endif
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -1631,7 +1639,10 @@ QSI_DEF(SystemKernelDebuggerInformation)
{ {
PSYSTEM_KERNEL_DEBUGGER_INFORMATION skdi = (PSYSTEM_KERNEL_DEBUGGER_INFORMATION) Buffer; PSYSTEM_KERNEL_DEBUGGER_INFORMATION skdi = (PSYSTEM_KERNEL_DEBUGGER_INFORMATION) Buffer;
#if (NTDDI_VERSION >= NTDDI_VISTA)
*ReqSize = sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION); *ReqSize = sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION);
#endif
if (Size < sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION)) if (Size < sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION))
{ {
return STATUS_INFO_LENGTH_MISMATCH; return STATUS_INFO_LENGTH_MISMATCH;
@ -1640,6 +1651,10 @@ QSI_DEF(SystemKernelDebuggerInformation)
skdi->KernelDebuggerEnabled = KD_DEBUGGER_ENABLED; skdi->KernelDebuggerEnabled = KD_DEBUGGER_ENABLED;
skdi->KernelDebuggerNotPresent = KD_DEBUGGER_NOT_PRESENT; skdi->KernelDebuggerNotPresent = KD_DEBUGGER_NOT_PRESENT;
#if (NTDDI_VERSION < NTDDI_VISTA)
*ReqSize = sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION);
#endif
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -2308,7 +2323,6 @@ struct _QSSI_CALLS
{ {
NTSTATUS (* Query) (PVOID,ULONG,PULONG); NTSTATUS (* Query) (PVOID,ULONG,PULONG);
NTSTATUS (* Set) (PVOID,ULONG); NTSTATUS (* Set) (PVOID,ULONG);
ULONG Alignment;
} QSSI_CALLS; } QSSI_CALLS;
// QS Query & Set // QS Query & Set
@ -2316,12 +2330,9 @@ struct _QSSI_CALLS
// XS Set // XS Set
// XX unknown behaviour // XX unknown behaviour
// //
#define SI_QS(n) {QSI_USE(n),SSI_USE(n),TYPE_ALIGNMENT(ULONG)} #define SI_QS(n) {QSI_USE(n),SSI_USE(n)}
#define SI_QX(n) {QSI_USE(n),NULL,TYPE_ALIGNMENT(ULONG)} #define SI_QX(n) {QSI_USE(n),NULL}
#define SI_XS(n) {NULL,SSI_USE(n),TYPE_ALIGNMENT(ULONG)} #define SI_XS(n) {NULL,SSI_USE(n)}
#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_XX(n) {NULL,NULL} #define SI_XX(n) {NULL,NULL}
static static
@ -2363,7 +2374,7 @@ CallQS [] =
SI_QX(SystemCrashDumpInformation), SI_QX(SystemCrashDumpInformation),
SI_QX(SystemExceptionInformation), SI_QX(SystemExceptionInformation),
SI_QX(SystemCrashDumpStateInformation), SI_QX(SystemCrashDumpStateInformation),
SI_QX_ALIGN(SystemKernelDebuggerInformation, TYPE_ALIGNMENT(BOOLEAN)), SI_QX(SystemKernelDebuggerInformation),
SI_QX(SystemContextSwitchInformation), SI_QX(SystemContextSwitchInformation),
SI_QS(SystemRegistryQuotaInformation), SI_QS(SystemRegistryQuotaInformation),
SI_XS(SystemExtendServiceTableInformation), SI_XS(SystemExtendServiceTableInformation),
@ -2406,6 +2417,7 @@ NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
{ {
KPROCESSOR_MODE PreviousMode; KPROCESSOR_MODE PreviousMode;
ULONG ResultLength = 0; ULONG ResultLength = 0;
ULONG Alignment = TYPE_ALIGNMENT(ULONG);
NTSTATUS FStatus = STATUS_NOT_IMPLEMENTED; NTSTATUS FStatus = STATUS_NOT_IMPLEMENTED;
PAGED_CODE(); PAGED_CODE();
@ -2414,6 +2426,7 @@ NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
_SEH2_TRY _SEH2_TRY
{ {
#if (NTDDI_VERSION >= NTDDI_VISTA)
/* /*
* Check if the request is valid. * Check if the request is valid.
*/ */
@ -2421,11 +2434,15 @@ NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
{ {
_SEH2_YIELD(return STATUS_INVALID_INFO_CLASS); _SEH2_YIELD(return STATUS_INVALID_INFO_CLASS);
} }
#endif
if (PreviousMode != KernelMode) if (PreviousMode != KernelMode)
{ {
/* SystemKernelDebuggerInformation needs only BOOLEAN alignment */ /* 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) if (UnsafeResultLength != NULL)
ProbeForWriteUlong(UnsafeResultLength); ProbeForWriteUlong(UnsafeResultLength);
} }
@ -2433,6 +2450,16 @@ NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
if (UnsafeResultLength) if (UnsafeResultLength)
*UnsafeResultLength = 0; *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) if (NULL != CallQS [SystemInformationClass].Query)
{ {
/* /*