[PATCH v4 4/6] ntdll: Clarify NtAllocateVirtualMemory zero_bits parameter semantics
Rémi Bernon
rbernon at codeweavers.com
Tue May 28 05:15:16 CDT 2019
This parameter was misinterpreted as an alignment parameter for the
lower bits of the allocated memory region, although it is a constraint
on the higher bits.
Add a new internal ntdll virtual_alloc function that has a separate
alignment parameter which is now used instead of the zero_bits
parameter.
Replace external calls to NtAllocateVirtualMemory with VirtualAlloc.
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
dlls/commdlg.dll16/filedlg.c | 3 +--
dlls/ntdll/directory.c | 4 ++--
dlls/ntdll/heap.c | 5 ++---
dlls/ntdll/ntdll_misc.h | 2 ++
dlls/ntdll/signal_arm.c | 12 +++++------
dlls/ntdll/signal_arm64.c | 16 +++++++--------
dlls/ntdll/signal_i386.c | 16 +++++++--------
dlls/ntdll/signal_powerpc.c | 12 +++++------
dlls/ntdll/signal_x86_64.c | 16 +++++++--------
dlls/ntdll/thread.c | 3 +--
dlls/ntdll/virtual.c | 40 +++++++++++++++++++++++++++---------
11 files changed, 74 insertions(+), 55 deletions(-)
diff --git a/dlls/commdlg.dll16/filedlg.c b/dlls/commdlg.dll16/filedlg.c
index 5b72bfab100..050cddb0dd5 100644
--- a/dlls/commdlg.dll16/filedlg.c
+++ b/dlls/commdlg.dll16/filedlg.c
@@ -509,8 +509,7 @@ static LPOFNHOOKPROC alloc_hook( LPOFNHOOKPROC16 hook16 )
SIZE_T size = 0x1000;
unsigned int i;
- if (!hooks && NtAllocateVirtualMemory( GetCurrentProcess(), (void **)&hooks, 12, &size,
- MEM_COMMIT, PAGE_EXECUTE_READWRITE ))
+ if (!hooks && !(hooks = VirtualAlloc( NULL, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE )))
return NULL;
for (i = 0; i < count; i++)
diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c
index bbdbbe9781f..8292128ab51 100644
--- a/dlls/ntdll/directory.c
+++ b/dlls/ntdll/directory.c
@@ -1603,14 +1603,14 @@ static KERNEL_DIRENT *start_vfat_ioctl( int fd )
SIZE_T size = 2 * sizeof(*de) + page_size;
void *addr = NULL;
- if (NtAllocateVirtualMemory( GetCurrentProcess(), &addr, 1, &size, MEM_RESERVE, PAGE_READWRITE ))
+ if (virtual_alloc( &addr, 0, &size, MEM_RESERVE, PAGE_READWRITE, 1 ))
return NULL;
/* commit only the size needed for the dir entries */
/* this leaves an extra unaccessible page, which should make the kernel */
/* fail with -EFAULT before it stomps all over our memory */
de = addr;
size = 2 * sizeof(*de);
- NtAllocateVirtualMemory( GetCurrentProcess(), &addr, 1, &size, MEM_COMMIT, PAGE_READWRITE );
+ virtual_alloc( &addr, 0, &size, MEM_COMMIT, PAGE_READWRITE, 1 );
}
/* set d_reclen to 65535 to work around an AFS kernel bug */
diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c
index cccaaee1d45..6cf7bdccc6f 100644
--- a/dlls/ntdll/heap.c
+++ b/dlls/ntdll/heap.c
@@ -726,8 +726,7 @@ static void *allocate_large_block( HEAP *heap, DWORD flags, SIZE_T size )
LPVOID address = NULL;
if (block_size < size) return NULL; /* overflow */
- if (NtAllocateVirtualMemory( NtCurrentProcess(), &address, 5,
- &block_size, MEM_COMMIT, get_protection_type( flags ) ))
+ if (virtual_alloc( &address, 0, &block_size, MEM_COMMIT, get_protection_type( flags ), 5 ))
{
WARN("Could not allocate block for %08lx bytes\n", size );
return NULL;
@@ -1521,7 +1520,7 @@ void heap_set_debug_flags( HANDLE handle )
void *ptr = NULL;
SIZE_T size = MAX_FREE_PENDING * sizeof(*heap->pending_free);
- if (!NtAllocateVirtualMemory( NtCurrentProcess(), &ptr, 4, &size, MEM_COMMIT, PAGE_READWRITE ))
+ if (!virtual_alloc( &ptr, 0, &size, MEM_COMMIT, PAGE_READWRITE, 4 ))
{
heap->pending_free = ptr;
heap->pending_pos = 0;
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index 2d83f541bd5..24af706399b 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -168,6 +168,8 @@ extern NTSTATUS nt_to_unix_file_name_attr( const OBJECT_ATTRIBUTES *attr, ANSI_S
UINT disposition ) DECLSPEC_HIDDEN;
/* virtual memory */
+extern NTSTATUS virtual_alloc( PVOID *ret, ULONG zero_bits, SIZE_T *size_ptr,
+ ULONG type, ULONG protect, ULONG alignment );
extern NTSTATUS virtual_map_section( HANDLE handle, PVOID *addr_ptr, ULONG zero_bits, SIZE_T commit_size,
const LARGE_INTEGER *offset_ptr, SIZE_T *size_ptr, ULONG protect,
pe_image_info_t *image_info ) DECLSPEC_HIDDEN;
diff --git a/dlls/ntdll/signal_arm.c b/dlls/ntdll/signal_arm.c
index e01c8ce2193..12926d07563 100644
--- a/dlls/ntdll/signal_arm.c
+++ b/dlls/ntdll/signal_arm.c
@@ -967,22 +967,22 @@ int CDECL __wine_set_signal_handler(unsigned int sig, wine_signal_handler wsh)
*/
NTSTATUS signal_alloc_thread( TEB **teb )
{
- static size_t sigstack_zero_bits;
+ static size_t sigstack_alignment;
SIZE_T size;
NTSTATUS status;
- if (!sigstack_zero_bits)
+ if (!sigstack_alignment)
{
size_t min_size = page_size;
/* find the first power of two not smaller than min_size */
- while ((1u << sigstack_zero_bits) < min_size) sigstack_zero_bits++;
+ while ((1u << sigstack_alignment) < min_size) sigstack_alignment++;
assert( sizeof(TEB) <= min_size );
}
- size = 1 << sigstack_zero_bits;
+ size = 1 << sigstack_alignment;
*teb = NULL;
- if (!(status = NtAllocateVirtualMemory( NtCurrentProcess(), (void **)teb, sigstack_zero_bits,
- &size, MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE )))
+ if (!(status = virtual_alloc( (void **)teb, 0, &size, MEM_COMMIT | MEM_TOP_DOWN,
+ PAGE_READWRITE, sigstack_alignment )))
{
(*teb)->Tib.Self = &(*teb)->Tib;
(*teb)->Tib.ExceptionList = (void *)~0UL;
diff --git a/dlls/ntdll/signal_arm64.c b/dlls/ntdll/signal_arm64.c
index 94520c95ced..ebcf107f88d 100644
--- a/dlls/ntdll/signal_arm64.c
+++ b/dlls/ntdll/signal_arm64.c
@@ -871,24 +871,24 @@ int CDECL __wine_set_signal_handler(unsigned int sig, wine_signal_handler wsh)
*/
NTSTATUS signal_alloc_thread( TEB **teb )
{
- static size_t sigstack_zero_bits;
+ static size_t sigstack_alignment;
SIZE_T size;
NTSTATUS status;
- if (!sigstack_zero_bits)
+ if (!sigstack_alignment)
{
size_t min_size = teb_size + max( MINSIGSTKSZ, 8192 );
/* find the first power of two not smaller than min_size */
- sigstack_zero_bits = 12;
- while ((1u << sigstack_zero_bits) < min_size) sigstack_zero_bits++;
- signal_stack_size = (1 << sigstack_zero_bits) - teb_size;
+ sigstack_alignment = 12;
+ while ((1u << sigstack_alignment) < min_size) sigstack_alignment++;
+ signal_stack_size = (1 << sigstack_alignment) - teb_size;
assert( sizeof(TEB) <= teb_size );
}
- size = 1 << sigstack_zero_bits;
+ size = 1 << sigstack_alignment;
*teb = NULL;
- if (!(status = NtAllocateVirtualMemory( NtCurrentProcess(), (void **)teb, sigstack_zero_bits,
- &size, MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE )))
+ if (!(status = virtual_alloc( (void **)teb, 0, &size, MEM_COMMIT | MEM_TOP_DOWN,
+ PAGE_READWRITE, sigstack_alignment )))
{
(*teb)->Tib.Self = &(*teb)->Tib;
(*teb)->Tib.ExceptionList = (void *)~0UL;
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
index b4e88d125f1..9594e20551b 100644
--- a/dlls/ntdll/signal_i386.c
+++ b/dlls/ntdll/signal_i386.c
@@ -2312,25 +2312,25 @@ static void ldt_unlock(void)
*/
NTSTATUS signal_alloc_thread( TEB **teb )
{
- static size_t sigstack_zero_bits;
+ static size_t sigstack_alignment;
struct x86_thread_data *thread_data;
SIZE_T size;
void *addr = NULL;
NTSTATUS status;
- if (!sigstack_zero_bits)
+ if (!sigstack_alignment)
{
size_t min_size = teb_size + max( MINSIGSTKSZ, 8192 );
/* find the first power of two not smaller than min_size */
- sigstack_zero_bits = 12;
- while ((1u << sigstack_zero_bits) < min_size) sigstack_zero_bits++;
- signal_stack_mask = (1 << sigstack_zero_bits) - 1;
- signal_stack_size = (1 << sigstack_zero_bits) - teb_size;
+ sigstack_alignment = 12;
+ while ((1u << sigstack_alignment) < min_size) sigstack_alignment++;
+ signal_stack_mask = (1 << sigstack_alignment) - 1;
+ signal_stack_size = (1 << sigstack_alignment) - teb_size;
}
size = signal_stack_mask + 1;
- if (!(status = NtAllocateVirtualMemory( NtCurrentProcess(), &addr, sigstack_zero_bits,
- &size, MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE )))
+ if (!(status = virtual_alloc( &addr, 0, &size, MEM_COMMIT | MEM_TOP_DOWN,
+ PAGE_READWRITE, sigstack_alignment )))
{
*teb = addr;
(*teb)->Tib.Self = &(*teb)->Tib;
diff --git a/dlls/ntdll/signal_powerpc.c b/dlls/ntdll/signal_powerpc.c
index 86398d8f54f..15fde291647 100644
--- a/dlls/ntdll/signal_powerpc.c
+++ b/dlls/ntdll/signal_powerpc.c
@@ -1018,22 +1018,22 @@ int CDECL __wine_set_signal_handler(unsigned int sig, wine_signal_handler wsh)
*/
NTSTATUS signal_alloc_thread( TEB **teb )
{
- static size_t sigstack_zero_bits;
+ static size_t sigstack_alignment;
SIZE_T size;
NTSTATUS status;
- if (!sigstack_zero_bits)
+ if (!sigstack_alignment)
{
size_t min_size = page_size; /* this is just for the TEB, we don't use a signal stack yet */
/* find the first power of two not smaller than min_size */
- while ((1u << sigstack_zero_bits) < min_size) sigstack_zero_bits++;
+ while ((1u << sigstack_alignment) < min_size) sigstack_alignment++;
assert( sizeof(TEB) <= min_size );
}
- size = 1 << sigstack_zero_bits;
+ size = 1 << sigstack_alignment;
*teb = NULL;
- if (!(status = NtAllocateVirtualMemory( NtCurrentProcess(), (void **)teb, sigstack_zero_bits,
- &size, MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE )))
+ if (!(status = virtual_alloc( (void **)teb, 0, &size, MEM_COMMIT | MEM_TOP_DOWN,
+ PAGE_READWRITE, sigstack_alignment )))
{
(*teb)->Tib.Self = &(*teb)->Tib;
(*teb)->Tib.ExceptionList = (void *)~0UL;
diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c
index c2151f78c63..86c1878ea72 100644
--- a/dlls/ntdll/signal_x86_64.c
+++ b/dlls/ntdll/signal_x86_64.c
@@ -3263,24 +3263,24 @@ int CDECL __wine_set_signal_handler(unsigned int sig, wine_signal_handler wsh)
*/
NTSTATUS signal_alloc_thread( TEB **teb )
{
- static size_t sigstack_zero_bits;
+ static size_t sigstack_alignment;
SIZE_T size;
NTSTATUS status;
- if (!sigstack_zero_bits)
+ if (!sigstack_alignment)
{
size_t min_size = teb_size + max( MINSIGSTKSZ, 8192 );
/* find the first power of two not smaller than min_size */
- sigstack_zero_bits = 12;
- while ((1u << sigstack_zero_bits) < min_size) sigstack_zero_bits++;
- signal_stack_size = (1 << sigstack_zero_bits) - teb_size;
+ sigstack_alignment = 12;
+ while ((1u << sigstack_alignment) < min_size) sigstack_alignment++;
+ signal_stack_size = (1 << sigstack_alignment) - teb_size;
assert( sizeof(TEB) <= teb_size );
}
- size = 1 << sigstack_zero_bits;
+ size = 1 << sigstack_alignment;
*teb = NULL;
- if (!(status = NtAllocateVirtualMemory( NtCurrentProcess(), (void **)teb, sigstack_zero_bits,
- &size, MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE )))
+ if (!(status = virtual_alloc( (void **)teb, 0, &size, MEM_COMMIT | MEM_TOP_DOWN,
+ PAGE_READWRITE, sigstack_alignment )))
{
(*teb)->Tib.Self = &(*teb)->Tib;
(*teb)->Tib.ExceptionList = (void *)~0UL;
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index 46de839400d..974064a4b4d 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -184,8 +184,7 @@ void thread_init(void)
addr = NULL;
size = sizeof(*peb);
- NtAllocateVirtualMemory( NtCurrentProcess(), &addr, 1, &size,
- MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE );
+ virtual_alloc( &addr, 0, &size, MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE, 1 );
peb = addr;
peb->FastPebLock = &peb_lock;
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index 78973a8cda4..90475a01f21 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -2461,19 +2461,18 @@ void virtual_set_large_address_space(void)
NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG zero_bits,
SIZE_T *size_ptr, ULONG type, ULONG protect )
{
- void *base;
- unsigned int vprot;
- SIZE_T size = *size_ptr;
- SIZE_T mask = get_mask( zero_bits );
NTSTATUS status = STATUS_SUCCESS;
- BOOL is_dos_memory = FALSE;
- struct file_view *view;
- sigset_t sigset;
- TRACE("%p %p %08lx %x %08x\n", process, *ret, size, type, protect );
+ if (!size_ptr) return STATUS_ACCESS_VIOLATION;
- if (!size) return STATUS_INVALID_PARAMETER;
- if (!mask) return STATUS_INVALID_PARAMETER_3;
+ TRACE("%p %p %08lx %x %08x\n", process, *ret, *size_ptr, type, protect );
+
+ if (!*size_ptr) return STATUS_INVALID_PARAMETER;
+ if (zero_bits)
+ {
+ FIXME("Unimplemented zero_bits handling\n");
+ return STATUS_INVALID_PARAMETER_3;
+ }
if (process != NtCurrentProcess())
{
@@ -2499,6 +2498,27 @@ NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG zero_
return result.virtual_alloc.status;
}
+ return virtual_alloc( ret, zero_bits, size_ptr, type, protect, 0 );
+}
+
+
+/***********************************************************************
+ * virtual_alloc (NTDLL.@)
+ *
+ * Same as NtAllocateVirtualMemory but with an alignment parameter
+ */
+NTSTATUS virtual_alloc( PVOID *ret, ULONG zero_bits, SIZE_T *size_ptr,
+ ULONG type, ULONG protect, ULONG alignment )
+{
+ void *base;
+ unsigned int vprot;
+ SIZE_T size = *size_ptr;
+ SIZE_T mask = get_mask( alignment );
+ NTSTATUS status = STATUS_SUCCESS;
+ BOOL is_dos_memory = FALSE;
+ struct file_view *view;
+ sigset_t sigset;
+
/* Round parameters to a page boundary */
if (is_beyond_limit( 0, size, working_set_limit )) return STATUS_WORKING_SET_LIMIT_RANGE;
--
2.20.1
More information about the wine-devel
mailing list