Commit e90b2bb9 authored by Paul Gofman's avatar Paul Gofman Committed by Alexandre Julliard

ntdll: Fix size validation in NtFreeVirtualMemory().

parent d8fc23d8
...@@ -1857,12 +1857,12 @@ static void test_NtFreeVirtualMemory(void) ...@@ -1857,12 +1857,12 @@ static void test_NtFreeVirtualMemory(void)
size = 0x11000; size = 0x11000;
status = NtFreeVirtualMemory(NtCurrentProcess(), &addr1, &size, MEM_RELEASE); status = NtFreeVirtualMemory(NtCurrentProcess(), &addr1, &size, MEM_RELEASE);
todo_wine ok(status == STATUS_UNABLE_TO_FREE_VM, "Unexpected status %08lx.\n", status); ok(status == STATUS_UNABLE_TO_FREE_VM, "Unexpected status %08lx.\n", status);
addr = (char *)addr1 + 0x1001; addr = (char *)addr1 + 0x1001;
size = 0xffff; size = 0xffff;
status = NtFreeVirtualMemory(NtCurrentProcess(), &addr, &size, MEM_RELEASE); status = NtFreeVirtualMemory(NtCurrentProcess(), &addr, &size, MEM_RELEASE);
todo_wine ok(status == STATUS_UNABLE_TO_FREE_VM, "Unexpected status %08lx.\n", status); ok(status == STATUS_UNABLE_TO_FREE_VM, "Unexpected status %08lx.\n", status);
ok(size == 0xffff, "Unexpected size %p.\n", (void *)size); ok(size == 0xffff, "Unexpected size %p.\n", (void *)size);
ok(addr == (char *)addr1 + 0x1001, "Got addr %p, addr1 %p.\n", addr, addr1); ok(addr == (char *)addr1 + 0x1001, "Got addr %p, addr1 %p.\n", addr, addr1);
...@@ -1872,16 +1872,16 @@ static void test_NtFreeVirtualMemory(void) ...@@ -1872,16 +1872,16 @@ static void test_NtFreeVirtualMemory(void)
todo_wine ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); todo_wine ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
*(volatile char *)addr1 = 1; *(volatile char *)addr1 = 1;
*((volatile char *)addr1 + 0x2000) = 1; *((volatile char *)addr1 + 0x2000) = 1;
todo_wine ok(size == 0x1000, "Unexpected size %p.\n", (void *)size); ok(size == 0x1000, "Unexpected size %p.\n", (void *)size);
todo_wine ok(addr == (char *)addr1 + 0x1000, "Got addr %p, addr1 %p.\n", addr, addr1); ok(addr == (char *)addr1 + 0x1000, "Got addr %p, addr1 %p.\n", addr, addr1);
size = 0xfff; size = 0xfff;
addr = (char *)addr1 + 1; addr = (char *)addr1 + 1;
status = NtFreeVirtualMemory(NtCurrentProcess(), &addr, &size, MEM_RELEASE); status = NtFreeVirtualMemory(NtCurrentProcess(), &addr, &size, MEM_RELEASE);
todo_wine ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); todo_wine ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status);
*((volatile char *)addr1 + 0x2000) = 1; *((volatile char *)addr1 + 0x2000) = 1;
todo_wine ok(size == 0x1000, "Unexpected size %p.\n", (void *)size); ok(size == 0x1000, "Unexpected size %p.\n", (void *)size);
todo_wine ok(addr == addr1, "Got addr %p, addr1 %p.\n", addr, addr1); ok(addr == addr1, "Got addr %p, addr1 %p.\n", addr, addr1);
size = 0x1000; size = 0x1000;
addr = addr1; addr = addr1;
...@@ -1901,12 +1901,12 @@ static void test_NtFreeVirtualMemory(void) ...@@ -1901,12 +1901,12 @@ static void test_NtFreeVirtualMemory(void)
size = 0; size = 0;
addr = (char *)addr1 + 0x1000; addr = (char *)addr1 + 0x1000;
status = NtFreeVirtualMemory(NtCurrentProcess(), &addr, &size, MEM_RELEASE); status = NtFreeVirtualMemory(NtCurrentProcess(), &addr, &size, MEM_RELEASE);
todo_wine ok(status == STATUS_MEMORY_NOT_ALLOCATED, "Unexpected status %08lx.\n", status); ok(status == STATUS_MEMORY_NOT_ALLOCATED, "Unexpected status %08lx.\n", status);
size = 0x1000; size = 0x1000;
addr = (char *)addr1 + 0x1000; addr = (char *)addr1 + 0x1000;
status = NtFreeVirtualMemory(NtCurrentProcess(), &addr, &size, MEM_DECOMMIT); status = NtFreeVirtualMemory(NtCurrentProcess(), &addr, &size, MEM_DECOMMIT);
todo_wine ok(status == STATUS_MEMORY_NOT_ALLOCATED, "Unexpected status %08lx.\n", status); ok(status == STATUS_MEMORY_NOT_ALLOCATED, "Unexpected status %08lx.\n", status);
size = 0; size = 0;
addr = (char *)addr1 + 0x2000; addr = (char *)addr1 + 0x2000;
......
...@@ -4204,26 +4204,36 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *si ...@@ -4204,26 +4204,36 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *si
if (addr == (void *)1 && !size && type == MEM_RELEASE) virtual_release_address_space(); if (addr == (void *)1 && !size && type == MEM_RELEASE) virtual_release_address_space();
else status = STATUS_INVALID_PARAMETER; else status = STATUS_INVALID_PARAMETER;
} }
else if (!(view = find_view( base, size )) || !is_view_valloc( view )) else if (!(view = find_view( base, 0 ))) status = STATUS_MEMORY_NOT_ALLOCATED;
{ else if (!is_view_valloc( view )) status = STATUS_INVALID_PARAMETER;
status = STATUS_INVALID_PARAMETER;
}
else if (type == MEM_RELEASE) else if (type == MEM_RELEASE)
{ {
/* Free the pages */ /* Free the pages */
if (size) status = STATUS_INVALID_PARAMETER; if (size && (char *)view->base + view->size - base < size) status = STATUS_UNABLE_TO_FREE_VM;
else if (base != view->base) status = STATUS_FREE_VM_NOT_AT_BASE; else if (!size && base != view->base) status = STATUS_FREE_VM_NOT_AT_BASE;
else else
{ {
*addr_ptr = base; if (!size) size = view->size;
*size_ptr = view->size;
if (size == view->size)
{
assert( base == view->base );
delete_view( view ); delete_view( view );
} }
else
{
FIXME( "Parial view release is not supported.\n" );
status = STATUS_INVALID_PARAMETER;
}
*addr_ptr = base;
*size_ptr = size;
}
} }
else if (type == MEM_DECOMMIT) else if (type == MEM_DECOMMIT)
{ {
if (!size && base != view->base) status = STATUS_FREE_VM_NOT_AT_BASE; if (!size && base != view->base) status = STATUS_FREE_VM_NOT_AT_BASE;
else if (base - (char *)view->base + size > view->size) status = STATUS_UNABLE_TO_FREE_VM;
else status = decommit_pages( view, base - (char *)view->base, size ); else status = decommit_pages( view, base - (char *)view->base, size );
if (status == STATUS_SUCCESS) if (status == STATUS_SUCCESS)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment