http://bugs.winehq.org/show_bug.cgi?id=12783
Summary: Allocation of PEB and TEB can overlap dll mappings Product: Wine Version: 0.9.60 Platform: PC OS/Version: Solaris Status: UNCONFIRMED Severity: critical Priority: P2 Component: ntdll AssignedTo: wine-bugs@winehq.org ReportedBy: trisk+winehq@acm.jhu.edu
thread_init in ntdll/thread.c is responsible for setting up the control structures for a new thread. It allocates memory for a user data region, a PEB (Process Environment Block), and a TEB (Thread Environment Block).
On Windows NT, the PEB and the first TEB are fixed at 0x7ffdf000 and 0x7ffde000, respectively, unless the kernel is patched for address randomisation. The TEB is one page (see wine's definition of TEB) and adjacent to the PEB.
thread_init uses NtAllocateVirtualMemory backed by anonymous mmaps. It allocates a 64k region for user data at a fixed address of 0x7ffe0000. For the PEB and TEB allocations, the system is free to choose the address. The TEB in Wine is actually allocated as part of larger region also storing pthreads data, so it doesn't fit in the address that Windows uses for it without overlapping the traditional PEB region.
Later on, __wine_process_init in dlls/ntdll/loader.c loads builtin dlls to their respective addresses. This calls NtAllocateVirtualMemory and there is code in create_view to deal with overlapping segments. It is asserted that no allocation should overlap with a segment that doesn't have the VFLAG_SYSTEM flag set.
In Wine 0.9.60 on Solaris, one of the dll allocations (ntdll at 7ff90000-7ffdb000 ) would overlap with the PEB at 7ffb0000-7ffb1000, which triggers the assert.
Regression testing shows that this commit caused the regression, possibly because of size changes for ntdll: [4c6d2b01cc842ac13af6257a0c41f67ae49c992a] ntdll: Don't create a temporary dir, run wineprefixcreate directly in the final dir.
Possible solutions: Mapping the TEB and PEB at fixed addresses Ensuring NtAllocateVirtualMemory mmaps do not overlap with the dll address space accidentally.