[KMTESTS:MM]

- Test unaligned address and addresses close to MmHighestUserAddress in MmMapLockedPagesSpecifyCache test
CORE-13444

svn path=/trunk/; revision=75084
This commit is contained in:
Thomas Faber 2017-06-18 08:00:29 +00:00
parent 2a16952b1c
commit 6bea3b076d
3 changed files with 98 additions and 11 deletions

View file

@ -14,6 +14,7 @@ typedef struct _QUERY_BUFFER
USHORT Length;
PVOID Buffer;
BOOLEAN Cached;
NTSTATUS Status;
} QUERY_BUFFER, *PQUERY_BUFFER;
typedef struct _READ_BUFFER
@ -25,6 +26,7 @@ typedef struct _READ_BUFFER
#define IOCTL_QUERY_BUFFER 1
#define IOCTL_READ_BUFFER 2
#define IOCTL_CLEAN 3
#define WRITE_PATTERN 0xA4A5A6A7

View file

@ -121,7 +121,7 @@ TestMessageHandler(
TestCleanEverything();
ok(ExGetPreviousMode() == UserMode, "Not comming from umode!\n");
ok(ExGetPreviousMode() == UserMode, "Not coming from umode!\n");
if (!skip(Buffer && InLength >= sizeof(QUERY_BUFFER) && *OutLength >= sizeof(QUERY_BUFFER), "Cannot read/write from/to buffer!\n"))
{
PQUERY_BUFFER QueryBuffer;
@ -178,17 +178,28 @@ TestMessageHandler(
SehStatus = STATUS_SUCCESS;
_SEH2_TRY
{
CurrentUser = MmMapLockedPagesSpecifyCache(CurrentMdl, UserMode, CacheType, NULL, FALSE, NormalPagePriority);
CurrentUser = MmMapLockedPagesSpecifyCache(CurrentMdl, UserMode, CacheType, QueryBuffer->Buffer, FALSE, NormalPagePriority);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SehStatus = _SEH2_GetExceptionCode();
}
_SEH2_END;
ok_eq_hex(SehStatus, STATUS_SUCCESS);
if (QueryBuffer->Status != -1)
{
ok_eq_hex(SehStatus, QueryBuffer->Status);
if (NT_SUCCESS(QueryBuffer->Status))
{
ok(CurrentUser != NULL, "MmMapLockedPagesSpecifyCache failed!\n");
}
else
{
ok(CurrentUser == NULL, "MmMapLockedPagesSpecifyCache succeeded!\n");
}
}
QueryBuffer->Status = SehStatus;
}
else
{
ExFreePoolWithTag(CurrentBuffer, 'MLPC');
}
@ -208,7 +219,7 @@ TestMessageHandler(
ok_eq_size(*OutLength, 0);
ok(CurrentMdl != NULL, "MDL is not in use!\n");
if (!skip(Buffer && InLength >= sizeof(QUERY_BUFFER), "Cannot read from buffer!\n"))
if (!skip(Buffer && InLength >= sizeof(READ_BUFFER), "Cannot read from buffer!\n"))
{
PREAD_BUFFER ReadBuffer;
@ -237,6 +248,11 @@ TestMessageHandler(
break;
}
case IOCTL_CLEAN:
{
TestCleanEverything();
break;
}
default:
ok(0, "Got an unknown message! DeviceObject=%p, ControlCode=%lu, Buffer=%p, In=%lu, Out=%lu bytes\n",
DeviceObject, ControlCode, Buffer, InLength, *OutLength);

View file

@ -6,9 +6,13 @@
*/
#include <kmt_test.h>
#include <ndk/exfuncs.h>
#include "MmMapLockedPagesSpecifyCache.h"
#define ALIGN_DOWN_BY(size, align) \
((ULONG_PTR)(size) & ~((ULONG_PTR)(align) - 1))
#define SET_BUFFER_LENGTH(Var, Length) \
{ \
C_ASSERT(((Length) % sizeof(ULONG)) == 0); \
@ -20,6 +24,7 @@
QueryBuffer.Length = BufferLength; \
QueryBuffer.Buffer = NULL; \
QueryBuffer.Cached = UseCache; \
QueryBuffer.Status = STATUS_SUCCESS; \
}
#define FILL_READ_BUFFER(QueryBuffer, ReadBuffer) \
@ -78,6 +83,9 @@ START_TEST(MmMapLockedPagesSpecifyCache)
DWORD Length;
USHORT i;
USHORT BufferLength;
SYSTEM_BASIC_INFORMATION BasicInfo;
NTSTATUS Status;
ULONG_PTR HighestAddress;
KmtLoadDriver(L"MmMapLockedPagesSpecifyCache", FALSE);
KmtOpenDriver();
@ -180,9 +188,7 @@ START_TEST(MmMapLockedPagesSpecifyCache)
// more than 2 pages
SET_BUFFER_LENGTH(BufferLength, 2 * 4096 + 2048);
QueryBuffer.Length = BufferLength;
QueryBuffer.Buffer = NULL;
QueryBuffer.Cached = FALSE;
FILL_QUERY_BUFFER(QueryBuffer, BufferLength, FALSE);
Length = sizeof(QUERY_BUFFER);
ok(KmtSendBufferToDriver(IOCTL_QUERY_BUFFER, &QueryBuffer, sizeof(QUERY_BUFFER), &Length) == ERROR_SUCCESS, "\n");
ok_eq_int(QueryBuffer.Length, BufferLength);
@ -193,9 +199,7 @@ START_TEST(MmMapLockedPagesSpecifyCache)
FILL_READ_BUFFER(QueryBuffer, ReadBuffer);
ok(KmtSendBufferToDriver(IOCTL_READ_BUFFER, &ReadBuffer, sizeof(READ_BUFFER), &Length) == ERROR_SUCCESS, "\n");
QueryBuffer.Length = BufferLength;
QueryBuffer.Buffer = NULL;
QueryBuffer.Cached = TRUE;
FILL_QUERY_BUFFER(QueryBuffer, BufferLength, TRUE);
Length = sizeof(QUERY_BUFFER);
ok(KmtSendBufferToDriver(IOCTL_QUERY_BUFFER, &QueryBuffer, sizeof(QUERY_BUFFER), &Length) == ERROR_SUCCESS, "\n");
ok_eq_int(QueryBuffer.Length, BufferLength);
@ -206,6 +210,71 @@ START_TEST(MmMapLockedPagesSpecifyCache)
FILL_READ_BUFFER(QueryBuffer, ReadBuffer);
ok(KmtSendBufferToDriver(IOCTL_READ_BUFFER, &ReadBuffer, sizeof(READ_BUFFER), &Length) == ERROR_SUCCESS, "\n");
// ask for a specific address (we know that ReadBuffer.Buffer is free)
SET_BUFFER_LENGTH(BufferLength, 4096);
FILL_QUERY_BUFFER(QueryBuffer, BufferLength, FALSE);
QueryBuffer.Buffer = ReadBuffer.Buffer;
Length = sizeof(QUERY_BUFFER);
ok(KmtSendBufferToDriver(IOCTL_QUERY_BUFFER, &QueryBuffer, sizeof(QUERY_BUFFER), &Length) == ERROR_SUCCESS, "\n");
ok_eq_int(QueryBuffer.Length, BufferLength);
ok(QueryBuffer.Buffer == ReadBuffer.Buffer, "Buffer is NULL\n");
CHECK_ALLOC(QueryBuffer.Buffer, BufferLength);
Length = 0;
FILL_READ_BUFFER(QueryBuffer, ReadBuffer);
ok(KmtSendBufferToDriver(IOCTL_READ_BUFFER, &ReadBuffer, sizeof(READ_BUFFER), &Length) == ERROR_SUCCESS, "\n");
// ask for an unaligned address
SET_BUFFER_LENGTH(BufferLength, 4096);
FILL_QUERY_BUFFER(QueryBuffer, BufferLength, FALSE);
QueryBuffer.Buffer = (PVOID)((ULONG_PTR)ReadBuffer.Buffer + 2048);
QueryBuffer.Status = STATUS_INVALID_ADDRESS;
Length = sizeof(QUERY_BUFFER);
ok(KmtSendBufferToDriver(IOCTL_QUERY_BUFFER, &QueryBuffer, sizeof(QUERY_BUFFER), &Length) == ERROR_SUCCESS, "\n");
ok_eq_int(QueryBuffer.Length, BufferLength);
ok(QueryBuffer.Buffer == NULL, "Buffer is %p\n", QueryBuffer.Buffer);
Length = 0;
ok(KmtSendBufferToDriver(IOCTL_CLEAN, NULL, 0, &Length) == ERROR_SUCCESS, "\n");
// get system info for MmHighestUserAddress
Status = NtQuerySystemInformation(SystemBasicInformation,
&BasicInfo,
sizeof(BasicInfo),
NULL);
ok_eq_hex(Status, STATUS_SUCCESS);
trace("MaximumUserModeAddress: %lx\n", BasicInfo.MaximumUserModeAddress);
HighestAddress = ALIGN_DOWN_BY(BasicInfo.MaximumUserModeAddress, PAGE_SIZE);
// near MmHighestUserAddress
SET_BUFFER_LENGTH(BufferLength, 4096);
FILL_QUERY_BUFFER(QueryBuffer, BufferLength, FALSE);
QueryBuffer.Buffer = (PVOID)(HighestAddress - 15 * PAGE_SIZE); // 7ffe0000
QueryBuffer.Status = STATUS_INVALID_ADDRESS;
trace("QueryBuffer.Buffer %p\n", QueryBuffer.Buffer);
Length = sizeof(QUERY_BUFFER);
ok(KmtSendBufferToDriver(IOCTL_QUERY_BUFFER, &QueryBuffer, sizeof(QUERY_BUFFER), &Length) == ERROR_SUCCESS, "\n");
ok_eq_int(QueryBuffer.Length, BufferLength);
ok(QueryBuffer.Buffer == NULL, "Buffer is %p\n", QueryBuffer.Buffer);
Length = 0;
ok(KmtSendBufferToDriver(IOCTL_CLEAN, NULL, 0, &Length) == ERROR_SUCCESS, "\n");
// far enough away from MmHighestUserAddress
SET_BUFFER_LENGTH(BufferLength, 4096);
FILL_QUERY_BUFFER(QueryBuffer, BufferLength, FALSE);
QueryBuffer.Buffer = (PVOID)(HighestAddress - 16 * PAGE_SIZE); // 7ffdf000
QueryBuffer.Status = -1;
trace("QueryBuffer.Buffer %p\n", QueryBuffer.Buffer);
Length = sizeof(QUERY_BUFFER);
ok(KmtSendBufferToDriver(IOCTL_QUERY_BUFFER, &QueryBuffer, sizeof(QUERY_BUFFER), &Length) == ERROR_SUCCESS, "\n");
ok_eq_int(QueryBuffer.Length, BufferLength);
ok(QueryBuffer.Status == STATUS_SUCCESS ||
QueryBuffer.Status == STATUS_CONFLICTING_ADDRESSES, "Status = %lx\n", QueryBuffer.Status);
Length = 0;
ok(KmtSendBufferToDriver(IOCTL_CLEAN, NULL, 0, &Length) == ERROR_SUCCESS, "\n");
KmtCloseDriver();
KmtUnloadDriver();
}