[PATCH] ntdll: set correct protection flags on sections in builtin DLLs
Marcus Meissner
marcus at jet.franken.de
Sun Aug 22 15:58:31 CDT 2010
Hi,
Make sure we report the correct flags in NtQueryVirtualMemory
on a per section basis.
Triggered by the less correct patch in:
http://appdb.winehq.org/objectManager.php?sClass=version&iId=18971
http://bugs.winehq.org/show_bug.cgi?id=16998
Ciao, Marcus
---
dlls/ntdll/loader.c | 16 +++++++++++++++-
dlls/ntdll/ntdll_misc.h | 4 +++-
dlls/ntdll/tests/info.c | 14 +++++++-------
dlls/ntdll/virtual.c | 13 ++++++-------
4 files changed, 31 insertions(+), 16 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 4a2641b..bd641b7 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -1389,9 +1389,12 @@ static void load_builtin_callback( void *module, const char *filename )
{
static const WCHAR emptyW[1];
IMAGE_NT_HEADERS *nt;
+ IMAGE_SECTION_HEADER *sec;
WINE_MODREF *wm;
WCHAR *fullname;
const WCHAR *load_path;
+ int i;
+ struct file_view *view;
if (!module)
{
@@ -1406,7 +1409,18 @@ static void load_builtin_callback( void *module, const char *filename )
}
virtual_create_system_view( module, nt->OptionalHeader.SizeOfImage,
VPROT_SYSTEM | VPROT_IMAGE | VPROT_COMMITTED |
- VPROT_READ | VPROT_WRITECOPY | VPROT_EXEC );
+ VPROT_READ | VPROT_WRITECOPY | VPROT_EXEC, &view );
+
+ sec = (IMAGE_SECTION_HEADER*)((char*)&nt->OptionalHeader+nt->FileHeader.SizeOfOptionalHeader);
+ for (i=0;i<nt->FileHeader.NumberOfSections;i++) {
+ DWORD flags = VPROT_SYSTEM | VPROT_IMAGE | VPROT_COMMITTED;
+
+ if (sec[i].Characteristics & IMAGE_SCN_MEM_EXECUTE) flags |= VPROT_EXEC;
+ if (sec[i].Characteristics & IMAGE_SCN_MEM_READ) flags |= VPROT_READ;
+ if (sec[i].Characteristics & IMAGE_SCN_MEM_WRITE) flags |= VPROT_WRITE;
+ if (sec[i].Characteristics & IMAGE_SCN_MEM_SHARED) flags |= VPROT_WRITECOPY;
+ VIRTUAL_SetProt( view, (char*)module + sec[i].VirtualAddress, sec[i].Misc.VirtualSize, flags );
+ }
/* create the MODREF */
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index c7b721a..48944b5 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -155,7 +155,9 @@ extern NTSTATUS nt_to_unix_file_name_attr( const OBJECT_ATTRIBUTES *attr, ANSI_S
/* virtual memory */
extern void virtual_get_system_info( SYSTEM_BASIC_INFORMATION *info );
-extern NTSTATUS virtual_create_system_view( void *base, SIZE_T size, DWORD vprot );
+struct file_view;
+extern BOOL VIRTUAL_SetProt( struct file_view *view, void *base, size_t size, BYTE vprot );
+extern NTSTATUS virtual_create_system_view( void *base, SIZE_T size, DWORD vprot, struct file_view **view);
extern NTSTATUS virtual_alloc_thread_stack( TEB *teb, SIZE_T reserve_size, SIZE_T commit_size );
extern void virtual_clear_thread_stack(void);
extern BOOL virtual_handle_stack_fault( void *addr );
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c
index a56bcd1..f30c6ab 100644
--- a/dlls/ntdll/tests/info.c
+++ b/dlls/ntdll/tests/info.c
@@ -1077,15 +1077,15 @@ static void test_queryvirtualmemory(void)
MEMORY_BASIC_INFORMATION mbi;
char stackbuf[42];
- trace("Check flags of a function entry in NTDLL.DLL\n");
+ trace("Check flags of a function entry in NTDLL.DLL at %p\n", pNtQueryVirtualMemory);
status = pNtQueryVirtualMemory(NtCurrentProcess(), pNtQueryVirtualMemory, MemoryBasicInformation, &mbi, sizeof(MEMORY_BASIC_INFORMATION), &readcount);
ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
ok( readcount == sizeof(MEMORY_BASIC_INFORMATION), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION),readcount);
ok (mbi.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi.AllocationProtect, PAGE_EXECUTE_WRITECOPY);
ok (mbi.State == MEM_COMMIT, "mbi.State is 0x%x, expected 0x%x\n", mbi.State, MEM_COMMIT);
- todo_wine ok (mbi.Protect == PAGE_EXECUTE_READ, "mbi.Protect is 0x%x, expected 0x%x\n", mbi.Protect, PAGE_EXECUTE_READ);
+ ok (mbi.Protect == PAGE_EXECUTE_READ, "mbi.Protect is 0x%x, expected 0x%x\n", mbi.Protect, PAGE_EXECUTE_READ);
- trace("Check flags of heap\n");
+ trace("Check flags of heap at %p\n", GetProcessHeap());
status = pNtQueryVirtualMemory(NtCurrentProcess(), GetProcessHeap(), MemoryBasicInformation, &mbi, sizeof(MEMORY_BASIC_INFORMATION), &readcount);
ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
ok( readcount == sizeof(MEMORY_BASIC_INFORMATION), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION),readcount);
@@ -1095,7 +1095,7 @@ static void test_queryvirtualmemory(void)
ok (mbi.Protect == PAGE_READWRITE || mbi.Protect == PAGE_EXECUTE_READWRITE,
"mbi.Protect is 0x%x\n", mbi.Protect);
- trace("Check flags of stack\n");
+ trace("Check flags of stack at %p\n", stackbuf);
status = pNtQueryVirtualMemory(NtCurrentProcess(), stackbuf, MemoryBasicInformation, &mbi, sizeof(MEMORY_BASIC_INFORMATION), &readcount);
ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
ok( readcount == sizeof(MEMORY_BASIC_INFORMATION), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION),readcount);
@@ -1103,7 +1103,7 @@ static void test_queryvirtualmemory(void)
ok (mbi.State == MEM_COMMIT, "mbi.State is 0x%x, expected 0x%x\n", mbi.State, MEM_COMMIT);
ok (mbi.Protect == PAGE_READWRITE, "mbi.Protect is 0x%x, expected 0x%x\n", mbi.Protect, PAGE_READWRITE);
- trace("Check flags of read-only data\n");
+ trace("Check flags of read-only data at %p\n", teststring);
status = pNtQueryVirtualMemory(NtCurrentProcess(), teststring, MemoryBasicInformation, &mbi, sizeof(MEMORY_BASIC_INFORMATION), &readcount);
ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
ok( readcount == sizeof(MEMORY_BASIC_INFORMATION), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION),readcount);
@@ -1112,13 +1112,13 @@ static void test_queryvirtualmemory(void)
if (mbi.Protect != PAGE_READONLY)
todo_wine ok( mbi.Protect == PAGE_READONLY, "mbi.Protect is 0x%x, expected 0x%X\n", mbi.Protect, PAGE_READONLY);
- trace("Check flags of read-write global data (.bss)\n");
+ trace("Check flags of read-write global data (.bss) at %p\n", rwtestbuf);
status = pNtQueryVirtualMemory(NtCurrentProcess(), rwtestbuf, MemoryBasicInformation, &mbi, sizeof(MEMORY_BASIC_INFORMATION), &readcount);
ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
ok( readcount == sizeof(MEMORY_BASIC_INFORMATION), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION),readcount);
ok (mbi.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi.AllocationProtect, PAGE_EXECUTE_WRITECOPY);
ok (mbi.State == MEM_COMMIT, "mbi.State is 0x%x, expected 0x%X\n", mbi.State, MEM_COMMIT);
- todo_wine ok (mbi.Protect == PAGE_READWRITE, "mbi.Protect is 0x%x, expected 0x%X\n", mbi.Protect, PAGE_READWRITE);
+ ok (mbi.Protect == PAGE_READWRITE, "mbi.Protect is 0x%x, expected 0x%X\n", mbi.Protect, PAGE_READWRITE);
}
static void test_affinity(void)
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index 84427fb..9f564eb 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -597,10 +597,10 @@ static NTSTATUS get_vprot_flags( DWORD protect, unsigned int *vprot )
* TRUE: Success
* FALSE: Failure
*/
-static BOOL VIRTUAL_SetProt( FILE_VIEW *view, /* [in] Pointer to view */
- void *base, /* [in] Starting address */
- size_t size, /* [in] Size in bytes */
- BYTE vprot ) /* [in] Protections to use */
+BOOL VIRTUAL_SetProt( FILE_VIEW *view, /* [in] Pointer to view */
+ void *base, /* [in] Starting address */
+ size_t size, /* [in] Size in bytes */
+ BYTE vprot ) /* [in] Protections to use */
{
int unix_prot = VIRTUAL_GetUnixProt(vprot);
BYTE *p = view->prot + (((char *)base - (char *)view->base) >> page_shift);
@@ -1395,16 +1395,15 @@ void virtual_get_system_info( SYSTEM_BASIC_INFORMATION *info )
/***********************************************************************
* virtual_create_system_view
*/
-NTSTATUS virtual_create_system_view( void *base, SIZE_T size, DWORD vprot )
+NTSTATUS virtual_create_system_view( void *base, SIZE_T size, DWORD vprot, FILE_VIEW**view )
{
- FILE_VIEW *view;
NTSTATUS status;
sigset_t sigset;
size = ROUND_SIZE( base, size );
base = ROUND_ADDR( base, page_mask );
server_enter_uninterrupted_section( &csVirtual, &sigset );
- status = create_view( &view, base, size, vprot );
+ status = create_view( view, base, size, vprot );
if (!status) TRACE( "created %p-%p\n", base, (char *)base + size );
server_leave_uninterrupted_section( &csVirtual, &sigset );
return status;
--
1.7.1
More information about the wine-patches
mailing list