ReactOS  0.4.15-dev-5640-g0dde428
StackOverflow.c File Reference
#include "precomp.h"
#include <pseh/pseh2.h>
Include dependency graph for StackOverflow.c:

Go to the source code of this file.

Functions

static void infinite_recursive (void)
 
 START_TEST (StackOverflow)
 

Variables

static int iteration = 0
 
static PVOID StackAllocationBase
 
static PVOID LastStackAllocation
 
static ULONG StackSize
 

Function Documentation

◆ infinite_recursive()

static void infinite_recursive ( void  )
static

Definition at line 23 of file StackOverflow.c.

24 {
25  MEMORY_BASIC_INFORMATION MemoryBasicInfo;
27  char Buffer[0x500];
28 
29  sprintf(Buffer, "Iteration %d.\n", iteration++);
30 
33  &Buffer[0],
35  &MemoryBasicInfo,
36  sizeof(MemoryBasicInfo),
37  NULL);
39  /* This never changes */
40  ok_ptr(MemoryBasicInfo.AllocationBase, StackAllocationBase);
41  /* Stack is committed one page at a time */
42  ok_ptr(MemoryBasicInfo.BaseAddress, (PVOID)PAGE_ROUND_DOWN(&Buffer[0]));
43  /* This is the protection of the memory when it was reserved. */
44  ok_long(MemoryBasicInfo.AllocationProtect, PAGE_READWRITE);
45  /* Windows commits the whole used stack at once, +2 pages. */
46 #if 0
48 #endif
49  /* This is the state of the queried address */
50  ok_long(MemoryBasicInfo.State, MEM_COMMIT);
51  /* This is the protection of the queried address */
52  ok_long(MemoryBasicInfo.Protect, PAGE_READWRITE);
53  /* Of course this is private memory. */
54  ok_long(MemoryBasicInfo.Type, MEM_PRIVATE);
55 
56  LastStackAllocation = &Buffer[-0x500];
57 
59 }
LONG NTSTATUS
Definition: precomp.h:26
static int iteration
Definition: StackOverflow.c:16
static ULONG StackSize
Definition: StackOverflow.c:19
#define PAGE_ROUND_DOWN(x)
Definition: mmtypes.h:36
NTSTATUS NTAPI NtQueryVirtualMemory(IN HANDLE ProcessHandle, IN PVOID BaseAddress, IN MEMORY_INFORMATION_CLASS MemoryInformationClass, OUT PVOID MemoryInformation, IN SIZE_T MemoryInformationLength, OUT PSIZE_T ReturnLength)
Definition: virtual.c:4403
#define ok_ptr(expression, result)
Definition: atltest.h:108
#define ok_long(expression, result)
Definition: atltest.h:133
#define MEM_COMMIT
Definition: nt_native.h:1313
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static PVOID StackAllocationBase
Definition: StackOverflow.c:17
Definition: bufpool.h:45
#define NtCurrentProcess()
Definition: nt_native.h:1657
Status
Definition: gdiplustypes.h:24
#define MEM_PRIVATE
Definition: nt_native.h:1318
static void infinite_recursive(void)
Definition: StackOverflow.c:23
static PVOID LastStackAllocation
Definition: StackOverflow.c:18
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define NULL
Definition: types.h:112
#define ok_ntstatus(status, expected)
Definition: atltest.h:135
#define STATUS_SUCCESS
Definition: shellext.h:65
#define PAGE_READWRITE
Definition: nt_native.h:1304

Referenced by START_TEST().

◆ START_TEST()

START_TEST ( StackOverflow  )

Definition at line 61 of file StackOverflow.c.

