NT allocates one page as TEB. Some native NT-dlls are using this.

diff --git a/scheduler/thread.c b/scheduler/thread.c
index e09e634..591723e 100644
--- a/scheduler/thread.c
+++ b/scheduler/thread.c
@@ -163,7 +163,7 @@
     close( teb->socket );
     if (teb->buffer) munmap( teb->buffer, teb->buffer_size );
     VirtualFree( teb->stack_base, 0, MEM_RELEASE );
-    HeapFree( SystemHeap, 0, teb );
+    VirtualFree( teb, 0, MEM_FREE );
 }
 
 
@@ -202,6 +202,12 @@
 
 /***********************************************************************
  *           THREAD_Create
+ *
+ * NOTES:
+ * 	Native NT dlls are using the space left on the allocated page
+ *	the first allocated TEB on NT is at 0x7ffde000, since we can't
+ *	allocate in this area and don't support a granularity of 4kb
+ *	yet we leave it to VirtualAlloc to choose an address.
  */
 TEB *THREAD_Create( PDB *pdb, DWORD flags, DWORD stack_size, BOOL alloc_stack16,
                      LPSECURITY_ATTRIBUTES sa, int *server_handle )
@@ -210,7 +216,7 @@
     int fd[2];
     HANDLE cleanup_object;
 
-    TEB *teb = HeapAlloc( SystemHeap, HEAP_ZERO_MEMORY, sizeof(TEB) );
+    TEB *teb = VirtualAlloc(0, 0x1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
     if (!teb) return NULL;
     teb->except      = (void *)-1;
     teb->htask16     = pdb->task;
@@ -258,13 +264,14 @@
 			   0, FALSE, DUPLICATE_SAME_ACCESS ) ) goto error;
     teb->cleanup = SERVICE_AddObject( cleanup_object, THREAD_FreeTEB, (ULONG_PTR)teb );
 
+    TRACE("(%p) succeeded\n", teb);
     return teb;
 
 error:
     if (*server_handle != -1) CloseHandle( *server_handle );
     if (teb->teb_sel) SELECTOR_FreeBlock( teb->teb_sel, 1 );
     if (teb->socket != -1) close( teb->socket );
-    HeapFree( SystemHeap, 0, teb );
+    VirtualFree( teb, 0, MEM_FREE );
     return NULL;
 }