mirror of
https://github.com/reactos/reactos.git
synced 2025-07-24 17:03:37 +00:00
[KMTESTS:MM]
- Add tests for ZwAllocateVirtualMemory, ZwCreateSection, ZwMapViewOfSection. Patch by Nikolay Borisov (nib9 at aber dot ac dot uk). - Some tests are currently skipped because they crash or assert on ROS: See ROSTESTS-107, ROSTESTS-108, ROSTESTS-109, ROSTESTS-110. ROSTESTS-105 #resolve svn path=/trunk/; revision=58874
This commit is contained in:
parent
4c309ccd7f
commit
76a1dccfe2
5 changed files with 1615 additions and 0 deletions
|
@ -52,6 +52,9 @@ list(APPEND KMTEST_DRV_SOURCE
|
|||
ntos_ke/KeSpinLock.c
|
||||
ntos_ke/KeTimer.c
|
||||
ntos_mm/MmSection.c
|
||||
ntos_mm/ZwAllocateVirtualMemory.c
|
||||
ntos_mm/ZwCreateSection.c
|
||||
ntos_mm/ZwMapViewOfSection.c
|
||||
ntos_ob/ObReference.c
|
||||
ntos_ob/ObType.c
|
||||
ntos_ob/ObTypes.c
|
||||
|
@ -65,6 +68,7 @@ add_library(kmtest_drv SHARED ${KMTEST_DRV_SOURCE})
|
|||
set_module_type(kmtest_drv kernelmodedriver)
|
||||
target_link_libraries(kmtest_drv kmtest_printf chkstk ${PSEH_LIB})
|
||||
add_importlibs(kmtest_drv ntoskrnl hal)
|
||||
add_dependencies(kmtest_drv bugcodes)
|
||||
add_target_compile_definitions(kmtest_drv KMT_KERNEL_MODE NTDDI_VERSION=NTDDI_WS03SP1)
|
||||
#add_pch(kmtest_drv include/kmt_test.h)
|
||||
|
||||
|
|
|
@ -46,6 +46,9 @@ KMT_TESTFUNC Test_RtlAvlTree;
|
|||
KMT_TESTFUNC Test_RtlException;
|
||||
KMT_TESTFUNC Test_RtlMemory;
|
||||
KMT_TESTFUNC Test_RtlSplayTree;
|
||||
KMT_TESTFUNC Test_ZwAllocateVirtualMemory;
|
||||
KMT_TESTFUNC Test_ZwCreateSection;
|
||||
KMT_TESTFUNC Test_ZwMapViewOfSection;
|
||||
|
||||
const KMT_TEST TestList[] =
|
||||
{
|
||||
|
@ -89,5 +92,8 @@ const KMT_TEST TestList[] =
|
|||
{ "RtlExceptionKM", Test_RtlException },
|
||||
{ "RtlMemoryKM", Test_RtlMemory },
|
||||
{ "RtlSplayTreeKM", Test_RtlSplayTree },
|
||||
{ "ZwAllocateVirtualMemory", Test_ZwAllocateVirtualMemory },
|
||||
{ "ZwCreateSection", Test_ZwCreateSection },
|
||||
{ "ZwMapViewOfSection", Test_ZwMapViewOfSection },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
|
512
rostests/kmtests/ntos_mm/ZwAllocateVirtualMemory.c
Normal file
512
rostests/kmtests/ntos_mm/ZwAllocateVirtualMemory.c
Normal file
|
@ -0,0 +1,512 @@
|
|||
/*
|
||||
* PROJECT: ReactOS kernel-mode tests
|
||||
* LICENSE: GPLv2+ - See COPYING in the top level directory
|
||||
* PURPOSE: Kernel-Mode Test Suite ZwAllocateVirtualMemory/ZwFreeVirtualMemory
|
||||
* PROGRAMMER: Nikolay Borisov <nib9@aber.ac.uk>
|
||||
*/
|
||||
|
||||
#include <kmt_test.h>
|
||||
|
||||
#define ROUND_DOWN(n,align) (((ULONG_PTR)n) & ~((align) - 1l))
|
||||
#define DEFAULT_ALLOC_SIZE 200
|
||||
#define IGNORE -1
|
||||
#define PAGE_NOPROT 0x0 //MEM_RESERVE has this type of "protection"
|
||||
|
||||
/* These are being used in ZwMapViewOfSection as well */
|
||||
const char TestString[] = "TheLongBrownFoxJumpedTheWhiteRabbitTheLongBrownFoxJumpedTheWhiteRabbitTheLongBrownFoxJumpedTheWhiteRabbitTheLongBrownFoxJumpedTheWhiteRabbitTheLongBrownFoxJumpedTheWhiteRabbitTheLongBrownFoxJumpedThe";
|
||||
const SIZE_T TestStringSize = sizeof(TestString);
|
||||
|
||||
VOID Test_ZwAllocateVirtualMemory(VOID);
|
||||
|
||||
typedef struct _TEST_CONTEXT
|
||||
{
|
||||
HANDLE ProcessHandle;
|
||||
ULONG RegionSize;
|
||||
ULONG AllocationType;
|
||||
ULONG Protect;
|
||||
PVOID Bases[1024];
|
||||
SHORT ThreadId;
|
||||
} TEST_CONTEXT, *PTEST_CONTEXT;
|
||||
|
||||
|
||||
#define ALLOC_MEMORY_WITH_FREE(ProcessHandle, BaseAddress, ZeroBits, RegionSize, AllocationType, Protect, RetStatus, FreeStatus) \
|
||||
do { \
|
||||
Status = ZwAllocateVirtualMemory(ProcessHandle, &BaseAddress, ZeroBits, &RegionSize, AllocationType, Protect); \
|
||||
ok_eq_hex(Status, RetStatus); \
|
||||
RegionSize = 0; \
|
||||
Status = ZwFreeVirtualMemory(ProcessHandle, &BaseAddress, &RegionSize, MEM_RELEASE); \
|
||||
if (FreeStatus != IGNORE) ok_eq_hex(Status, FreeStatus); \
|
||||
BaseAddress = NULL; \
|
||||
RegionSize = DEFAULT_ALLOC_SIZE; \
|
||||
} while (0) \
|
||||
|
||||
|
||||
|
||||
static
|
||||
BOOLEAN
|
||||
CheckBuffer(PVOID Buffer, SIZE_T Size, UCHAR Value)
|
||||
{
|
||||
PUCHAR Array = Buffer;
|
||||
SIZE_T i;
|
||||
|
||||
for (i = 0; i < Size; i++)
|
||||
{
|
||||
if (Array[i] != Value)
|
||||
{
|
||||
trace("Expected %x, found %x at offset %lu\n", Value, Array[i], (ULONG)i);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static
|
||||
SIZE_T
|
||||
CheckBufferRead(CONST VOID *Source, CONST VOID *Destination, SIZE_T Length, NTSTATUS ExpectedStatus)
|
||||
{
|
||||
NTSTATUS ExceptionStatus;
|
||||
SIZE_T Match = 0;
|
||||
|
||||
KmtStartSeh()
|
||||
Match = RtlCompareMemory(Source, Destination, Length);
|
||||
KmtEndSeh(ExpectedStatus);
|
||||
|
||||
return Match;
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
CheckBufferReadWrite(PVOID Destination, CONST VOID *Source, SIZE_T Length, NTSTATUS ExpectedStatus)
|
||||
{
|
||||
//do a little bit of writing/reading to memory
|
||||
NTSTATUS ExceptionStatus;
|
||||
SIZE_T Match = 0;
|
||||
|
||||
KmtStartSeh()
|
||||
RtlCopyMemory(Destination, Source, Length);
|
||||
KmtEndSeh(ExpectedStatus);
|
||||
|
||||
Match = CheckBufferRead(Source, Destination, Length, ExpectedStatus);
|
||||
if (ExpectedStatus == STATUS_SUCCESS) ok_eq_int(Match, Length);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
VOID
|
||||
SimpleErrorChecks(VOID)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PVOID Base = NULL;
|
||||
SIZE_T RegionSize = DEFAULT_ALLOC_SIZE;
|
||||
|
||||
//HANDLE TESTS
|
||||
ALLOC_MEMORY_WITH_FREE(NtCurrentProcess(), Base, 0, RegionSize, (MEM_COMMIT | MEM_RESERVE), PAGE_READWRITE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
ALLOC_MEMORY_WITH_FREE(NULL, Base, 0, RegionSize, (MEM_COMMIT | MEM_RESERVE), PAGE_READWRITE, STATUS_INVALID_HANDLE, STATUS_INVALID_HANDLE);
|
||||
ALLOC_MEMORY_WITH_FREE((HANDLE)0xdeadbeef, Base, 0, RegionSize, (MEM_COMMIT | MEM_RESERVE), PAGE_READWRITE, STATUS_INVALID_HANDLE, STATUS_INVALID_HANDLE);
|
||||
|
||||
//BASE ADDRESS TESTS
|
||||
Base = (PVOID)0x00567A20;
|
||||
ALLOC_MEMORY_WITH_FREE(NtCurrentProcess(), Base, 0, RegionSize, (MEM_COMMIT | MEM_RESERVE), PAGE_READWRITE, STATUS_CONFLICTING_ADDRESSES, STATUS_FREE_VM_NOT_AT_BASE);
|
||||
|
||||
Base = (PVOID) 0x60000000;
|
||||
ALLOC_MEMORY_WITH_FREE(NtCurrentProcess(), Base, 0, RegionSize, (MEM_COMMIT | MEM_RESERVE), PAGE_READWRITE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
|
||||
Base = (PVOID)((char *)MmSystemRangeStart + 200);
|
||||
ALLOC_MEMORY_WITH_FREE(NtCurrentProcess(), Base, 0, RegionSize, (MEM_COMMIT | MEM_RESERVE), PAGE_READWRITE, STATUS_INVALID_PARAMETER_2, STATUS_INVALID_PARAMETER_2);
|
||||
|
||||
/* http://jira.reactos.org/browse/CORE-6814 */
|
||||
RegionSize = 0x1000;
|
||||
Base = Test_ZwAllocateVirtualMemory;
|
||||
ALLOC_MEMORY_WITH_FREE(NtCurrentProcess(), Base, 0, RegionSize, MEM_COMMIT, PAGE_READWRITE, STATUS_INVALID_PARAMETER_2, STATUS_INVALID_PARAMETER_2);
|
||||
|
||||
//ZERO BITS TESTS
|
||||
ALLOC_MEMORY_WITH_FREE(NtCurrentProcess(), Base, 21, RegionSize, (MEM_COMMIT | MEM_RESERVE), PAGE_READWRITE, STATUS_NO_MEMORY, STATUS_MEMORY_NOT_ALLOCATED);
|
||||
ALLOC_MEMORY_WITH_FREE(NtCurrentProcess(), Base, 22, RegionSize, (MEM_COMMIT | MEM_RESERVE), PAGE_READWRITE, STATUS_INVALID_PARAMETER_3, STATUS_MEMORY_NOT_ALLOCATED);
|
||||
ALLOC_MEMORY_WITH_FREE(NtCurrentProcess(), Base, -1, RegionSize, (MEM_COMMIT | MEM_RESERVE), PAGE_READWRITE, STATUS_INVALID_PARAMETER_3, STATUS_MEMORY_NOT_ALLOCATED);
|
||||
ALLOC_MEMORY_WITH_FREE(NtCurrentProcess(), Base, 3, RegionSize, (MEM_COMMIT | MEM_RESERVE), PAGE_READWRITE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
|
||||
//REGION SIZE TESTS
|
||||
ALLOC_MEMORY_WITH_FREE(NtCurrentProcess(), Base, 0, RegionSize, (MEM_COMMIT | MEM_RESERVE), PAGE_READWRITE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
RegionSize = -1;
|
||||
ALLOC_MEMORY_WITH_FREE(NtCurrentProcess(), Base, 0, RegionSize, (MEM_COMMIT | MEM_RESERVE), PAGE_READWRITE, STATUS_INVALID_PARAMETER_4, STATUS_MEMORY_NOT_ALLOCATED);
|
||||
RegionSize = 0;
|
||||
ALLOC_MEMORY_WITH_FREE(NtCurrentProcess(), Base, 0, RegionSize, (MEM_COMMIT | MEM_RESERVE), PAGE_READWRITE, STATUS_INVALID_PARAMETER_4, STATUS_MEMORY_NOT_ALLOCATED);
|
||||
RegionSize = 0xFFFFFFFF; // 4 gb is invalid
|
||||
ALLOC_MEMORY_WITH_FREE(NtCurrentProcess(), Base, 0, RegionSize, (MEM_COMMIT | MEM_RESERVE), PAGE_READWRITE, STATUS_INVALID_PARAMETER_4, STATUS_MEMORY_NOT_ALLOCATED);
|
||||
|
||||
//Allocation type tests
|
||||
ALLOC_MEMORY_WITH_FREE(NtCurrentProcess(), Base, 0, RegionSize, MEM_PHYSICAL, PAGE_READWRITE, STATUS_INVALID_PARAMETER_5, STATUS_MEMORY_NOT_ALLOCATED);
|
||||
ALLOC_MEMORY_WITH_FREE(NtCurrentProcess(), Base, 0, RegionSize, (MEM_COMMIT | MEM_RESET), PAGE_READWRITE, STATUS_INVALID_PARAMETER_5, STATUS_MEMORY_NOT_ALLOCATED);
|
||||
ALLOC_MEMORY_WITH_FREE(NtCurrentProcess(), Base, 0, RegionSize, 0, PAGE_READWRITE, STATUS_INVALID_PARAMETER_5, STATUS_MEMORY_NOT_ALLOCATED);
|
||||
ALLOC_MEMORY_WITH_FREE(NtCurrentProcess(), Base, 0, RegionSize, MEM_TOP_DOWN, PAGE_READWRITE, STATUS_INVALID_PARAMETER_5, STATUS_MEMORY_NOT_ALLOCATED);
|
||||
ALLOC_MEMORY_WITH_FREE(NtCurrentProcess(), Base, 0, RegionSize, (MEM_TOP_DOWN | MEM_RESET), PAGE_READWRITE, STATUS_INVALID_PARAMETER_5, STATUS_MEMORY_NOT_ALLOCATED);
|
||||
ALLOC_MEMORY_WITH_FREE(NtCurrentProcess(), Base, 0, RegionSize, (MEM_TOP_DOWN | MEM_COMMIT), PAGE_READWRITE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
ALLOC_MEMORY_WITH_FREE(NtCurrentProcess(), Base, 0, RegionSize, (MEM_PHYSICAL | MEM_RESERVE), PAGE_READWRITE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
ALLOC_MEMORY_WITH_FREE(NtCurrentProcess(), Base, 0, RegionSize, (MEM_PHYSICAL | MEM_COMMIT), PAGE_READWRITE, STATUS_INVALID_PARAMETER_5, STATUS_MEMORY_NOT_ALLOCATED);
|
||||
ALLOC_MEMORY_WITH_FREE(NtCurrentProcess(), Base, 0, RegionSize, (MEM_RESET | MEM_COMMIT | MEM_RESERVE), PAGE_READWRITE, STATUS_INVALID_PARAMETER_5, STATUS_MEMORY_NOT_ALLOCATED);
|
||||
ALLOC_MEMORY_WITH_FREE(NtCurrentProcess(), Base, 0, RegionSize, -1, PAGE_READWRITE, STATUS_INVALID_PARAMETER_5, STATUS_MEMORY_NOT_ALLOCATED);
|
||||
ALLOC_MEMORY_WITH_FREE(NtCurrentProcess(), Base, 0, RegionSize, MEM_COMMIT, PAGE_READWRITE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
ALLOC_MEMORY_WITH_FREE(NtCurrentProcess(), Base, 0, RegionSize, MEM_RESERVE, PAGE_READWRITE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
ALLOC_MEMORY_WITH_FREE(NtCurrentProcess(), Base, 0, RegionSize, MEM_RESERVE, PAGE_WRITECOPY, STATUS_INVALID_PAGE_PROTECTION, STATUS_MEMORY_NOT_ALLOCATED);
|
||||
ALLOC_MEMORY_WITH_FREE(NtCurrentProcess(), Base, 0, RegionSize, MEM_RESERVE, PAGE_EXECUTE_WRITECOPY, STATUS_INVALID_PAGE_PROTECTION, STATUS_MEMORY_NOT_ALLOCATED);
|
||||
|
||||
//Memory protection tests
|
||||
ALLOC_MEMORY_WITH_FREE(NtCurrentProcess(), Base, 0, RegionSize, (MEM_COMMIT | MEM_RESERVE), 0, STATUS_INVALID_PAGE_PROTECTION, STATUS_MEMORY_NOT_ALLOCATED);
|
||||
ALLOC_MEMORY_WITH_FREE(NtCurrentProcess(), Base, 0, RegionSize, (MEM_COMMIT | MEM_RESERVE), -1, STATUS_INVALID_PAGE_PROTECTION, STATUS_MEMORY_NOT_ALLOCATED);
|
||||
if (!KmtIsCheckedBuild)
|
||||
{
|
||||
ALLOC_MEMORY_WITH_FREE(NtCurrentProcess(), Base, 0, RegionSize, (MEM_COMMIT | MEM_RESERVE), (PAGE_NOACCESS | PAGE_GUARD), STATUS_INVALID_PAGE_PROTECTION, STATUS_MEMORY_NOT_ALLOCATED);
|
||||
ALLOC_MEMORY_WITH_FREE(NtCurrentProcess(), Base, 0, RegionSize, (MEM_COMMIT | MEM_RESERVE), (PAGE_NOACCESS | PAGE_WRITECOMBINE), STATUS_INVALID_PAGE_PROTECTION, STATUS_MEMORY_NOT_ALLOCATED);
|
||||
}
|
||||
ALLOC_MEMORY_WITH_FREE(NtCurrentProcess(), Base, 0, RegionSize, (MEM_COMMIT | MEM_RESERVE), (PAGE_READONLY | PAGE_WRITECOMBINE), STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
SimpleAllocation(VOID)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
NTSTATUS ExceptionStatus;
|
||||
PVOID Base = NULL;
|
||||
SIZE_T RegionSize = DEFAULT_ALLOC_SIZE;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//Normal operation
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &Base, 0, &RegionSize, MEM_COMMIT, PAGE_READWRITE);
|
||||
ok_eq_size(RegionSize, 4096);
|
||||
|
||||
//check for the zero-filled pages
|
||||
ok_bool_true(CheckBuffer(Base, RegionSize, 0), "The buffer is not zero-filled");
|
||||
|
||||
CheckBufferReadWrite(Base, TestString, TestStringSize, STATUS_SUCCESS);
|
||||
|
||||
// try freeing
|
||||
RegionSize = 0;
|
||||
Status = ZwFreeVirtualMemory(NtCurrentProcess(), &Base, &RegionSize, MEM_RELEASE);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
ok_eq_size(RegionSize, PAGE_SIZE);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// COMMIT AND RESERVE SCENARIO AND STATE CHANGE
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//reserve and then commit
|
||||
Base = NULL;
|
||||
RegionSize = DEFAULT_ALLOC_SIZE;
|
||||
Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &Base, 0, &RegionSize, MEM_RESERVE, PAGE_READWRITE);
|
||||
Test_NtQueryVirtualMemory(Base, RegionSize, MEM_RESERVE, PAGE_NOPROT);
|
||||
CheckBufferReadWrite(Base, TestString, TestStringSize, STATUS_ACCESS_VIOLATION);
|
||||
|
||||
|
||||
Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &Base, 0, &RegionSize, MEM_COMMIT, PAGE_READWRITE);
|
||||
CheckBufferReadWrite(Base, TestString, TestStringSize, STATUS_SUCCESS);
|
||||
Test_NtQueryVirtualMemory(Base, RegionSize, MEM_COMMIT, PAGE_READWRITE);
|
||||
|
||||
RegionSize = 0;
|
||||
ZwFreeVirtualMemory(NtCurrentProcess(), &Base, &RegionSize, MEM_RELEASE);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// TRY READING/WRITING TO INVALID PROTECTION PAGES
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
RegionSize = DEFAULT_ALLOC_SIZE;
|
||||
Base = NULL;
|
||||
ZwAllocateVirtualMemory(NtCurrentProcess(), &Base, 0, &RegionSize, (MEM_COMMIT | MEM_RESERVE), PAGE_NOACCESS);
|
||||
|
||||
KmtStartSeh()
|
||||
RtlCopyMemory(Base, TestString, TestStringSize);
|
||||
KmtEndSeh(STATUS_ACCESS_VIOLATION);
|
||||
|
||||
Test_NtQueryVirtualMemory(Base, RegionSize, MEM_COMMIT, PAGE_NOACCESS);
|
||||
CheckBufferRead(Base, TestString, TestStringSize, STATUS_ACCESS_VIOLATION);
|
||||
|
||||
RegionSize = 0;
|
||||
ZwFreeVirtualMemory(NtCurrentProcess(), &Base, &RegionSize, MEM_RELEASE);
|
||||
|
||||
ZwAllocateVirtualMemory(NtCurrentProcess(), &Base, 0, &RegionSize, (MEM_COMMIT | MEM_RESERVE), PAGE_READONLY);
|
||||
KmtStartSeh()
|
||||
RtlCopyMemory(Base, TestString, TestStringSize);
|
||||
KmtEndSeh(STATUS_ACCESS_VIOLATION);
|
||||
|
||||
Test_NtQueryVirtualMemory(Base, RegionSize, MEM_COMMIT, PAGE_READONLY);
|
||||
|
||||
ok_bool_true(CheckBuffer(Base, TestStringSize, 0), "Couldn't read a read-only buffer");
|
||||
|
||||
RegionSize = 0;
|
||||
ZwFreeVirtualMemory(NtCurrentProcess(), &Base, &RegionSize, MEM_RELEASE);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// GUARD PAGES
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
/* FIXME: We don't support guard pages. See CORE-6639, ROSTESTS-107 */
|
||||
#ifdef ROSTESTS_107_FIXED
|
||||
RegionSize = 1000;
|
||||
Base = NULL;
|
||||
ZwAllocateVirtualMemory(NtCurrentProcess(), &Base, 0, &RegionSize, (MEM_COMMIT | MEM_RESERVE), (PAGE_GUARD | PAGE_READWRITE));
|
||||
|
||||
Test_NtQueryVirtualMemory(Base, RegionSize, MEM_COMMIT, (PAGE_GUARD | PAGE_READWRITE));
|
||||
KmtStartSeh()
|
||||
RtlCopyMemory(Base, TestString, TestStringSize);
|
||||
KmtEndSeh(STATUS_GUARD_PAGE_VIOLATION);
|
||||
|
||||
Test_NtQueryVirtualMemory(Base, RegionSize, MEM_COMMIT, PAGE_READWRITE);
|
||||
|
||||
KmtStartSeh()
|
||||
RtlCopyMemory(Base, TestString, TestStringSize);
|
||||
KmtEndSeh(STATUS_SUCCESS);
|
||||
|
||||
RegionSize = 0;
|
||||
ZwFreeVirtualMemory(NtCurrentProcess(), &Base, &RegionSize, MEM_RELEASE);
|
||||
#endif /* ROSTESTS_107_FIXED */
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
VOID
|
||||
CustomBaseAllocation(VOID)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
SIZE_T RegionSize = 200;
|
||||
PVOID Base = (PVOID) 0x60025000;
|
||||
PVOID ActualStartingAddress = (PVOID)ROUND_DOWN(Base, MM_ALLOCATION_GRANULARITY); //it is rounded down to the nearest allocation granularity (64k) address
|
||||
PVOID EndingAddress = (PVOID)(((ULONG_PTR)Base + RegionSize - 1) | (PAGE_SIZE - 1));
|
||||
SIZE_T ActualSize = BYTES_TO_PAGES((ULONG_PTR)EndingAddress - (ULONG_PTR)ActualStartingAddress) * PAGE_SIZE; //calculates the actual size based on the required pages
|
||||
|
||||
// allocate the memory
|
||||
Status = ZwAllocateVirtualMemory(NtCurrentProcess(), (PVOID *)&Base, 0, &RegionSize, (MEM_COMMIT | MEM_RESERVE), PAGE_READWRITE);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
ok_eq_size(RegionSize, ActualSize);
|
||||
ok_eq_ulong(Base, ActualStartingAddress);
|
||||
Test_NtQueryVirtualMemory(ActualStartingAddress, ActualSize, MEM_COMMIT, PAGE_READWRITE);
|
||||
|
||||
// try freeing
|
||||
RegionSize = 0;
|
||||
Status = ZwFreeVirtualMemory(NtCurrentProcess(), (PVOID *)&Base, &RegionSize, MEM_RELEASE);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
ok_eq_ulong(RegionSize, ActualSize);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
StressTesting(ULONG AllocationType)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
NTSTATUS ReturnStatus = STATUS_SUCCESS;
|
||||
static PVOID bases[1024]; //assume we are going to allocate only 5 gigs. static here means the arrays is not allocated on the stack but in the BSS segment of the driver
|
||||
ULONG Index = 0;
|
||||
PVOID Base = NULL;
|
||||
SIZE_T RegionSize = 5 * 1024 * 1024; // 5 megabytes;
|
||||
|
||||
RtlZeroMemory(bases, sizeof(bases));
|
||||
|
||||
for (Index = 0; Index < RTL_NUMBER_OF(bases) && NT_SUCCESS(Status); Index++)
|
||||
{
|
||||
Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &Base, 0, &RegionSize, AllocationType, PAGE_READWRITE);
|
||||
|
||||
bases[Index] = Base;
|
||||
if ((Index % 10) == 0)
|
||||
{
|
||||
if (AllocationType == MEM_COMMIT && NT_SUCCESS(Status))
|
||||
{
|
||||
CheckBufferReadWrite(Base, TestString, TestStringSize, STATUS_SUCCESS);
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckBufferReadWrite(Base, TestString, TestStringSize, STATUS_ACCESS_VIOLATION);
|
||||
}
|
||||
}
|
||||
|
||||
Base = NULL;
|
||||
}
|
||||
|
||||
trace("Finished reserving. Error code %x. Chunks allocated: %d\n", Status, Index );
|
||||
|
||||
ReturnStatus = Status;
|
||||
|
||||
//free the allocated memory so that we can continue with the tests
|
||||
Status = STATUS_SUCCESS;
|
||||
Index = 0;
|
||||
while (NT_SUCCESS(Status) && Index < RTL_NUMBER_OF(bases))
|
||||
{
|
||||
RegionSize = 0;
|
||||
Status = ZwFreeVirtualMemory(NtCurrentProcess(), &bases[Index], &RegionSize, MEM_RELEASE);
|
||||
bases[Index++] = NULL;
|
||||
}
|
||||
|
||||
return ReturnStatus;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
VOID
|
||||
NTAPI
|
||||
SystemProcessTestWorker(PVOID StartContext)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PTEST_CONTEXT Context = (PTEST_CONTEXT)StartContext;
|
||||
ULONG Index = 0;
|
||||
PVOID Base = NULL;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
RtlZeroMemory(Context->Bases, sizeof(Context->Bases));
|
||||
|
||||
Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &Base, 0, &Context->RegionSize, Context->AllocationType, Context->Protect);
|
||||
ZwFreeVirtualMemory(NtCurrentProcess(), &Base, &Context->RegionSize, MEM_RELEASE);
|
||||
Base = NULL;
|
||||
|
||||
//if the previous allocation has failed there is no need to do the loop
|
||||
while (NT_SUCCESS(Status) && Index < RTL_NUMBER_OF(Context->Bases))
|
||||
{
|
||||
Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &Base, 0, &Context->RegionSize, Context->AllocationType, Context->Protect);
|
||||
|
||||
Context->Bases[Index] = Base;
|
||||
if ((Index % 10) == 0)
|
||||
{
|
||||
if (Context->AllocationType == MEM_COMMIT)
|
||||
{
|
||||
CheckBufferReadWrite(Base, TestString, TestStringSize, STATUS_SUCCESS);
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckBufferReadWrite(Base, TestString, TestStringSize, STATUS_ACCESS_VIOLATION);
|
||||
}
|
||||
}
|
||||
|
||||
Base = NULL;
|
||||
Index++;
|
||||
}
|
||||
|
||||
trace("[SYSTEM THREAD %d]. Error code %x. Chunks allocated: %d\n", Context->ThreadId, Status, Index);
|
||||
|
||||
//free the allocated memory so that we can continue with the tests
|
||||
Status = STATUS_SUCCESS;
|
||||
Index = 0;
|
||||
while (NT_SUCCESS(Status) && Index < RTL_NUMBER_OF(Context->Bases))
|
||||
{
|
||||
Context->RegionSize = 0;
|
||||
Status = ZwFreeVirtualMemory(NtCurrentProcess(), &Context->Bases[Index], &Context->RegionSize, MEM_RELEASE);
|
||||
Context->Bases[Index++] = NULL;
|
||||
}
|
||||
|
||||
PsTerminateSystemThread(Status);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
VOID
|
||||
KmtInitTestContext(PTEST_CONTEXT Ctx, SHORT ThreadId, ULONG RegionSize, ULONG AllocationType, ULONG Protect)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
Ctx->AllocationType = AllocationType;
|
||||
Ctx->Protect = Protect;
|
||||
Ctx->RegionSize = RegionSize;
|
||||
Ctx->ThreadId = ThreadId;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
VOID
|
||||
SystemProcessTest(VOID)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
HANDLE Thread1 = INVALID_HANDLE_VALUE;
|
||||
HANDLE Thread2 = INVALID_HANDLE_VALUE;
|
||||
PVOID ThreadObjects[2] = { NULL };
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
PTEST_CONTEXT StartContext1;
|
||||
PTEST_CONTEXT StartContext2;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
StartContext1 = ExAllocatePoolWithTag(PagedPool, sizeof(TEST_CONTEXT), 'tXTC');
|
||||
StartContext2 = ExAllocatePoolWithTag(PagedPool, sizeof(TEST_CONTEXT), 'tXTC');
|
||||
if (StartContext1 == NULL || StartContext2 == NULL)
|
||||
{
|
||||
trace("Error allocating space for context structs\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
KmtInitTestContext(StartContext1, 1, 1 * 1024 * 1024, MEM_COMMIT, PAGE_READWRITE);
|
||||
KmtInitTestContext(StartContext2, 2, 3 * 1024 * 1024, MEM_COMMIT, PAGE_READWRITE);
|
||||
InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
|
||||
|
||||
Status = PsCreateSystemThread(&Thread1, THREAD_ALL_ACCESS, &ObjectAttributes, NULL, NULL, SystemProcessTestWorker, StartContext1);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
trace("Error creating thread1\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
Status = ObReferenceObjectByHandle(Thread1, THREAD_ALL_ACCESS, PsThreadType, KernelMode, &ThreadObjects[0], NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
trace("error referencing thread1\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
Status = PsCreateSystemThread(&Thread2, THREAD_ALL_ACCESS, &ObjectAttributes, NULL, NULL, SystemProcessTestWorker, StartContext2);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
trace("Error creating thread2\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
Status = ObReferenceObjectByHandle(Thread2, THREAD_ALL_ACCESS, PsThreadType, KernelMode, &ThreadObjects[1], NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
trace("error referencing thread2\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
||||
if (ThreadObjects[0])
|
||||
Status = KeWaitForSingleObject(ThreadObjects[0], Executive, KernelMode, FALSE, NULL);
|
||||
|
||||
if (StartContext1 != NULL)
|
||||
ExFreePoolWithTag(StartContext1, 'tXTC');
|
||||
|
||||
if (ThreadObjects[1])
|
||||
Status = KeWaitForSingleObject(ThreadObjects[1], Executive, KernelMode, FALSE, NULL);
|
||||
|
||||
if (StartContext2 != NULL)
|
||||
ExFreePoolWithTag(StartContext2, 'tXTC');
|
||||
|
||||
if (ThreadObjects[0] != NULL)
|
||||
ObDereferenceObject(ThreadObjects[0]);
|
||||
|
||||
if (ThreadObjects[1] != NULL)
|
||||
ObDereferenceObject(ThreadObjects[1]);
|
||||
|
||||
if (Thread1 != INVALID_HANDLE_VALUE)
|
||||
ZwClose(Thread1);
|
||||
|
||||
if (Thread2 != INVALID_HANDLE_VALUE)
|
||||
ZwClose(Thread2);
|
||||
}
|
||||
|
||||
|
||||
START_TEST(ZwAllocateVirtualMemory)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
SimpleErrorChecks();
|
||||
|
||||
SimpleAllocation();
|
||||
|
||||
CustomBaseAllocation();
|
||||
|
||||
Status = StressTesting(MEM_RESERVE);
|
||||
ok_eq_hex(Status, STATUS_NO_MEMORY);
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
Status = StressTesting(MEM_COMMIT);
|
||||
ok_eq_hex(Status, STATUS_COMMITMENT_LIMIT);
|
||||
|
||||
SystemProcessTest();
|
||||
}
|
525
rostests/kmtests/ntos_mm/ZwCreateSection.c
Normal file
525
rostests/kmtests/ntos_mm/ZwCreateSection.c
Normal file
|
@ -0,0 +1,525 @@
|
|||
/*
|
||||
* PROJECT: ReactOS kernel-mode tests
|
||||
* LICENSE: GPLv2+ - See COPYING in the top level directory
|
||||
* PURPOSE: Kernel-Mode Test Suite ZwCreateSection
|
||||
* PROGRAMMER: Nikolay Borisov <nib9@aber.ac.uk>
|
||||
*/
|
||||
|
||||
#include <kmt_test.h>
|
||||
|
||||
#define IGNORE -999
|
||||
#define NO_HANDLE_CLOSE -998
|
||||
#define _4mb 4194304
|
||||
extern const char TestString[];
|
||||
extern const SIZE_T TestStringSize;
|
||||
static UNICODE_STRING FileReadOnlyPath = RTL_CONSTANT_STRING(L"\\SystemRoot\\system32\\ntdll.dll");
|
||||
static UNICODE_STRING WritableFilePath = RTL_CONSTANT_STRING(L"\\SystemRoot\\kmtest-MmSection.txt");
|
||||
static UNICODE_STRING CalcImgPath = RTL_CONSTANT_STRING(L"\\SystemRoot\\system32\\calc.exe");
|
||||
static OBJECT_ATTRIBUTES NtdllObject;
|
||||
static OBJECT_ATTRIBUTES KmtestFileObject;
|
||||
static OBJECT_ATTRIBUTES CalcFileObject;
|
||||
|
||||
#define CREATE_SECTION(Handle, DesiredAccess, Attributes, Size, SectionPageProtection, AllocationAttributes, FileHandle, RetStatus, CloseRetStatus) do \
|
||||
{ \
|
||||
Status = ZwCreateSection(&Handle, DesiredAccess, Attributes, &Size, SectionPageProtection, AllocationAttributes, FileHandle); \
|
||||
ok_eq_hex(Status, RetStatus); \
|
||||
if (NT_SUCCESS(Status)) \
|
||||
{ \
|
||||
if (CloseRetStatus != NO_HANDLE_CLOSE) \
|
||||
{ \
|
||||
Status = ZwClose(Handle); \
|
||||
Handle = NULL; \
|
||||
if (CloseRetStatus != IGNORE) ok_eq_hex(Status, CloseRetStatus); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define TestMapView(SectionHandle, ProcessHandle, BaseAddress2, ZeroBits, CommitSize, SectionOffset, ViewSize2, InheritDisposition, AllocationType, Win32Protect, MapStatus, UnmapStatus) do \
|
||||
{ \
|
||||
Status = ZwMapViewOfSection(SectionHandle, ProcessHandle, BaseAddress2, ZeroBits, CommitSize, SectionOffset, ViewSize2, InheritDisposition, AllocationType, Win32Protect); \
|
||||
ok_eq_hex(Status, MapStatus); \
|
||||
if (NT_SUCCESS(Status)) \
|
||||
{ \
|
||||
Status = ZwUnmapViewOfSection(ProcessHandle, BaseAddress); \
|
||||
if (UnmapStatus != IGNORE) ok_eq_hex(Status, UnmapStatus); \
|
||||
*BaseAddress2 = NULL; \
|
||||
*ViewSize2 = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define CheckObject(Handle, Pointers, Handles) do \
|
||||
{ \
|
||||
PUBLIC_OBJECT_BASIC_INFORMATION ObjectInfo; \
|
||||
Status = ZwQueryObject(Handle, ObjectBasicInformation, \
|
||||
&ObjectInfo, sizeof ObjectInfo, NULL); \
|
||||
ok_eq_hex(Status, STATUS_SUCCESS); \
|
||||
ok_eq_ulong(ObjectInfo.PointerCount, Pointers); \
|
||||
ok_eq_ulong(ObjectInfo.HandleCount, Handles); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define CheckSection(SectionHandle, SectionFlag, SectionSize, RetStatus) do \
|
||||
{ \
|
||||
SECTION_BASIC_INFORMATION Sbi; \
|
||||
NTSTATUS Status; \
|
||||
Status = ZwQuerySection(SectionHandle, SectionBasicInformation, \
|
||||
&Sbi, sizeof Sbi, NULL); \
|
||||
ok_eq_hex(Status, RetStatus); \
|
||||
if (RetStatus == STATUS_SUCCESS && NT_SUCCESS(Status)) \
|
||||
{ \
|
||||
ok_eq_pointer(Sbi.BaseAddress, NULL); \
|
||||
ok_eq_longlong(Sbi.Size.QuadPart, SectionSize); \
|
||||
ok_eq_hex(Sbi.Attributes, SectionFlag | SEC_FILE); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static
|
||||
VOID
|
||||
FileSectionViewPermissionCheck(HANDLE ReadOnlyFile, HANDLE WriteOnlyFile, HANDLE ExecutableFile)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
HANDLE SectionHandle = NULL;
|
||||
PVOID BaseAddress = NULL;
|
||||
SIZE_T ViewSize = 0;
|
||||
LARGE_INTEGER MaximumSize;
|
||||
|
||||
MaximumSize.QuadPart = TestStringSize;
|
||||
|
||||
//READ-ONLY FILE COMBINATIONS
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_READ, NULL, MaximumSize, PAGE_READONLY, SEC_COMMIT, ReadOnlyFile, STATUS_SUCCESS, NO_HANDLE_CLOSE);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READONLY, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_EXECUTE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
ZwClose(SectionHandle);
|
||||
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_READ, NULL, MaximumSize, PAGE_READWRITE, SEC_COMMIT, ReadOnlyFile, STATUS_SUCCESS, NO_HANDLE_CLOSE);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READONLY, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_EXECUTE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
ZwClose(SectionHandle);
|
||||
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_READ, NULL, MaximumSize, PAGE_EXECUTE, SEC_COMMIT, ReadOnlyFile, STATUS_SUCCESS, NO_HANDLE_CLOSE);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READONLY, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_EXECUTE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
ZwClose(SectionHandle);
|
||||
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_READ, NULL, MaximumSize, PAGE_WRITECOPY, SEC_COMMIT, ReadOnlyFile, STATUS_SUCCESS, NO_HANDLE_CLOSE);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READONLY, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_EXECUTE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
ZwClose(SectionHandle);
|
||||
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_WRITE, NULL, MaximumSize, PAGE_READONLY, SEC_COMMIT, ReadOnlyFile, STATUS_SUCCESS, NO_HANDLE_CLOSE);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READONLY, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_EXECUTE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
ZwClose(SectionHandle);
|
||||
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_WRITE, NULL, MaximumSize, PAGE_READWRITE, SEC_COMMIT, ReadOnlyFile, STATUS_SUCCESS, NO_HANDLE_CLOSE);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READONLY, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_EXECUTE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
ZwClose(SectionHandle);
|
||||
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_WRITE, NULL, MaximumSize, PAGE_EXECUTE, SEC_COMMIT, ReadOnlyFile, STATUS_SUCCESS, NO_HANDLE_CLOSE);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READONLY, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_EXECUTE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
ZwClose(SectionHandle);
|
||||
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_WRITE, NULL, MaximumSize, PAGE_WRITECOPY, SEC_COMMIT, ReadOnlyFile, STATUS_SUCCESS, NO_HANDLE_CLOSE);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READONLY, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_EXECUTE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
ZwClose(SectionHandle);
|
||||
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_EXECUTE, NULL, MaximumSize, PAGE_READONLY, SEC_COMMIT, ReadOnlyFile, STATUS_SUCCESS, NO_HANDLE_CLOSE);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READONLY, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_EXECUTE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
ZwClose(SectionHandle);
|
||||
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_EXECUTE, NULL, MaximumSize, PAGE_READWRITE, SEC_COMMIT, ReadOnlyFile, STATUS_SUCCESS, NO_HANDLE_CLOSE);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READONLY, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_EXECUTE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
ZwClose(SectionHandle);
|
||||
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_EXECUTE, NULL, MaximumSize, PAGE_EXECUTE, SEC_COMMIT, ReadOnlyFile, STATUS_SUCCESS, NO_HANDLE_CLOSE);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READONLY, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_EXECUTE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
ZwClose(SectionHandle);
|
||||
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_EXECUTE, NULL, MaximumSize, PAGE_WRITECOPY, SEC_COMMIT, ReadOnlyFile, STATUS_SUCCESS, NO_HANDLE_CLOSE);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READONLY, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_EXECUTE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
ZwClose(SectionHandle);
|
||||
|
||||
//WRITE-ONLY FILE COMBINATIONS
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_READ, NULL, MaximumSize, PAGE_READONLY, SEC_COMMIT, WriteOnlyFile, STATUS_SUCCESS, NO_HANDLE_CLOSE);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READONLY, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_EXECUTE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
ZwClose(SectionHandle);
|
||||
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_READ, NULL, MaximumSize, PAGE_READWRITE, SEC_COMMIT, WriteOnlyFile, STATUS_SUCCESS, NO_HANDLE_CLOSE);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READONLY, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_EXECUTE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
ZwClose(SectionHandle);
|
||||
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_READ, NULL, MaximumSize, PAGE_EXECUTE, SEC_COMMIT, WriteOnlyFile, STATUS_SUCCESS, NO_HANDLE_CLOSE);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READONLY, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_EXECUTE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
ZwClose(SectionHandle);
|
||||
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_READ, NULL, MaximumSize, PAGE_WRITECOPY, SEC_COMMIT, WriteOnlyFile, STATUS_SUCCESS, NO_HANDLE_CLOSE);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READONLY, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_EXECUTE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
ZwClose(SectionHandle);
|
||||
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_WRITE, NULL, MaximumSize, PAGE_READONLY, SEC_COMMIT, WriteOnlyFile, STATUS_SUCCESS, NO_HANDLE_CLOSE);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READONLY, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_EXECUTE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
ZwClose(SectionHandle);
|
||||
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_WRITE, NULL, MaximumSize, PAGE_READWRITE, SEC_COMMIT, WriteOnlyFile, STATUS_SUCCESS, NO_HANDLE_CLOSE);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READONLY, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_EXECUTE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
ZwClose(SectionHandle);
|
||||
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_WRITE, NULL, MaximumSize, PAGE_EXECUTE, SEC_COMMIT, WriteOnlyFile, STATUS_SUCCESS, NO_HANDLE_CLOSE);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READONLY, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_EXECUTE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
ZwClose(SectionHandle);
|
||||
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_WRITE, NULL, MaximumSize, PAGE_WRITECOPY, SEC_COMMIT, WriteOnlyFile, STATUS_SUCCESS, NO_HANDLE_CLOSE);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READONLY, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_EXECUTE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
ZwClose(SectionHandle);
|
||||
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_EXECUTE, NULL, MaximumSize, PAGE_READONLY, SEC_COMMIT, WriteOnlyFile, STATUS_SUCCESS, NO_HANDLE_CLOSE);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READONLY, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_EXECUTE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
ZwClose(SectionHandle);
|
||||
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_EXECUTE, NULL, MaximumSize, PAGE_READWRITE, SEC_COMMIT, WriteOnlyFile, STATUS_SUCCESS, NO_HANDLE_CLOSE);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READONLY, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_EXECUTE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
ZwClose(SectionHandle);
|
||||
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_EXECUTE, NULL, MaximumSize, PAGE_EXECUTE, SEC_COMMIT, WriteOnlyFile, STATUS_SUCCESS, NO_HANDLE_CLOSE);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READONLY, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_EXECUTE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
ZwClose(SectionHandle);
|
||||
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_EXECUTE, NULL, MaximumSize, PAGE_WRITECOPY, SEC_COMMIT, WriteOnlyFile, STATUS_SUCCESS, NO_HANDLE_CLOSE);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READONLY, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(SectionHandle, ZwCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_EXECUTE, STATUS_SECTION_PROTECTION, STATUS_SUCCESS);
|
||||
ZwClose(SectionHandle);
|
||||
|
||||
//EXECUTE ONLY FILE
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_READ, NULL, MaximumSize, PAGE_READONLY, SEC_COMMIT, ExecutableFile, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_READ, NULL, MaximumSize, PAGE_READWRITE, SEC_COMMIT, ExecutableFile, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_READ, NULL, MaximumSize, PAGE_EXECUTE, SEC_COMMIT, ExecutableFile, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_READ, NULL, MaximumSize, PAGE_WRITECOPY, SEC_COMMIT, ExecutableFile, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_WRITE, NULL, MaximumSize, PAGE_READONLY, SEC_COMMIT, ExecutableFile, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_WRITE, NULL, MaximumSize, PAGE_READWRITE, SEC_COMMIT, ExecutableFile, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_WRITE, NULL, MaximumSize, PAGE_EXECUTE, SEC_COMMIT, ExecutableFile, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_WRITE, NULL, MaximumSize, PAGE_WRITECOPY, SEC_COMMIT, ExecutableFile, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_EXECUTE, NULL, MaximumSize, PAGE_READONLY, SEC_COMMIT, ExecutableFile, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_EXECUTE, NULL, MaximumSize, PAGE_READWRITE, SEC_COMMIT, ExecutableFile, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_EXECUTE, NULL, MaximumSize, PAGE_EXECUTE, SEC_COMMIT, ExecutableFile, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(SectionHandle, SECTION_MAP_EXECUTE, NULL, MaximumSize, PAGE_WRITECOPY, SEC_COMMIT, ExecutableFile, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
KmtInitTestFiles(PHANDLE ReadOnlyFile, PHANDLE WriteOnlyFile, PHANDLE ExecutableFile)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
LARGE_INTEGER FileOffset;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
|
||||
//INIT THE READ-ONLY FILE
|
||||
Status = ZwCreateFile(ReadOnlyFile, ( GENERIC_READ | GENERIC_EXECUTE ), &NtdllObject, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, FILE_NON_DIRECTORY_FILE, NULL, 0);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
ok(*ReadOnlyFile != NULL, "Couldn't acquire READONLY handle\n");
|
||||
|
||||
//INIT THE EXECUTABLE FILE
|
||||
Status = ZwCreateFile(ExecutableFile, GENERIC_EXECUTE, &CalcFileObject, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, FILE_NON_DIRECTORY_FILE, NULL, 0);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
ok(*ExecutableFile != NULL, "Couldn't acquire EXECUTE handle\n");
|
||||
|
||||
//INIT THE WRITE-ONLY FILE
|
||||
//NB: this file is deleted at the end of basic behavior checks
|
||||
Status = ZwCreateFile(WriteOnlyFile, (GENERIC_WRITE | SYNCHRONIZE), &KmtestFileObject, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_WRITE, FILE_SUPERSEDE, FILE_NON_DIRECTORY_FILE, NULL, 0);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
ok_eq_ulongptr(IoStatusBlock.Information, FILE_CREATED);
|
||||
ok(*WriteOnlyFile != NULL, "WriteOnlyFile is NULL\n");
|
||||
if (*WriteOnlyFile)
|
||||
{
|
||||
FileOffset.QuadPart = 0;
|
||||
Status = ZwWriteFile(*WriteOnlyFile, NULL, NULL, NULL, &IoStatusBlock, (PVOID)TestString, TestStringSize, &FileOffset, NULL);
|
||||
ok(Status == STATUS_SUCCESS || Status == STATUS_PENDING, "Status = 0x%08lx\n", Status);
|
||||
Status = ZwWaitForSingleObject(*WriteOnlyFile, FALSE, NULL);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
ok_eq_ulongptr(IoStatusBlock.Information, TestStringSize);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
SimpleErrorChecks(HANDLE FileHandleReadOnly, HANDLE FileHandleWriteOnly, HANDLE FileHandleExecuteOnly)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
HANDLE Section = NULL;
|
||||
OBJECT_ATTRIBUTES ObjectAttributesReadOnly;
|
||||
OBJECT_ATTRIBUTES ObjectAttributesWriteOnly;
|
||||
OBJECT_ATTRIBUTES InvalidObjectAttributes;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
FILE_STANDARD_INFORMATION FileStandardInfo;
|
||||
LARGE_INTEGER MaximumSize;
|
||||
UNICODE_STRING SectReadOnly = RTL_CONSTANT_STRING(L"\\BaseNamedObjects\\KmtTestReadSect");
|
||||
UNICODE_STRING SectWriteOnly = RTL_CONSTANT_STRING(L"\\BaseNamedObjects\\KmtTestWriteSect");
|
||||
UNICODE_STRING InvalidObjectString = RTL_CONSTANT_STRING(L"THIS/IS/INVALID");
|
||||
|
||||
MaximumSize.QuadPart = TestStringSize;
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributesReadOnly, &SectReadOnly, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
|
||||
InitializeObjectAttributes(&ObjectAttributesWriteOnly, &SectWriteOnly, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
|
||||
InitializeObjectAttributes(&InvalidObjectAttributes, &InvalidObjectString, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//PAGE FILE BACKED SECTION
|
||||
//DESIRED ACCESS TESTS
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READWRITE, SEC_COMMIT, NULL, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(Section, 0, NULL, MaximumSize, PAGE_READWRITE, SEC_COMMIT, NULL, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(Section, -1, NULL, MaximumSize, PAGE_READWRITE, SEC_COMMIT, NULL, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
|
||||
//OBJECT ATTRIBUTES
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, &ObjectAttributesReadOnly, MaximumSize, PAGE_READWRITE, SEC_COMMIT, NULL, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, &InvalidObjectAttributes, MaximumSize, PAGE_READWRITE, SEC_COMMIT, NULL, STATUS_OBJECT_PATH_SYNTAX_BAD, STATUS_SUCCESS);
|
||||
|
||||
//MAXIMUM SIZE
|
||||
MaximumSize.QuadPart = -1;
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READWRITE, SEC_COMMIT, NULL, STATUS_SECTION_TOO_BIG, IGNORE);
|
||||
|
||||
MaximumSize.QuadPart = 0;
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READWRITE, SEC_COMMIT, NULL, STATUS_INVALID_PARAMETER_4, IGNORE);
|
||||
|
||||
//division by zero in ROS
|
||||
if (!skip(SharedUserData->LargePageMinimum > 0, "LargePageMinimum is 0"))
|
||||
{
|
||||
MaximumSize.QuadPart = (_4mb / SharedUserData->LargePageMinimum) * SharedUserData->LargePageMinimum; //4mb
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READWRITE, (SEC_LARGE_PAGES | SEC_COMMIT), NULL, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
MaximumSize.QuadPart = TestStringSize;
|
||||
|
||||
//SECTION PAGE PROTECTION
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_EXECUTE_READ, SEC_COMMIT, NULL, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_EXECUTE_READWRITE, SEC_COMMIT, NULL, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_EXECUTE_WRITECOPY, SEC_COMMIT, NULL, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READONLY, SEC_COMMIT, NULL, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, (PAGE_EXECUTE_READ | PAGE_READWRITE), SEC_COMMIT, NULL, STATUS_INVALID_PAGE_PROTECTION, IGNORE);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, (PAGE_READONLY | PAGE_READWRITE), SEC_COMMIT, NULL, STATUS_INVALID_PAGE_PROTECTION, IGNORE);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, (PAGE_WRITECOPY | PAGE_READONLY), SEC_COMMIT, NULL, STATUS_INVALID_PAGE_PROTECTION, IGNORE);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, 0, SEC_COMMIT, NULL, STATUS_INVALID_PAGE_PROTECTION, STATUS_SUCCESS);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, -1, SEC_COMMIT, NULL, STATUS_INVALID_PAGE_PROTECTION, STATUS_SUCCESS);
|
||||
|
||||
//ALLOCATION ATTRIBUTES
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READWRITE, 0, NULL, STATUS_INVALID_PARAMETER_6, IGNORE);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READWRITE, (SEC_COMMIT | SEC_RESERVE), NULL, STATUS_INVALID_PARAMETER_6, IGNORE);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READWRITE, SEC_RESERVE, NULL, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READWRITE, SEC_IMAGE, NULL, STATUS_INVALID_FILE_FOR_SECTION, IGNORE);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READWRITE, (SEC_IMAGE | SEC_COMMIT), NULL, STATUS_INVALID_PARAMETER_6, IGNORE);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READWRITE, -1, NULL, STATUS_INVALID_PARAMETER_6, IGNORE);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READWRITE, SEC_LARGE_PAGES, NULL, STATUS_INVALID_PARAMETER_6, IGNORE);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READWRITE, (SEC_LARGE_PAGES | SEC_COMMIT), NULL, STATUS_INVALID_PARAMETER_4, IGNORE);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READWRITE, SEC_NOCACHE, NULL, STATUS_INVALID_PARAMETER_6, IGNORE);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READWRITE, (SEC_NOCACHE | SEC_RESERVE | SEC_COMMIT), NULL, STATUS_INVALID_PARAMETER_6, IGNORE);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READWRITE, (SEC_NOCACHE | SEC_COMMIT), NULL, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READWRITE, (SEC_NOCACHE | SEC_RESERVE), NULL, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//NORMAL FILE-BACKED SECTION
|
||||
|
||||
//DESIRED ACCESS TESTS
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, &ObjectAttributesReadOnly, MaximumSize, PAGE_READONLY, SEC_COMMIT, FileHandleReadOnly, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, &ObjectAttributesWriteOnly, MaximumSize, PAGE_WRITECOPY, SEC_COMMIT, FileHandleWriteOnly, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(Section, SECTION_MAP_WRITE, &ObjectAttributesReadOnly, MaximumSize, PAGE_READONLY, SEC_COMMIT, FileHandleReadOnly, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(Section, SECTION_MAP_READ, &ObjectAttributesWriteOnly, MaximumSize, PAGE_WRITECOPY, SEC_COMMIT, FileHandleWriteOnly, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
|
||||
//Object Attributes
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READONLY, SEC_COMMIT, FileHandleReadOnly, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, &InvalidObjectAttributes, MaximumSize, PAGE_READONLY, SEC_COMMIT, FileHandleReadOnly, STATUS_OBJECT_PATH_SYNTAX_BAD, IGNORE);
|
||||
|
||||
//MAXIMUM SIZE
|
||||
MaximumSize.QuadPart = TestStringSize - 100;
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READONLY, SEC_COMMIT, FileHandleWriteOnly, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
|
||||
MaximumSize.QuadPart = -1;
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READONLY, SEC_COMMIT, FileHandleWriteOnly, STATUS_SECTION_TOO_BIG, IGNORE);
|
||||
|
||||
MaximumSize.QuadPart = TestStringSize + 1;
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READONLY, SEC_COMMIT, FileHandleWriteOnly, STATUS_SECTION_TOO_BIG, IGNORE);
|
||||
|
||||
MaximumSize.QuadPart = 0;
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READONLY, SEC_COMMIT, FileHandleWriteOnly, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
|
||||
//SECTION PAGE PROTECTION
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_EXECUTE_READ, SEC_COMMIT, FileHandleWriteOnly, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_EXECUTE_READWRITE, SEC_COMMIT, FileHandleWriteOnly, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_EXECUTE_WRITECOPY, SEC_COMMIT, FileHandleWriteOnly, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READONLY, SEC_COMMIT, FileHandleWriteOnly, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, (PAGE_EXECUTE_READ | PAGE_READWRITE), SEC_COMMIT, FileHandleWriteOnly, STATUS_INVALID_PAGE_PROTECTION, IGNORE);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, (PAGE_READONLY | PAGE_READWRITE), SEC_COMMIT, FileHandleWriteOnly, STATUS_INVALID_PAGE_PROTECTION, IGNORE);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, (PAGE_WRITECOPY | PAGE_READONLY), SEC_COMMIT, FileHandleWriteOnly, STATUS_INVALID_PAGE_PROTECTION, IGNORE);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, 0, SEC_COMMIT, FileHandleWriteOnly, STATUS_INVALID_PAGE_PROTECTION, STATUS_SUCCESS);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, -1, SEC_COMMIT, FileHandleWriteOnly, STATUS_INVALID_PAGE_PROTECTION, STATUS_SUCCESS);
|
||||
|
||||
//allocation type
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READWRITE, 0, FileHandleWriteOnly, STATUS_INVALID_PARAMETER_6, IGNORE);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READWRITE, (SEC_COMMIT | SEC_RESERVE), FileHandleWriteOnly, STATUS_INVALID_PARAMETER_6, IGNORE);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READWRITE, SEC_RESERVE, FileHandleWriteOnly, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READWRITE, (SEC_IMAGE | SEC_COMMIT), FileHandleWriteOnly, STATUS_INVALID_PARAMETER_6, IGNORE);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READWRITE, -1, FileHandleWriteOnly, STATUS_INVALID_PARAMETER_6, IGNORE);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READWRITE, SEC_LARGE_PAGES, FileHandleWriteOnly, STATUS_INVALID_PARAMETER_6, IGNORE);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READWRITE, (SEC_LARGE_PAGES | SEC_COMMIT), FileHandleWriteOnly, STATUS_INVALID_PARAMETER_6, IGNORE);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READWRITE, SEC_NOCACHE, FileHandleWriteOnly, STATUS_INVALID_PARAMETER_6, IGNORE);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READWRITE, (SEC_NOCACHE | SEC_RESERVE | SEC_COMMIT), FileHandleWriteOnly, STATUS_INVALID_PARAMETER_6, IGNORE);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READWRITE, (SEC_NOCACHE | SEC_COMMIT), FileHandleWriteOnly, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READWRITE, (SEC_NOCACHE | SEC_RESERVE), FileHandleWriteOnly, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READWRITE, SEC_IMAGE, FileHandleWriteOnly, STATUS_INVALID_IMAGE_NOT_MZ, IGNORE);
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
//EXECUTABLE IMAGE
|
||||
CREATE_SECTION(Section, SECTION_MAP_READ, &ObjectAttributesWriteOnly, MaximumSize, PAGE_WRITECOPY, SEC_IMAGE, FileHandleExecuteOnly, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(Section, SECTION_MAP_EXECUTE, &ObjectAttributesWriteOnly, MaximumSize, PAGE_WRITECOPY, SEC_IMAGE, FileHandleExecuteOnly, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
|
||||
//DESIRED ACCESS TESTS
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, &ObjectAttributesReadOnly, MaximumSize, PAGE_READONLY, SEC_COMMIT, FileHandleExecuteOnly, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, &ObjectAttributesWriteOnly, MaximumSize, PAGE_WRITECOPY, SEC_COMMIT, FileHandleExecuteOnly, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(Section, SECTION_MAP_WRITE, &ObjectAttributesReadOnly, MaximumSize, PAGE_READONLY, SEC_COMMIT, FileHandleExecuteOnly, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(Section, SECTION_MAP_READ, &ObjectAttributesWriteOnly, MaximumSize, PAGE_WRITECOPY, SEC_COMMIT, FileHandleExecuteOnly, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
|
||||
//Object Attributes
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_READONLY, SEC_COMMIT, FileHandleExecuteOnly, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, &InvalidObjectAttributes, MaximumSize, PAGE_READONLY, SEC_COMMIT, FileHandleExecuteOnly, STATUS_OBJECT_PATH_SYNTAX_BAD, IGNORE);
|
||||
|
||||
//MaximumSize
|
||||
Status = ZwQueryInformationFile(FileHandleExecuteOnly, &IoStatusBlock, &FileStandardInfo, sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation);
|
||||
if (!skip(NT_SUCCESS(Status), "Cannot query file information"))
|
||||
{
|
||||
//as big as file
|
||||
MaximumSize = FileStandardInfo.EndOfFile;
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_EXECUTE_READ, SEC_IMAGE, FileHandleExecuteOnly, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
|
||||
//less than file
|
||||
MaximumSize.QuadPart = FileStandardInfo.EndOfFile.QuadPart - 2;
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_EXECUTE_READ, SEC_IMAGE, FileHandleExecuteOnly, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
|
||||
//larger than file
|
||||
MaximumSize.QuadPart = FileStandardInfo.EndOfFile.QuadPart + 2;
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_EXECUTE_READ, SEC_IMAGE, FileHandleExecuteOnly, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
|
||||
//0
|
||||
MaximumSize.QuadPart = 0;
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_EXECUTE_READ, SEC_IMAGE, FileHandleExecuteOnly, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
|
||||
//-1 (very big number)
|
||||
MaximumSize.QuadPart = -1;
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, MaximumSize, PAGE_EXECUTE_READ, SEC_IMAGE, FileHandleExecuteOnly, STATUS_SECTION_TOO_BIG, IGNORE);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
BasicBehaviorChecks(HANDLE FileHandle)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
HANDLE Section = NULL;
|
||||
#ifdef ROSTESTS_108_FIXED
|
||||
PFILE_OBJECT FileObject;
|
||||
#endif /* ROSTESTS_108_FIXED */
|
||||
LARGE_INTEGER Length;
|
||||
Length.QuadPart = TestStringSize;
|
||||
|
||||
/* FIXME: Null pointer dereference. See ROSTESTS-108 */
|
||||
#ifdef ROSTESTS_108_FIXED
|
||||
//mimic lack of section support for a particular file as well.
|
||||
Status = ObReferenceObjectByHandle(FileHandle, STANDARD_RIGHTS_ALL, IoFileObjectType, KernelMode, (PVOID *)&FileObject, NULL);
|
||||
if (!skip(NT_SUCCESS(Status), "Cannot reference object by handle\n"))
|
||||
{
|
||||
PSECTION_OBJECT_POINTERS Pointers = FileObject->SectionObjectPointer;
|
||||
|
||||
FileObject->SectionObjectPointer = NULL;
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, Length, PAGE_READONLY, SEC_COMMIT, FileHandle, STATUS_INVALID_FILE_FOR_SECTION, IGNORE);
|
||||
FileObject->SectionObjectPointer = Pointers;
|
||||
ObDereferenceObject(FileObject);
|
||||
}
|
||||
#endif /* ROSTESTS_108_FIXED */
|
||||
Length.QuadPart = TestStringSize;
|
||||
CREATE_SECTION(Section, (SECTION_ALL_ACCESS), NULL, Length, PAGE_READONLY, SEC_COMMIT, FileHandle, STATUS_SUCCESS, NO_HANDLE_CLOSE);
|
||||
CheckObject(Section, 2, 1);
|
||||
CheckSection(Section, SEC_FILE, Length.QuadPart, STATUS_SUCCESS);
|
||||
ZwClose(Section); //manually close it due to NO_HANDLE_CLOSE in CREATE_SECTION
|
||||
|
||||
//section length should be set to that of file
|
||||
Length.QuadPart = 0;
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, Length, PAGE_READONLY, SEC_COMMIT, FileHandle, STATUS_SUCCESS, NO_HANDLE_CLOSE);
|
||||
CheckSection(Section, SEC_FILE, TestStringSize, STATUS_SUCCESS);
|
||||
ZwClose(Section);
|
||||
|
||||
//create a smaller section than file
|
||||
Length.QuadPart = TestStringSize - 100;
|
||||
CREATE_SECTION(Section, SECTION_ALL_ACCESS, NULL, Length, PAGE_READONLY, SEC_COMMIT, FileHandle, STATUS_SUCCESS, NO_HANDLE_CLOSE);
|
||||
CheckSection(Section, SEC_FILE, TestStringSize - 100, STATUS_SUCCESS);
|
||||
ZwClose(Section);
|
||||
}
|
||||
|
||||
|
||||
START_TEST(ZwCreateSection)
|
||||
{
|
||||
HANDLE FileHandleReadOnly = NULL;
|
||||
HANDLE FileHandleWriteOnly = NULL;
|
||||
HANDLE FileHandleExecuteOnly = NULL;
|
||||
|
||||
InitializeObjectAttributes(&NtdllObject, &FileReadOnlyPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
|
||||
InitializeObjectAttributes(&KmtestFileObject, &WritableFilePath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
|
||||
InitializeObjectAttributes(&CalcFileObject, &CalcImgPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
|
||||
|
||||
KmtInitTestFiles(&FileHandleReadOnly, &FileHandleWriteOnly, &FileHandleExecuteOnly);
|
||||
|
||||
FileSectionViewPermissionCheck(FileHandleReadOnly, FileHandleWriteOnly, FileHandleExecuteOnly);
|
||||
SimpleErrorChecks(FileHandleReadOnly, FileHandleWriteOnly, FileHandleExecuteOnly);
|
||||
BasicBehaviorChecks(FileHandleWriteOnly);
|
||||
|
||||
if (FileHandleReadOnly)
|
||||
ZwClose(FileHandleReadOnly);
|
||||
|
||||
if (FileHandleWriteOnly)
|
||||
{
|
||||
ZwClose(FileHandleWriteOnly);
|
||||
ZwDeleteFile(&KmtestFileObject);
|
||||
}
|
||||
|
||||
if (FileHandleExecuteOnly)
|
||||
ZwClose(FileHandleExecuteOnly);
|
||||
}
|
568
rostests/kmtests/ntos_mm/ZwMapViewOfSection.c
Normal file
568
rostests/kmtests/ntos_mm/ZwMapViewOfSection.c
Normal file
|
@ -0,0 +1,568 @@
|
|||
/*
|
||||
* PROJECT: ReactOS kernel-mode tests
|
||||
* LICENSE: GPLv2+ - See COPYING in the top level directory
|
||||
* PURPOSE: Kernel-Mode Test Suite ZwMapViewOfSection
|
||||
* PROGRAMMER: Nikolay Borisov <nib9@aber.ac.uk>
|
||||
*/
|
||||
|
||||
#include <kmt_test.h>
|
||||
|
||||
#define IGNORE -99
|
||||
#define NEW_CONTENT "NewContent"
|
||||
#define NEW_CONTENT_LEN sizeof(NEW_CONTENT)
|
||||
|
||||
static UNICODE_STRING FileReadOnlyPath = RTL_CONSTANT_STRING(L"\\SystemRoot\\system32\\ntdll.dll");
|
||||
static UNICODE_STRING NtosImgPath = RTL_CONSTANT_STRING(L"\\SystemRoot\\system32\\ntoskrnl.exe");
|
||||
static UNICODE_STRING WritableFilePath = RTL_CONSTANT_STRING(L"\\SystemRoot\\kmtest-MmSection.txt");
|
||||
static UNICODE_STRING SharedSectionName = RTL_CONSTANT_STRING(L"\\BaseNamedObjects\\kmtest-SharedSection");
|
||||
extern const char TestString[];
|
||||
extern const SIZE_T TestStringSize;
|
||||
static OBJECT_ATTRIBUTES NtdllObject;
|
||||
static OBJECT_ATTRIBUTES KmtestFileObject;
|
||||
static OBJECT_ATTRIBUTES NtoskrnlFileObject;
|
||||
|
||||
#define TestMapView(SectionHandle, ProcessHandle, BaseAddress2, ZeroBits, CommitSize, SectionOffset, ViewSize2, InheritDisposition, AllocationType, Win32Protect, MapStatus, UnmapStatus) do \
|
||||
{ \
|
||||
Status = ZwMapViewOfSection(SectionHandle, ProcessHandle, BaseAddress2, ZeroBits, CommitSize, SectionOffset, ViewSize2, InheritDisposition, AllocationType, Win32Protect); \
|
||||
ok_eq_hex(Status, MapStatus); \
|
||||
if (NT_SUCCESS(Status)) \
|
||||
{ \
|
||||
Status = ZwUnmapViewOfSection(ProcessHandle, BaseAddress); \
|
||||
if (UnmapStatus != IGNORE) ok_eq_hex(Status, UnmapStatus); \
|
||||
*BaseAddress2 = NULL; \
|
||||
*ViewSize2 = 0; \
|
||||
} \
|
||||
} while (0) \
|
||||
|
||||
#define MmTestMapView(Object, ProcessHandle, BaseAddress2, ZeroBits, CommitSize, SectionOffset, ViewSize2, InheritDisposition, AllocationType, Win32Protect, MapStatus, UnmapStatus) do \
|
||||
{ \
|
||||
Status = MmMapViewOfSection(Object, ProcessHandle, BaseAddress2, ZeroBits, CommitSize, SectionOffset, ViewSize2, InheritDisposition, AllocationType, Win32Protect); \
|
||||
ok_eq_hex(Status, MapStatus); \
|
||||
if (NT_SUCCESS(Status)) \
|
||||
{ \
|
||||
Status = MmUnmapViewOfSection(ProcessHandle, BaseAddress); \
|
||||
if (UnmapStatus != IGNORE) ok_eq_hex(Status, UnmapStatus); \
|
||||
*BaseAddress2 = NULL; \
|
||||
*ViewSize2 = 0; \
|
||||
} \
|
||||
} while (0) \
|
||||
|
||||
#define CheckObject(Handle, Pointers, Handles) do \
|
||||
{ \
|
||||
PUBLIC_OBJECT_BASIC_INFORMATION ObjectInfo; \
|
||||
Status = ZwQueryObject(Handle, ObjectBasicInformation, \
|
||||
&ObjectInfo, sizeof ObjectInfo, NULL); \
|
||||
ok_eq_hex(Status, STATUS_SUCCESS); \
|
||||
ok_eq_ulong(ObjectInfo.PointerCount, Pointers); \
|
||||
ok_eq_ulong(ObjectInfo.HandleCount, Handles); \
|
||||
} while (0) \
|
||||
|
||||
static
|
||||
VOID
|
||||
KmtInitTestFiles(PHANDLE ReadOnlyFile, PHANDLE WriteOnlyFile, PHANDLE ExecutableFile)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
LARGE_INTEGER FileOffset;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
|
||||
//INIT THE READ-ONLY FILE
|
||||
Status = ZwCreateFile(ReadOnlyFile, GENERIC_READ, &NtdllObject, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, FILE_NON_DIRECTORY_FILE, NULL, 0);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
ok(*ReadOnlyFile != NULL, "Couldn't acquire READONLY handle\n");
|
||||
|
||||
//INIT THE EXECUTABLE FILE
|
||||
Status = ZwCreateFile(ExecutableFile, GENERIC_EXECUTE, &NtdllObject, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, FILE_NON_DIRECTORY_FILE, NULL, 0);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
ok(*ExecutableFile != NULL, "Couldn't acquire EXECUTE handle\n");
|
||||
|
||||
//INIT THE WRITE-ONLY FILE
|
||||
//TODO: Delete the file when the tests are all executed
|
||||
Status = ZwCreateFile(WriteOnlyFile, (GENERIC_WRITE | SYNCHRONIZE), &KmtestFileObject, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_WRITE, FILE_SUPERSEDE, (FILE_NON_DIRECTORY_FILE | FILE_DELETE_ON_CLOSE), NULL, 0);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
ok_eq_ulongptr(IoStatusBlock.Information, FILE_CREATED);
|
||||
ok(*WriteOnlyFile != NULL, "WriteOnlyFile is NULL\n");
|
||||
if (*WriteOnlyFile)
|
||||
{
|
||||
FileOffset.QuadPart = 0;
|
||||
Status = ZwWriteFile(*WriteOnlyFile, NULL, NULL, NULL, &IoStatusBlock, (PVOID)TestString, TestStringSize, &FileOffset, NULL);
|
||||
ok(Status == STATUS_SUCCESS || Status == STATUS_PENDING, "Status = 0x%08lx\n", Status);
|
||||
Status = ZwWaitForSingleObject(*WriteOnlyFile, FALSE, NULL);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
ok_eq_ulongptr(IoStatusBlock.Information, TestStringSize);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
VOID
|
||||
SimpleErrorChecks(HANDLE FileHandleReadOnly, HANDLE FileHandleWriteOnly, HANDLE ExecutableImg)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
HANDLE WriteSectionHandle;
|
||||
HANDLE ReadOnlySection;
|
||||
HANDLE PageFileSectionHandle;
|
||||
LARGE_INTEGER MaximumSize;
|
||||
LARGE_INTEGER SectionOffset;
|
||||
SIZE_T AllocSize = TestStringSize;
|
||||
SIZE_T ViewSize = 0;
|
||||
PVOID BaseAddress = NULL;
|
||||
PVOID AllocBase = NULL;
|
||||
MaximumSize.QuadPart = TestStringSize;
|
||||
|
||||
//Used for parameters working on file-based section
|
||||
Status = ZwCreateSection(&WriteSectionHandle, SECTION_ALL_ACCESS, NULL, &MaximumSize, PAGE_READWRITE, SEC_COMMIT, FileHandleWriteOnly);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
|
||||
Status = ZwCreateSection(&ReadOnlySection, SECTION_ALL_ACCESS, NULL, &MaximumSize, PAGE_READONLY, SEC_COMMIT, FileHandleReadOnly);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
|
||||
//Used for parameters taking effect only on page-file backed section
|
||||
MaximumSize.QuadPart = 5 * MM_ALLOCATION_GRANULARITY;
|
||||
Status = ZwCreateSection(&PageFileSectionHandle, SECTION_ALL_ACCESS, NULL, &MaximumSize, PAGE_READWRITE, SEC_COMMIT, NULL);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
|
||||
MaximumSize.QuadPart = TestStringSize;
|
||||
|
||||
//section handle
|
||||
TestMapView(WriteSectionHandle, NtCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView((HANDLE)0xDEADBEEF, NtCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_INVALID_HANDLE, IGNORE);
|
||||
TestMapView(INVALID_HANDLE_VALUE, NtCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_OBJECT_TYPE_MISMATCH, IGNORE);
|
||||
TestMapView(NULL, NtCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_INVALID_HANDLE, IGNORE);
|
||||
|
||||
//process handle
|
||||
TestMapView(WriteSectionHandle, (HANDLE)0xDEADBEEF, &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_INVALID_HANDLE, IGNORE);
|
||||
TestMapView(WriteSectionHandle, (HANDLE)NULL, &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_INVALID_HANDLE, IGNORE);
|
||||
|
||||
//base address
|
||||
BaseAddress = (PVOID)0x00567A20;
|
||||
TestMapView(WriteSectionHandle, NtCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_MAPPED_ALIGNMENT, IGNORE);
|
||||
|
||||
BaseAddress = (PVOID) 0x60000000;
|
||||
TestMapView(WriteSectionHandle, NtCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
|
||||
BaseAddress = (PVOID)((char *)MmSystemRangeStart + 200);
|
||||
TestMapView(WriteSectionHandle, NtCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_INVALID_PARAMETER_3, IGNORE);
|
||||
|
||||
//try mapping section to an already mapped address
|
||||
Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &AllocBase, 0, &AllocSize, MEM_COMMIT, PAGE_READWRITE);
|
||||
if (!skip(NT_SUCCESS(Status), "Cannot allocate memory\n"))
|
||||
{
|
||||
BaseAddress = AllocBase;
|
||||
TestMapView(WriteSectionHandle, NtCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_CONFLICTING_ADDRESSES, IGNORE);
|
||||
Status = ZwFreeVirtualMemory(NtCurrentProcess(), &AllocBase, &AllocSize, MEM_RELEASE);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
//zero bits
|
||||
TestMapView(WriteSectionHandle, NtCurrentProcess(), &BaseAddress, 1, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(WriteSectionHandle, NtCurrentProcess(), &BaseAddress, 5, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(WriteSectionHandle, NtCurrentProcess(), &BaseAddress, -1, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_INVALID_PARAMETER_4, IGNORE);
|
||||
TestMapView(WriteSectionHandle, NtCurrentProcess(), &BaseAddress, 20, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_NO_MEMORY, IGNORE);
|
||||
TestMapView(WriteSectionHandle, NtCurrentProcess(), &BaseAddress, 21, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_NO_MEMORY, IGNORE);
|
||||
TestMapView(WriteSectionHandle, NtCurrentProcess(), &BaseAddress, 22, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_INVALID_PARAMETER_4, IGNORE);
|
||||
|
||||
//commit size
|
||||
TestMapView(PageFileSectionHandle, NtCurrentProcess(), &BaseAddress, 0, 500, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(PageFileSectionHandle, NtCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(PageFileSectionHandle, NtCurrentProcess(), &BaseAddress, 0, -1, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_INVALID_PARAMETER_5, IGNORE);
|
||||
TestMapView(PageFileSectionHandle, NtCurrentProcess(), &BaseAddress, 0, 0x10000000, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_INVALID_PARAMETER_5, IGNORE);
|
||||
TestMapView(WriteSectionHandle, NtCurrentProcess(), &BaseAddress, 0, 500, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_INVALID_PARAMETER_5, IGNORE);
|
||||
TestMapView(WriteSectionHandle, NtCurrentProcess(), &BaseAddress, 0, 500, NULL, &ViewSize, ViewUnmap, MEM_RESERVE, PAGE_READWRITE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
|
||||
//section offset
|
||||
SectionOffset.QuadPart = 0;
|
||||
TestMapView(WriteSectionHandle, NtCurrentProcess(), &BaseAddress, 0, 0, &SectionOffset, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
ok_eq_ulonglong(SectionOffset.QuadPart, 0);
|
||||
|
||||
SectionOffset.QuadPart = 0x00040211; //MSDN is wrong, in w2k3 the ZwMapViewOfSection doesn't align offsets automatically
|
||||
TestMapView(PageFileSectionHandle, NtCurrentProcess(), &BaseAddress, 0, 500, &SectionOffset, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_MAPPED_ALIGNMENT, IGNORE);
|
||||
|
||||
SectionOffset.QuadPart = -1;
|
||||
TestMapView(WriteSectionHandle, NtCurrentProcess(), &BaseAddress, 0, 0, &SectionOffset, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_MAPPED_ALIGNMENT, IGNORE);
|
||||
|
||||
//View Size
|
||||
TestMapView(WriteSectionHandle, NtCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
|
||||
ViewSize = -1;
|
||||
TestMapView(WriteSectionHandle, NtCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_INVALID_PARAMETER_3, IGNORE);
|
||||
|
||||
ViewSize = TestStringSize+1;
|
||||
TestMapView(WriteSectionHandle, NtCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_INVALID_VIEW_SIZE, IGNORE);
|
||||
TestMapView(WriteSectionHandle, NtCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, MEM_RESERVE, PAGE_READWRITE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
|
||||
ViewSize = TestStringSize;
|
||||
TestMapView(WriteSectionHandle, NtCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
|
||||
ViewSize = TestStringSize-1;
|
||||
TestMapView(WriteSectionHandle, NtCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
|
||||
//allocation type
|
||||
TestMapView(WriteSectionHandle, NtCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, MEM_RESERVE, PAGE_READWRITE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
/* FIXME: Fails ASSERT((AllocationType & MEM_RESERVE) == 0) in MmMapViewOfArm3Section. See ROSTESTS-109 */
|
||||
#ifdef ROSTESTS_109_FIXED
|
||||
TestMapView(PageFileSectionHandle, NtCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, MEM_RESERVE, PAGE_READWRITE, STATUS_INVALID_PARAMETER_9, STATUS_SUCCESS);
|
||||
#endif /* ROSTESTS_109_FIXED */
|
||||
TestMapView(WriteSectionHandle, NtCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, (MEM_RESERVE | MEM_COMMIT), PAGE_READWRITE, STATUS_INVALID_PARAMETER_9, IGNORE);
|
||||
TestMapView(WriteSectionHandle, NtCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, (MEM_LARGE_PAGES | MEM_RESERVE), PAGE_READWRITE, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
|
||||
//win32protect
|
||||
TestMapView(WriteSectionHandle, NtCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READONLY, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(WriteSectionHandle, NtCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_NOACCESS, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(WriteSectionHandle, NtCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_EXECUTE_WRITECOPY, STATUS_SECTION_PROTECTION, IGNORE);
|
||||
TestMapView(ReadOnlySection, NtCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_SECTION_PROTECTION, IGNORE);
|
||||
TestMapView(ReadOnlySection, NtCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_WRITECOPY, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(ReadOnlySection, NtCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_EXECUTE_READ, STATUS_SECTION_PROTECTION, IGNORE);
|
||||
TestMapView(ReadOnlySection, NtCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_EXECUTE, STATUS_SECTION_PROTECTION, IGNORE);
|
||||
TestMapView(ReadOnlySection, NtCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_READONLY, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(ReadOnlySection, NtCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, PAGE_NOACCESS, STATUS_SUCCESS, STATUS_SUCCESS);
|
||||
TestMapView(ReadOnlySection, NtCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, 0, (PAGE_READWRITE | PAGE_READONLY), STATUS_INVALID_PAGE_PROTECTION, IGNORE);
|
||||
TestMapView(ReadOnlySection, NtCurrentProcess(), &BaseAddress, 0, 0, NULL, &ViewSize, ViewUnmap, MEM_RESERVE, PAGE_READONLY, STATUS_SECTION_PROTECTION, IGNORE);
|
||||
|
||||
ZwClose(WriteSectionHandle);
|
||||
ZwClose(PageFileSectionHandle);
|
||||
ZwClose(ReadOnlySection);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
VOID
|
||||
AdvancedErrorChecks(HANDLE FileHandleReadOnly, HANDLE FileHandleWriteOnly)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PVOID BaseAddress;
|
||||
HANDLE FileSectionHandle;
|
||||
LARGE_INTEGER SectionOffset;
|
||||
LARGE_INTEGER MaximumSize;
|
||||
SIZE_T ViewSize = 0;
|
||||
PVOID SectionObject;
|
||||
|
||||
MaximumSize.QuadPart = TestStringSize;
|
||||
//Used for parameters working on file-based section
|
||||
Status = ZwCreateSection(&FileSectionHandle, SECTION_ALL_ACCESS, NULL, &MaximumSize, PAGE_READWRITE, SEC_COMMIT, FileHandleWriteOnly);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
|
||||
Status = ObReferenceObjectByHandle(FileSectionHandle,
|
||||
STANDARD_RIGHTS_ALL,
|
||||
NULL,
|
||||
KernelMode,
|
||||
&SectionObject,
|
||||
NULL);
|
||||
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
|
||||
//Bypassing Zw function calls mean bypassing the alignment checks which are not crucial for the branches being tested here
|
||||
|
||||
//test first conditional branch
|
||||
ViewSize = -1;
|
||||
MmTestMapView(SectionObject, PsGetCurrentProcess(), &BaseAddress, 0, TestStringSize, &SectionOffset, &ViewSize, ViewUnmap, MEM_RESERVE, PAGE_READWRITE, STATUS_INVALID_VIEW_SIZE, IGNORE);
|
||||
|
||||
//test second conditional branch
|
||||
ViewSize = 1;
|
||||
SectionOffset.QuadPart = TestStringSize;
|
||||
MmTestMapView(SectionObject, PsGetCurrentProcess(), &BaseAddress, 0, TestStringSize, &SectionOffset, &ViewSize, ViewUnmap, 0, PAGE_READWRITE, STATUS_INVALID_VIEW_SIZE, IGNORE);
|
||||
|
||||
ObDereferenceObject(SectionObject);
|
||||
ZwClose(FileSectionHandle);
|
||||
}
|
||||
|
||||
static
|
||||
SIZE_T
|
||||
CompareFileContents(HANDLE FileHandle, SIZE_T BufferLength, PVOID Buffer)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
LARGE_INTEGER ByteOffset;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
PVOID FileContent;
|
||||
SIZE_T Match;
|
||||
|
||||
Match = 0;
|
||||
ByteOffset.QuadPart = 0;
|
||||
|
||||
FileContent = ExAllocatePoolWithTag(PagedPool, BufferLength, 'Test');
|
||||
if (!skip((FileContent != NULL), "Error allocating memory for FileContent\n"))
|
||||
{
|
||||
Status = ZwReadFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, FileContent, BufferLength, &ByteOffset, NULL);
|
||||
ok_eq_hex(Status, STATUS_SUCCESS);
|
||||
ok_eq_ulongptr(IoStatusBlock.Information, BufferLength);
|
||||
|
||||
Match = 0;
|
||||
Match = RtlCompareMemory(FileContent, Buffer, BufferLength);
|
||||
ExFreePoolWithTag(FileContent, 'Test');
|
||||
}
|
||||
|
||||
return Match;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
VOID
|
||||
NTAPI
|
||||
SystemProcessWorker(PVOID StartContext)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PVOID BaseAddress;
|
||||
HANDLE SectionHandle;
|
||||
SIZE_T ViewSize;
|
||||
SIZE_T Match;
|
||||
LARGE_INTEGER SectionOffset;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
|
||||
UNREFERENCED_PARAMETER(StartContext);
|
||||
|
||||
BaseAddress = NULL;
|
||||
ViewSize = TestStringSize;
|
||||
SectionOffset.QuadPart = 0;
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes, &SharedSectionName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
|
||||
Status = ZwOpenSection(&SectionHandle, SECTION_ALL_ACCESS, &ObjectAttributes);
|
||||
if (!skip(NT_SUCCESS(Status), "Error acquiring handle to section. Error = %p\n", Status))
|
||||
{
|
||||
CheckObject(SectionHandle, 4, 2);
|
||||
Status = ZwMapViewOfSection(SectionHandle, NtCurrentProcess(), &BaseAddress, 0, TestStringSize, &SectionOffset, &ViewSize, ViewUnmap, 0, PAGE_READWRITE);
|
||||
|
||||
//make sure ZwMapViewofSection doesn't touch the section ref counts.
|
||||
CheckObject(SectionHandle, 4, 2);
|
||||
|
||||
if (!skip(NT_SUCCESS(Status), "Error mapping page file view in system process. Error = %p\n", Status))
|
||||
{
|
||||
Match = RtlCompareMemory(BaseAddress, TestString, TestStringSize);
|
||||
ok_eq_size(Match, TestStringSize);
|
||||
|
||||
RtlCopyMemory(BaseAddress, NEW_CONTENT, NEW_CONTENT_LEN);
|
||||
ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
|
||||
|
||||
//make sure ZwMapViewofSection doesn't touch the section ref counts.
|
||||
CheckObject(SectionHandle, 4, 2);
|
||||
}
|
||||
|
||||
ZwClose(SectionHandle);
|
||||
}
|
||||
|
||||
PsTerminateSystemThread(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
VOID
|
||||
BehaviorChecks(HANDLE FileHandleReadOnly, HANDLE FileHandleWriteOnly)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PVOID BaseAddress = NULL;
|
||||
PVOID ThreadObject;
|
||||
HANDLE WriteSectionHandle;
|
||||
HANDLE SysThreadHandle;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
LARGE_INTEGER SectionOffset;
|
||||
LARGE_INTEGER MaximumSize;
|
||||
SIZE_T Match;
|
||||
SIZE_T ViewSize = 0;
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes, &SharedSectionName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
|
||||
MaximumSize.QuadPart = TestStringSize;
|
||||
SectionOffset.QuadPart = 0;
|
||||
|
||||
Status = ZwCreateSection(&WriteSectionHandle, SECTION_ALL_ACCESS, &ObjectAttributes, &MaximumSize, PAGE_READWRITE, SEC_COMMIT, FileHandleWriteOnly);
|
||||
CheckObject(WriteSectionHandle, 3, 1);
|
||||
ok(NT_SUCCESS(Status), "Error creating write section from file. Error = %p\n", Status);
|
||||
|
||||
//check for section reading/writing by comparing section content to a well-known value.
|
||||
Status = ZwMapViewOfSection(WriteSectionHandle, NtCurrentProcess() ,&BaseAddress, 0, 0, &SectionOffset, &ViewSize, ViewUnmap, 0, PAGE_READWRITE);
|
||||
CheckObject(WriteSectionHandle, 3, 1);
|
||||
if (!skip(NT_SUCCESS(Status), "Error mapping view with READ/WRITE priv. Error = %p\n", Status))
|
||||
{
|
||||
Match = RtlCompareMemory(BaseAddress, TestString, TestStringSize);
|
||||
ok_eq_size(Match, TestStringSize);
|
||||
|
||||
//now check writing to section
|
||||
RtlCopyMemory(BaseAddress, NEW_CONTENT, NEW_CONTENT_LEN);
|
||||
|
||||
Match = RtlCompareMemory(BaseAddress, NEW_CONTENT, NEW_CONTENT_LEN);
|
||||
ok_eq_size(Match, NEW_CONTENT_LEN);
|
||||
|
||||
//check to see if the contents have been flushed to the actual file on disk.
|
||||
Match = CompareFileContents(FileHandleWriteOnly, NEW_CONTENT_LEN, NEW_CONTENT);
|
||||
ok_eq_size(Match, NEW_CONTENT_LEN);
|
||||
|
||||
//bring everything back to normal
|
||||
RtlCopyMemory(BaseAddress, TestString, TestStringSize);
|
||||
|
||||
//Initiate an external thread to modify the file
|
||||
InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
|
||||
Status = PsCreateSystemThread(&SysThreadHandle, STANDARD_RIGHTS_ALL, &ObjectAttributes, NULL, NULL, SystemProcessWorker, NULL);
|
||||
if (!skip(NT_SUCCESS(Status), "Error creating System thread. Error = %p\n", Status))
|
||||
{
|
||||
Status = ObReferenceObjectByHandle(SysThreadHandle, THREAD_ALL_ACCESS, PsThreadType, KernelMode, &ThreadObject, NULL);
|
||||
if (!skip(NT_SUCCESS(Status), "Error getting reference to System thread when testing file-backed section\n"))
|
||||
{
|
||||
//wait until the system thread actually terminates
|
||||
KeWaitForSingleObject(ThreadObject, Executive, KernelMode, FALSE, NULL);
|
||||
|
||||
//no longer need the thread object
|
||||
ObDereferenceObject(ThreadObject);
|
||||
|
||||
//test for bi-directional access to the shared page file
|
||||
Match = RtlCompareMemory(BaseAddress, NEW_CONTENT, NEW_CONTENT_LEN);
|
||||
ok_eq_size(Match, NEW_CONTENT_LEN);
|
||||
|
||||
//bring everything back to normal, again
|
||||
RtlCopyMemory(BaseAddress, TestString, TestStringSize);
|
||||
}
|
||||
}
|
||||
|
||||
ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
|
||||
}
|
||||
|
||||
//Try to write to read-only mapped view
|
||||
BaseAddress = NULL;
|
||||
ViewSize = 0;
|
||||
SectionOffset.QuadPart = 0;
|
||||
Status = ZwMapViewOfSection(WriteSectionHandle, NtCurrentProcess(), &BaseAddress, 0, 0, &SectionOffset, &ViewSize, ViewUnmap, 0, PAGE_READONLY);
|
||||
if (!skip(NT_SUCCESS(Status), "Error mapping view with READ priv. Error = %p\n", Status))
|
||||
{
|
||||
NTSTATUS ExceptionStatus;
|
||||
|
||||
Match = RtlCompareMemory(BaseAddress, TestString, TestStringSize);
|
||||
ok_eq_size(Match, TestStringSize);
|
||||
|
||||
KmtStartSeh()
|
||||
RtlCopyMemory(BaseAddress, NEW_CONTENT, NEW_CONTENT_LEN);
|
||||
KmtEndSeh(STATUS_ACCESS_VIOLATION);
|
||||
|
||||
ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
|
||||
}
|
||||
|
||||
/* FIXME: Crash. See ROSTESTS-110 */
|
||||
#ifdef ROSTESTS_110_FIXED
|
||||
//try to access forbidden memory
|
||||
BaseAddress = NULL;
|
||||
ViewSize = 0;
|
||||
SectionOffset.QuadPart = 0;
|
||||
Status = ZwMapViewOfSection(WriteSectionHandle, NtCurrentProcess(), &BaseAddress, 0, 0, &SectionOffset, &ViewSize, ViewUnmap, 0, PAGE_NOACCESS);
|
||||
if (!skip(NT_SUCCESS(Status), "Error mapping view with PAGE_NOACCESS priv. Error = %p\n", Status))
|
||||
{
|
||||
NTSTATUS ExceptionStatus;
|
||||
|
||||
KmtStartSeh()
|
||||
RtlCompareMemory(BaseAddress, TestString, TestStringSize);
|
||||
KmtEndSeh(STATUS_ACCESS_VIOLATION);
|
||||
|
||||
ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
|
||||
}
|
||||
#endif /* ROSTESTS_110_FIXED */
|
||||
|
||||
ZwClose(WriteSectionHandle);
|
||||
|
||||
//section created with sec_reserve should not be commited.
|
||||
BaseAddress = NULL;
|
||||
ViewSize = 0;
|
||||
SectionOffset.QuadPart = 0;
|
||||
Status = ZwCreateSection(&WriteSectionHandle, SECTION_ALL_ACCESS, &ObjectAttributes, &MaximumSize, PAGE_READWRITE, SEC_RESERVE, FileHandleWriteOnly);
|
||||
if (!skip(NT_SUCCESS(Status), "Error creating page file section. Error = %p\n", Status))
|
||||
{
|
||||
Status = ZwMapViewOfSection(WriteSectionHandle, NtCurrentProcess(), &BaseAddress, 0, TestStringSize, &SectionOffset, &ViewSize, ViewUnmap, MEM_RESERVE, PAGE_READWRITE);
|
||||
if (!skip(NT_SUCCESS(Status), "Error mapping page file view. Error = %p\n", Status))
|
||||
{
|
||||
//check also the SEC_COMMIT flag
|
||||
/* This test proves that MSDN is once again wrong
|
||||
* msdn.microsoft.com/en-us/library/windows/hardware/aa366537.aspx states that SEC_RESERVE
|
||||
* should cause the allocated memory for the view to be reserved but in fact it is always committed.
|
||||
* It fails also on windows.
|
||||
*/
|
||||
Test_NtQueryVirtualMemory(BaseAddress, PAGE_SIZE, MEM_COMMIT, PAGE_READWRITE);
|
||||
ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
|
||||
}
|
||||
|
||||
ZwClose(WriteSectionHandle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
VOID
|
||||
PageFileBehaviorChecks()
|
||||
{
|
||||
NTSTATUS Status;
|
||||
LARGE_INTEGER MaxSectionSize;
|
||||
LARGE_INTEGER SectionOffset;
|
||||
HANDLE PageFileSectionHandle;
|
||||
PVOID BaseAddress;
|
||||
SIZE_T ViewSize;
|
||||
SIZE_T Match;
|
||||
PVOID ThreadObject;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
|
||||
MaxSectionSize.QuadPart = TestStringSize;
|
||||
SectionOffset.QuadPart = 0;
|
||||
PageFileSectionHandle = INVALID_HANDLE_VALUE;
|
||||
BaseAddress = NULL;
|
||||
ViewSize = TestStringSize;
|
||||
InitializeObjectAttributes(&ObjectAttributes, &SharedSectionName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
|
||||
|
||||
//test memory sharing between 2 different processes
|
||||
Status = ZwCreateSection(&PageFileSectionHandle, SECTION_ALL_ACCESS, &ObjectAttributes, &MaxSectionSize, PAGE_READWRITE, SEC_COMMIT, NULL);
|
||||
if (!skip(NT_SUCCESS(Status), "Error creating page file section. Error = %p\n", Status))
|
||||
{
|
||||
CheckObject(PageFileSectionHandle, 3, 1);
|
||||
Status = ZwMapViewOfSection(PageFileSectionHandle, NtCurrentProcess(), &BaseAddress, 0, TestStringSize, &SectionOffset, &ViewSize, ViewUnmap, 0, PAGE_READWRITE);
|
||||
if (!skip(NT_SUCCESS(Status), "Error mapping page file view. Error = %p\n", Status))
|
||||
{
|
||||
HANDLE SysThreadHandle;
|
||||
|
||||
CheckObject(PageFileSectionHandle, 3, 1);
|
||||
|
||||
//check also the SEC_COMMIT flag
|
||||
Test_NtQueryVirtualMemory(BaseAddress, PAGE_SIZE, MEM_COMMIT, PAGE_READWRITE);
|
||||
|
||||
RtlCopyMemory(BaseAddress, TestString, TestStringSize);
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
|
||||
Status = PsCreateSystemThread(&SysThreadHandle, STANDARD_RIGHTS_ALL, &ObjectAttributes, NULL, NULL, SystemProcessWorker, NULL);
|
||||
|
||||
if (!skip(NT_SUCCESS(Status), "Error creating System thread. Error = %p\n", Status))
|
||||
{
|
||||
Status = ObReferenceObjectByHandle(SysThreadHandle, THREAD_ALL_ACCESS, PsThreadType, KernelMode, &ThreadObject, NULL);
|
||||
if (!skip(NT_SUCCESS(Status), "Error getting reference to System thread when testing pagefile-backed section\n"))
|
||||
{
|
||||
//wait until the system thread actually terminates
|
||||
KeWaitForSingleObject(ThreadObject, Executive, KernelMode, FALSE, NULL);
|
||||
|
||||
//no longer need the thread object
|
||||
ObDereferenceObject(ThreadObject);
|
||||
|
||||
//test for bi-directional access to the shared page file
|
||||
Match = RtlCompareMemory(BaseAddress, NEW_CONTENT, NEW_CONTENT_LEN);
|
||||
ok_eq_size(Match, NEW_CONTENT_LEN);
|
||||
}
|
||||
}
|
||||
ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
|
||||
}
|
||||
ZwClose(PageFileSectionHandle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
START_TEST(ZwMapViewOfSection)
|
||||
{
|
||||
HANDLE FileHandleReadOnly = NULL;
|
||||
HANDLE FileHandleWriteOnly = NULL;
|
||||
HANDLE ExecutableFileHandle = NULL;
|
||||
|
||||
InitializeObjectAttributes(&NtdllObject, &FileReadOnlyPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
|
||||
InitializeObjectAttributes(&KmtestFileObject, &WritableFilePath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
|
||||
InitializeObjectAttributes(&NtoskrnlFileObject, &NtosImgPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
|
||||
|
||||
KmtInitTestFiles(&FileHandleReadOnly, &FileHandleWriteOnly, &ExecutableFileHandle);
|
||||
|
||||
SimpleErrorChecks(FileHandleReadOnly, FileHandleWriteOnly, ExecutableFileHandle);
|
||||
AdvancedErrorChecks(FileHandleReadOnly, FileHandleWriteOnly);
|
||||
BehaviorChecks(FileHandleReadOnly, FileHandleWriteOnly);
|
||||
PageFileBehaviorChecks();
|
||||
|
||||
if (FileHandleReadOnly)
|
||||
ZwClose(FileHandleReadOnly);
|
||||
|
||||
if (FileHandleWriteOnly)
|
||||
ZwClose(FileHandleWriteOnly);
|
||||
|
||||
if (ExecutableFileHandle)
|
||||
ZwClose(ExecutableFileHandle);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue