Author: tfaber Date: Sun Sep 11 11:22:00 2011 New Revision: 53687
URL: http://svn.reactos.org/svn/reactos?rev=53687&view=rev Log: [KMTESTS] - Add support for guarded allocations, that can be used to detect buffer overruns - Add GuardedMemory example test - Add MmSection test with some basic parameter checks for MmCreateSection - Fix some x64 build problems - Update readme
Added: trunk/rostests/kmtests/example/GuardedMemory.c (with props) trunk/rostests/kmtests/ntos_mm/ trunk/rostests/kmtests/ntos_mm/MmSection.c (with props) Modified: trunk/rostests/kmtests/CMakeLists.txt trunk/rostests/kmtests/include/kmt_test.h trunk/rostests/kmtests/kmtest.rbuild trunk/rostests/kmtests/kmtest_drv.rbuild trunk/rostests/kmtests/kmtest_drv/testlist.c trunk/rostests/kmtests/ntos_ex/ExDoubleList.c trunk/rostests/kmtests/ntos_ex/ExSequencedList.c trunk/rostests/kmtests/ntos_ex/ExSingleList.c trunk/rostests/kmtests/ntos_ke/KeIrql.c trunk/rostests/kmtests/readme.txt
Modified: trunk/rostests/kmtests/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/CMakeLists.txt?rev... ============================================================================== --- trunk/rostests/kmtests/CMakeLists.txt [iso-8859-1] (original) +++ trunk/rostests/kmtests/CMakeLists.txt [iso-8859-1] Sun Sep 11 11:22:00 2011 @@ -8,6 +8,7 @@ add_subdirectory(ntos_io)
list(APPEND COMMON_SOURCE + example/GuardedMemory.c rtl/RtlAvlTree.c rtl/RtlMemory.c rtl/RtlSplayTree.c) @@ -42,6 +43,7 @@ ntos_ke/KeIrql.c ntos_ke/KeProcessor.c ntos_ke/KeSpinLock.c + ntos_mm/MmSection.c ntos_ob/ObReference.c ntos_ob/ObType.c ${COMMON_SOURCE}
Added: trunk/rostests/kmtests/example/GuardedMemory.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/example/GuardedMem... ============================================================================== --- trunk/rostests/kmtests/example/GuardedMemory.c (added) +++ trunk/rostests/kmtests/example/GuardedMemory.c [iso-8859-1] Sun Sep 11 11:22:00 2011 @@ -1,0 +1,63 @@ +/* + * PROJECT: ReactOS kernel-mode tests + * LICENSE: GPLv2+ - See COPYING in the top level directory + * PURPOSE: Kernel-Mode Test Suite Guarded Memory example test + * PROGRAMMER: Thomas Faber thfabba@gmx.de + */ + +#include <kmt_test.h> + +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-Wnonnull" +#endif /* defined __GNUC__ */ + +START_TEST(GuardedMemory) +{ + NTSTATUS Status; + SIZE_T Size = 123; + PCHAR *Buffer; + + /* access some invalid memory to test SEH */ + Status = STATUS_SUCCESS; + _SEH2_TRY + { + RtlFillMemory(NULL, 1, 0); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } _SEH2_END; + ok_eq_hex(Status, STATUS_ACCESS_VIOLATION); + + /* get guarded mem */ + Buffer = KmtAllocateGuarded(Size); + + if (skip(Buffer != NULL, "Failed to allocate guarded memory\n")) + return; + + /* access to guarded mem should be fine */ + Status = STATUS_SUCCESS; + _SEH2_TRY + { + RtlFillMemory(Buffer, Size, 0); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } _SEH2_END; + ok_eq_hex(Status, STATUS_SUCCESS); + + /* access one byte behind guarded mem must cause an access violation! */ + Status = STATUS_SUCCESS; + _SEH2_TRY + { + RtlFillMemory(Buffer + Size, 1, 0); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } _SEH2_END; + ok_eq_hex(Status, STATUS_ACCESS_VIOLATION); + + KmtFreeGuarded(Buffer); +}
Propchange: trunk/rostests/kmtests/example/GuardedMemory.c ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/rostests/kmtests/include/kmt_test.h URL: http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/include/kmt_test.h... ============================================================================== --- trunk/rostests/kmtests/include/kmt_test.h [iso-8859-1] (original) +++ trunk/rostests/kmtests/include/kmt_test.h [iso-8859-1] Sun Sep 11 11:22:00 2011 @@ -129,6 +129,8 @@ VOID KmtTrace(PCSTR FileAndLine, PCSTR Format, ...) KMT_FORMAT(ms_printf, 2, 3); BOOLEAN KmtVSkip(INT Condition, PCSTR FileAndLine, PCSTR Format, va_list Arguments) KMT_FORMAT(ms_printf, 3, 0); BOOLEAN KmtSkip(INT Condition, PCSTR FileAndLine, PCSTR Format, ...) KMT_FORMAT(ms_printf, 3, 4); +PVOID KmtAllocateGuarded(SIZE_T SizeRequested); +VOID KmtFreeGuarded(PVOID Pointer);
#ifdef KMT_KERNEL_MODE #define ok_irql(irql) ok(KeGetCurrentIrql() == irql, "IRQL is %d, expected %d\n", KeGetCurrentIrql(), irql) @@ -411,6 +413,44 @@ return Ret; }
+PVOID KmtAllocateGuarded(SIZE_T SizeRequested) +{ + NTSTATUS Status; + SIZE_T Size = PAGE_ROUND_UP(SizeRequested + PAGE_SIZE); + PVOID VirtualMemory = NULL; + PCHAR StartOfBuffer; + + Status = ZwAllocateVirtualMemory(ZwCurrentProcess(), &VirtualMemory, 0, &Size, MEM_RESERVE, PAGE_NOACCESS); + + if (!NT_SUCCESS(Status)) + return NULL; + + Size -= PAGE_SIZE; + Status = ZwAllocateVirtualMemory(ZwCurrentProcess(), &VirtualMemory, 0, &Size, MEM_COMMIT, PAGE_READWRITE); + if (!NT_SUCCESS(Status)) + { + Size = 0; + Status = ZwFreeVirtualMemory(ZwCurrentProcess(), &VirtualMemory, &Size, MEM_RELEASE); + ok_eq_hex(Status, STATUS_SUCCESS); + return NULL; + } + + StartOfBuffer = VirtualMemory; + StartOfBuffer += Size - SizeRequested; + + return StartOfBuffer; +} + +VOID KmtFreeGuarded(PVOID Pointer) +{ + NTSTATUS Status; + PVOID VirtualMemory = (PVOID)PAGE_ROUND_DOWN((SIZE_T)Pointer); + SIZE_T Size = 0; + + Status = ZwFreeVirtualMemory(ZwCurrentProcess(), &VirtualMemory, &Size, MEM_RELEASE); + ok_eq_hex(Status, STATUS_SUCCESS); +} + #endif /* defined KMT_DEFINE_TEST_FUNCTIONS */
#endif /* !defined _KMTEST_TEST_H_ */
Modified: trunk/rostests/kmtests/kmtest.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/kmtest.rbuild?rev=... ============================================================================== --- trunk/rostests/kmtests/kmtest.rbuild [iso-8859-1] (original) +++ trunk/rostests/kmtests/kmtest.rbuild [iso-8859-1] Sun Sep 11 11:22:00 2011 @@ -12,6 +12,7 @@ </directory> <directory name="example"> <file>Example_user.c</file> + <file>GuardedMemory.c</file> </directory> <directory name="ntos_io"> <file>IoDeviceObject_user.c</file>
Modified: trunk/rostests/kmtests/kmtest_drv.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/kmtest_drv.rbuild?... ============================================================================== --- trunk/rostests/kmtests/kmtest_drv.rbuild [iso-8859-1] (original) +++ trunk/rostests/kmtests/kmtest_drv.rbuild [iso-8859-1] Sun Sep 11 11:22:00 2011 @@ -12,6 +12,7 @@ </directory> <directory name="example"> <file>Example.c</file> + <file>GuardedMemory.c</file> <file>KernelType.c</file> </directory> <directory name="ntos_ex"> @@ -42,6 +43,9 @@ <file>KeIrql.c</file> <file>KeProcessor.c</file> <file>KeSpinLock.c</file> + </directory> + <directory name="ntos_mm"> + <file>MmSection.c</file> </directory> <directory name="ntos_ob"> <file>ObReference.c</file>
Modified: trunk/rostests/kmtests/kmtest_drv/testlist.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/kmtest_drv/testlis... ============================================================================== --- trunk/rostests/kmtests/kmtest_drv/testlist.c [iso-8859-1] (original) +++ trunk/rostests/kmtests/kmtest_drv/testlist.c [iso-8859-1] Sun Sep 11 11:22:00 2011 @@ -30,6 +30,7 @@ KMT_TESTFUNC Test_KeIrql; KMT_TESTFUNC Test_KeProcessor; KMT_TESTFUNC Test_KernelType; +KMT_TESTFUNC Test_MmSection; KMT_TESTFUNC Test_ObReference; KMT_TESTFUNC Test_ObType; KMT_TESTFUNC Test_ObTypeClean; @@ -63,6 +64,7 @@ { "KeIrql", Test_KeIrql }, { "-KeProcessor", Test_KeProcessor }, { "-KernelType", Test_KernelType }, + { "MmSection", Test_MmSection }, { "ObReference", Test_ObReference }, { "ObType", Test_ObType }, { "-ObTypeClean", Test_ObTypeClean },
Modified: trunk/rostests/kmtests/ntos_ex/ExDoubleList.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/ntos_ex/ExDoubleLi... ============================================================================== --- trunk/rostests/kmtests/ntos_ex/ExDoubleList.c [iso-8859-1] (original) +++ trunk/rostests/kmtests/ntos_ex/ExDoubleList.c [iso-8859-1] Sun Sep 11 11:22:00 2011 @@ -6,9 +6,11 @@ */
struct _LIST_ENTRY; +#ifdef _X86_ struct _LIST_ENTRY *__stdcall ExInterlockedInsertHeadList(struct _LIST_ENTRY *, struct _LIST_ENTRY *, unsigned long *); struct _LIST_ENTRY *__stdcall ExInterlockedInsertTailList(struct _LIST_ENTRY *, struct _LIST_ENTRY *, unsigned long *); struct _LIST_ENTRY *__stdcall ExInterlockedRemoveHeadList(struct _LIST_ENTRY *, unsigned long *); +#endif
#include <kmt_test.h>
Modified: trunk/rostests/kmtests/ntos_ex/ExSequencedList.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/ntos_ex/ExSequence... ============================================================================== --- trunk/rostests/kmtests/ntos_ex/ExSequencedList.c [iso-8859-1] (original) +++ trunk/rostests/kmtests/ntos_ex/ExSequencedList.c [iso-8859-1] Sun Sep 11 11:22:00 2011 @@ -13,7 +13,7 @@ #include <kmt_test.h>
/* TODO: SLIST_HEADER is a lot different for x64 */ - +#ifndef _M_AMD64 #define CheckSListHeader(ListHead, ExpectedPointer, ExpectedDepth) do \ { \ ok_eq_pointer((ListHead)->Next.Next, ExpectedPointer); \ @@ -39,9 +39,11 @@ #undef ExInterlockedPopEntrySList #define TestXListFunctional TestSListFunctionalExports #include "ExXList.h" +#endif
START_TEST(ExSequencedList) { +#ifndef _M_AMD64 PSLIST_HEADER ListHead; KSPIN_LOCK SpinLock; USHORT ExpectedSequence = 0; @@ -76,4 +78,5 @@
KeLowerIrql(Irql); ExFreePoolWithTag(Buffer, 'TLqS'); +#endif }
Modified: trunk/rostests/kmtests/ntos_ex/ExSingleList.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/ntos_ex/ExSingleLi... ============================================================================== --- trunk/rostests/kmtests/ntos_ex/ExSingleList.c [iso-8859-1] (original) +++ trunk/rostests/kmtests/ntos_ex/ExSingleList.c [iso-8859-1] Sun Sep 11 11:22:00 2011 @@ -6,8 +6,10 @@ */
struct _SINGLE_LIST_ENTRY; +#ifdef _X86_ struct _SINGLE_LIST_ENTRY *__stdcall ExInterlockedPushEntryList(struct _SINGLE_LIST_ENTRY *, struct _SINGLE_LIST_ENTRY *, unsigned long *); struct _SINGLE_LIST_ENTRY *__stdcall ExInterlockedPopEntryList(struct _SINGLE_LIST_ENTRY *, unsigned long *); +#endif
#include <kmt_test.h>
Modified: trunk/rostests/kmtests/ntos_ke/KeIrql.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/ntos_ke/KeIrql.c?r... ============================================================================== --- trunk/rostests/kmtests/ntos_ke/KeIrql.c [iso-8859-1] (original) +++ trunk/rostests/kmtests/ntos_ke/KeIrql.c [iso-8859-1] Sun Sep 11 11:22:00 2011 @@ -7,6 +7,10 @@
__declspec(dllimport) void __stdcall KeRaiseIrql(unsigned char, unsigned char *); __declspec(dllimport) void __stdcall KeLowerIrql(unsigned char); +#ifdef _M_AMD64 +#define CLOCK1_LEVEL CLOCK_LEVEL +#define CLOCK2_LEVEL CLOCK_LEVEL +#endif
#include <kmt_test.h>
Added: trunk/rostests/kmtests/ntos_mm/MmSection.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/ntos_mm/MmSection.... ============================================================================== --- trunk/rostests/kmtests/ntos_mm/MmSection.c (added) +++ trunk/rostests/kmtests/ntos_mm/MmSection.c [iso-8859-1] Sun Sep 11 11:22:00 2011 @@ -1,0 +1,98 @@ +/* + * PROJECT: ReactOS kernel-mode tests + * LICENSE: GPLv2+ - See COPYING in the top level directory + * PURPOSE: Kernel-Mode Test Suite Section Object test + * PROGRAMMER: Thomas Faber thfabba@gmx.de + */ + +#include <kmt_test.h> + +#define StartSeh() ExceptionStatus = STATUS_SUCCESS; _SEH2_TRY { +#define EndSeh(ExpectedStatus) } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { ExceptionStatus = _SEH2_GetExceptionCode(); } _SEH2_END; ok_eq_hex(ExceptionStatus, ExpectedStatus) + +START_TEST(MmSection) +{ + NTSTATUS Status = STATUS_SUCCESS; + NTSTATUS ExceptionStatus; + const PVOID InvalidPointer = (PVOID)0x5555555555555555LLU; + PVOID SectionObject; + LARGE_INTEGER MaximumSize; + + StartSeh() + Status = MmCreateSection(NULL, 0, NULL, NULL, 0, SEC_RESERVE, NULL, NULL); + EndSeh(STATUS_SUCCESS); + ok_eq_hex(Status, STATUS_INVALID_PAGE_PROTECTION); + + if (!KmtIsCheckedBuild) + { + /* PAGE_NOACCESS and missing SEC_RESERVE/SEC_COMMIT/SEC_IMAGE assert */ + StartSeh() + Status = MmCreateSection(NULL, 0, NULL, NULL, PAGE_NOACCESS, SEC_RESERVE, NULL, NULL); + EndSeh(STATUS_ACCESS_VIOLATION); + + StartSeh() + Status = MmCreateSection(NULL, 0, NULL, NULL, PAGE_NOACCESS, 0, NULL, NULL); + EndSeh(STATUS_ACCESS_VIOLATION); + } + + SectionObject = InvalidPointer; + StartSeh() + Status = MmCreateSection(&SectionObject, 0, NULL, NULL, 0, SEC_RESERVE, NULL, NULL); + EndSeh(STATUS_SUCCESS); + ok_eq_hex(Status, STATUS_INVALID_PAGE_PROTECTION); + ok_eq_pointer(SectionObject, InvalidPointer); + + StartSeh() + Status = MmCreateSection(NULL, 0, NULL, NULL, PAGE_READONLY, SEC_RESERVE, NULL, NULL); + EndSeh(STATUS_ACCESS_VIOLATION); + + SectionObject = InvalidPointer; + StartSeh() + Status = MmCreateSection(&SectionObject, 0, NULL, NULL, PAGE_READONLY, SEC_RESERVE, NULL, NULL); + EndSeh(STATUS_ACCESS_VIOLATION); + ok_eq_pointer(SectionObject, InvalidPointer); + + MaximumSize.QuadPart = 0; + StartSeh() + Status = MmCreateSection(NULL, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_RESERVE, NULL, NULL); + EndSeh(STATUS_SUCCESS); + ok_eq_hex(Status, STATUS_INVALID_PARAMETER_4); + ok_eq_longlong(MaximumSize.QuadPart, 0LL); + + MaximumSize.QuadPart = 1; + StartSeh() + Status = MmCreateSection(NULL, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_RESERVE, NULL, NULL); + EndSeh(STATUS_ACCESS_VIOLATION); + ok_eq_longlong(MaximumSize.QuadPart, 1LL); + + SectionObject = InvalidPointer; + MaximumSize.QuadPart = 0; + StartSeh() + Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_RESERVE, NULL, NULL); + EndSeh(STATUS_SUCCESS); + ok_eq_hex(Status, STATUS_INVALID_PARAMETER_4); + ok_eq_longlong(MaximumSize.QuadPart, 0LL); + ok_eq_pointer(SectionObject, InvalidPointer); + + SectionObject = InvalidPointer; + MaximumSize.QuadPart = 1; + StartSeh() + Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_RESERVE, NULL, NULL); + EndSeh(STATUS_SUCCESS); + ok_eq_hex(Status, STATUS_SUCCESS); + ok_eq_longlong(MaximumSize.QuadPart, 1LL); + ok(SectionObject != InvalidPointer, "Section object pointer untouched\n"); + ok(SectionObject != NULL, "Section object pointer NULL\n"); + + if (SectionObject && SectionObject != InvalidPointer) + ObDereferenceObject(SectionObject); + + SectionObject = InvalidPointer; + MaximumSize.QuadPart = 1; + StartSeh() + Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_IMAGE, NULL, NULL); + EndSeh(STATUS_SUCCESS); + ok_eq_hex(Status, STATUS_INVALID_FILE_FOR_SECTION); + ok_eq_longlong(MaximumSize.QuadPart, 1LL); + ok_eq_pointer(SectionObject, InvalidPointer); +}
Propchange: trunk/rostests/kmtests/ntos_mm/MmSection.c ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/rostests/kmtests/readme.txt URL: http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/readme.txt?rev=536... ============================================================================== --- trunk/rostests/kmtests/readme.txt [iso-8859-1] (original) +++ trunk/rostests/kmtests/readme.txt [iso-8859-1] Sun Sep 11 11:22:00 2011 @@ -7,5 +7,5 @@ examples and templates.
-See http://www.reactos.org/wiki/User:ThFabba/KmtestsHowto for more +See http://www.reactos.org/wiki/KmtestsHowto for more information and a guide on how to use the framework.