62 {
64  MEMORY_BASIC_INFORMATION MemoryBasicInfo;
65 
66  /* Get the base of the stack */
69  &Status,
71  &MemoryBasicInfo,
72  sizeof(MemoryBasicInfo),
73  NULL);
75  StackAllocationBase = MemoryBasicInfo.AllocationBase;
76  trace("Stack allocation base is %p.\n", StackAllocationBase);
77  StackSize = MemoryBasicInfo.RegionSize;
78 
79  /* Check TEB attributes */
80  ok_ptr(NtCurrentTeb()->DeallocationStack, StackAllocationBase);
81  ok_ptr(NtCurrentTeb()->NtTib.StackBase, (PVOID)((ULONG_PTR)MemoryBasicInfo.BaseAddress + MemoryBasicInfo.RegionSize));
82 #ifdef _WIN64
83  ok_ptr(NtCurrentTeb()->NtTib.StackLimit, (PVOID)((ULONG_PTR)MemoryBasicInfo.BaseAddress - 2 * PAGE_SIZE));
84 #else
85  ok_ptr(NtCurrentTeb()->NtTib.StackLimit, (PVOID)((ULONG_PTR)MemoryBasicInfo.BaseAddress - PAGE_SIZE));
86 #endif
87  trace("Guaranteed stack size is %lu.\n", NtCurrentTeb()->GuaranteedStackBytes);
88 
89  /* Get its size */
94  &MemoryBasicInfo,
95  sizeof(MemoryBasicInfo),
96  NULL);
98 
99  /* This is the complete stack size */
100  StackSize += MemoryBasicInfo.RegionSize;
101  trace("Stack size is 0x%lx.\n", StackSize);
102 
103  trace("Stack limit %p, stack base %p.\n", NtCurrentTeb()->NtTib.StackLimit, NtCurrentTeb()->NtTib.StackBase);
104 
105  /* Take a look at what is beyond the stack limit */
108  NtCurrentTeb()->NtTib.StackLimit,
110  &MemoryBasicInfo,
111  sizeof(MemoryBasicInfo),
112  NULL);
114 
115  ok_ptr(MemoryBasicInfo.BaseAddress, NtCurrentTeb()->NtTib.StackLimit);
116  ok_ptr(MemoryBasicInfo.AllocationBase, StackAllocationBase);
117  ok_long(MemoryBasicInfo.AllocationProtect, PAGE_READWRITE);
118 #ifdef _WIN64
119  ok_long(MemoryBasicInfo.RegionSize, 3 * PAGE_SIZE);
120 #else
121  ok_long(MemoryBasicInfo.RegionSize, 2 * PAGE_SIZE);
122 #endif
123  ok_long(MemoryBasicInfo.State, MEM_COMMIT);
124  ok_long(MemoryBasicInfo.Protect, PAGE_READWRITE);
125  ok_long(MemoryBasicInfo.Type, MEM_PRIVATE);
126 
127  /* Accessing below stack limit is OK, as long as we don't starve the reserved space. */
128  _SEH2_TRY
129  {
130  volatile CHAR* Pointer = (PVOID)((ULONG_PTR)NtCurrentTeb()->NtTib.StackLimit - PAGE_SIZE / 2);
131  CHAR Value = *Pointer;
132  (void)Value;
134  }
136  {
138  }
139  _SEH2_END;
141 
142  _SEH2_TRY
143  {
145  }
147  {
148  trace("Exception after %d iteration.\n", iteration);
150  }
151  _SEH2_END;
152 
154 
155  /* Windows lets 2 pages between the reserved memory and the smallest possible stack address */
157 #ifdef _WIN64
159 #else
161 #endif
162 
163  /* And in fact, this is the true condition of the stack overflow */
164  ok_ptr(NtCurrentTeb()->NtTib.StackLimit, (PVOID)((ULONG_PTR)StackAllocationBase + PAGE_SIZE));
165 
166  trace("Stack limit %p, stack base %p.\n", NtCurrentTeb()->NtTib.StackLimit, NtCurrentTeb()->NtTib.StackBase);
167 
168  /* Of course, accessing above the stack limit is OK. */
169  _SEH2_TRY
170  {
171  volatile CHAR* Pointer = (PVOID)((ULONG_PTR)NtCurrentTeb()->NtTib.StackLimit + PAGE_SIZE / 2);
172  CHAR Value = *Pointer;
173  (void)Value;
175  }
177  {
179  }
180  _SEH2_END;
182 
183  /* But once stack is starved, it's starved. */
184  _SEH2_TRY
185  {
186  volatile CHAR* Pointer = (PVOID)((ULONG_PTR)NtCurrentTeb()->NtTib.StackLimit - PAGE_SIZE / 2);
187  CHAR Value = *Pointer;
188  (void)Value;
190  }
192  {
193  trace("Exception after %d iteration.\n", iteration);
195  }
196  _SEH2_END;
198 }
_SEH2_TRY
Definition: create.c:4226
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
char CHAR
Definition: xmlstorage.h:175
LONG NTSTATUS
Definition: precomp.h:26
static int iteration
Definition: StackOverflow.c:16
static ULONG StackSize
Definition: StackOverflow.c:19
#define PAGE_ROUND_DOWN(x)
Definition: mmtypes.h:36
NTSTATUS NTAPI NtQueryVirtualMemory(IN HANDLE ProcessHandle, IN PVOID BaseAddress, IN MEMORY_INFORMATION_CLASS MemoryInformationClass, OUT PVOID MemoryInformation, IN SIZE_T MemoryInformationLength, OUT PSIZE_T ReturnLength)
Definition: virtual.c:4403
#define ok_ptr(expression, result)
Definition: atltest.h:108
_SEH2_END
Definition: create.c:4400
#define ok_long(expression, result)
Definition: atltest.h:133
#define MEM_COMMIT
Definition: nt_native.h:1313
uint32_t ULONG_PTR
Definition: typedefs.h:65
static PVOID StackAllocationBase
Definition: StackOverflow.c:17
void * PVOID
Definition: retypes.h:9
#define NtCurrentProcess()
Definition: nt_native.h:1657
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
Status
Definition: gdiplustypes.h:24
#define trace
Definition: atltest.h:70
#define MEM_PRIVATE
Definition: nt_native.h:1318
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
static void infinite_recursive(void)
Definition: StackOverflow.c:23
static PVOID LastStackAllocation
Definition: StackOverflow.c:18
#define PAGE_SIZE
Definition: env_spec_w32.h:49
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define ok(value,...)
Definition: atltest.h:57
#define NULL
Definition: types.h:112
#define STATUS_STACK_OVERFLOW
Definition: ntstatus.h:489
#define ok_ntstatus(status, expected)
Definition: atltest.h:135
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define STATUS_SUCCESS
Definition: shellext.h:65
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define PAGE_READWRITE
Definition: nt_native.h:1304

Variable Documentation

◆ iteration

int iteration = 0
static

◆ LastStackAllocation

PVOID LastStackAllocation
static

Definition at line 18 of file StackOverflow.c.

Referenced by infinite_recursive(), and START_TEST().

◆ StackAllocationBase

PVOID StackAllocationBase
static

Definition at line 17 of file StackOverflow.c.

Referenced by infinite_recursive(), and START_TEST().

◆ StackSize

ULONG StackSize
static

Definition at line 19 of file StackOverflow.c.

Referenced by infinite_recursive(), and START_TEST().