[Bug 31892] New: Handle failure to reserve NT shared user data at 0x7ffe0000 (Windows on ARM)

wine-bugs at winehq.org wine-bugs at winehq.org
Fri Oct 5 14:56:29 CDT 2012


http://bugs.winehq.org/show_bug.cgi?id=31892

             Bug #: 31892
           Summary: Handle failure to reserve NT shared user data at
                    0x7ffe0000 (Windows on ARM)
           Product: Wine
           Version: 1.5.14
          Platform: arm
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: ntdll
        AssignedTo: wine-bugs at winehq.org
        ReportedBy: focht at gmx.net
    Classification: Unclassified


Hello,

I recently resumed some investigations with Windows on ARM apps/installers and
ran into a problem due to a kernel 3.2 -> 3.0 downgrade.
The kernel downgrade was necessary because Freescale left Linaro some months
ago, stalling/halting all Linaro projects targeting i.mx platforms (the last
kernels were still buggy as hell anyway).

Back to a Linux 3.0.x kernel now which is being actively developed/maintained
within Freescale.
Unfortunately all wine builtins simply segfault on startup.

The code that fails:

http://source.winehq.org/git/wine.git/blob/6ec731b65cb6525d04b86737ff85a3e77054ed36:/dlls/ntdll/thread.c#l196

--- snip ---
 196 HANDLE thread_init(void)
 197 {
 198     TEB *teb;
 199     void *addr;
 200     SIZE_T size, info_size;
 201     HANDLE exe_file = 0;
 202     LARGE_INTEGER now;
 203     struct ntdll_thread_data *thread_data;
 204     static struct debug_info debug_info;  /* debug info for initial thread
*/
 205 
 206     virtual_init();
 207 
 208     /* reserve space for shared user data */
 209 
 210     addr = (void *)0x7ffe0000;
 211     size = 0x10000;
 212     NtAllocateVirtualMemory( NtCurrentProcess(), &addr, 0, &size,
MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
 213     user_shared_data = addr;
...
 293     /* initialize time values in user_shared_data */
 294     NtQuerySystemTime( &now );
 295     user_shared_data->SystemTime.LowPart = now.u.LowPart;
--- snip ---

NtAllocateVirtualMemory() fails to reserve that range but no return value
evaluation takes place hence the initial start address value is still taken.
Dereferencing of "user_shared_data" (USER_SHARED_DATA) causes the segfault.

Before the syscall:

--- snip ---
...
(gdb) bt
#0  0x2acc4a80 in mmap64 () from /lib/arm-linux-gnueabi/libc.so.6
#1  0x2aad45cc in wine_anon_mmap (start=0x7ffe0000, size=65536, prot=3,
flags=34)
    at /home/linaro/projects/wine/wine-git/libs/wine/mmap.c:221
#2  0x2add2cf8 in map_view (view_ret=0x7effebe4, base=0x7ffe0000, size=65536,
mask=65535, top_down=0, 
    vprot=1091) at /home/linaro/projects/wine/wine-git/dlls/ntdll/virtual.c:794
#3  0x2add7594 in NtAllocateVirtualMemory (process=0xffffffff, ret=0x7effecb0,
zero_bits=0, 
    size_ptr=0x7effecb4, type=12288, protect=4)
    at /home/linaro/projects/wine/wine-git/dlls/ntdll/virtual.c:1937
#4  0x2adc6554 in thread_init () at
/home/linaro/projects/wine/wine-git/dlls/ntdll/thread.c:212
#5  0x2ad8d5f4 in __wine_process_init () at
/home/linaro/projects/wine/wine-git/dlls/ntdll/loader.c:2892
#6  0x2aad2fdc in wine_init (argc=2, argv=0x7efff2a4, error=0x7effed4c "",
error_size=1024)
    at /home/linaro/projects/wine/wine-git/libs/wine/loader.c:831
#7  0x00008bbc in main (argc=2, argv=0x7efff2a4) at
/home/linaro/projects/wine/wine-git/loader/main.c:237 
..
--- snip ---

After syscall:

--- snip ---
(gdb) n
map_view (view_ret=0x7effebe4, base=0x7ffe0000, size=65536, mask=65535,
top_down=0, vprot=1091)
    at /home/linaro/projects/wine/wine-git/dlls/ntdll/virtual.c:799
799                if (ptr != base)
(gdb) info locals
ptr = 0x2ac05000
status = 2147352576
...
--- snip ---

-> STATUS_CONFLICTING_ADDRESSES 

mmap() failed to reserve 0x7ffe0000 and instead gave a different address range
in TASK_UNMAPPED_BASE area (0x2ac05000).

mmap VM area for userspace tasks: "arch/arm/include/asm/memory.h"

--- snip ---
...
#ifdef CONFIG_MMU

/*
 * PAGE_OFFSET - the virtual address of the start of the kernel image
 * TASK_SIZE - the maximum size of a user space task.
 * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area
 */
#define PAGE_OFFSET        UL(CONFIG_PAGE_OFFSET)
#define TASK_SIZE        (UL(CONFIG_PAGE_OFFSET) - UL(0x01000000))
#define TASK_UNMAPPED_BASE    (UL(CONFIG_PAGE_OFFSET) / 3)

/*
 * The maximum size of a 26-bit user space task.
 */
#define TASK_SIZE_26        UL(0x04000000)

/*
 * The module space lives between the addresses given by TASK_SIZE
 * and PAGE_OFFSET - it must be within 32MB of the kernel text.
 */
#ifndef CONFIG_THUMB2_KERNEL
#define MODULES_VADDR        (PAGE_OFFSET - 16*1024*1024)
#else
/* smaller range for Thumb-2 symbols relocation (2^24)*/
#define MODULES_VADDR        (PAGE_OFFSET - 8*1024*1024)
#endif

#if TASK_SIZE > MODULES_VADDR
#error Top of user space clashes with start of module space
#endif 
...
--- snip ---

Relevant kernel config settings:

--- snip ---
...
# CONFIG_VMSPLIT_3G is not set
CONFIG_VMSPLIT_2G=y
# CONFIG_VMSPLIT_1G is not set
CONFIG_PAGE_OFFSET=0x80000000  
...
--- snip ---

(TASK_SIZE = 0x7F000000) -> arch_get_unmapped_area() will not accept address
0x7ffe0000.

I worked around by moving to a 3GiB/1GiB user/kernel virtual memory split ->
CONFIG_PAGE_OFFSET=0xC0000000.

Anyway the reservation failure should be handled gracefully by either refusing
to run (at least on x86 platforms) or accept a new address range.

I don't know if USER_SHARED_DATA at 0x7ffe0000 exists/makes sense for Windows
on ARM platforms.
One has yet to see a real WoA system...

Regards

-- 
Configure bugmail: http://bugs.winehq.org/userprefs.cgi?tab=email
Do not reply to this email, post in Bugzilla using the
above URL to reply.
------- You are receiving this mail because: -------
You are watching all bug changes.



More information about the wine-bugs mailing list