ReactOS 0.4.16-dev-2491-g3dc6630
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 25 of file StackOverflow.c.

26{
27 MEMORY_BASIC_INFORMATION MemoryBasicInfo;
29 char Buffer[0x500];
30
31 sprintf(Buffer, "Iteration %d.\n", iteration++);
32
35 &Buffer[0],
37 &MemoryBasicInfo,
38 sizeof(MemoryBasicInfo),
39 NULL);
41 /* This never changes */
43 /* Stack is committed one page at a time */
44 ok_ptr(MemoryBasicInfo.BaseAddress, (PVOID)PAGE_ROUND_DOWN(&Buffer[0]));
45 /* This is the protection of the memory when it was reserved. */
47 /* Windows commits the whole used stack at once, +2 pages. */
48#if 0
50#endif
51 /* This is the state of the queried address */
52 ok_long(MemoryBasicInfo.State, MEM_COMMIT);
53 /* This is the protection of the queried address */
54 ok_long(MemoryBasicInfo.Protect, PAGE_READWRITE);
55 /* Of course this is private memory. */
56 ok_long(MemoryBasicInfo.Type, MEM_PRIVATE);
57
58 LastStackAllocation = &Buffer[-0x500];
59
61}
static PVOID StackAllocationBase
Definition: StackOverflow.c:19
static ULONG StackSize
Definition: StackOverflow.c:21
static PVOID LastStackAllocation
Definition: StackOverflow.c:20
static int iteration
Definition: StackOverflow.c:18
static void infinite_recursive(void)
Definition: StackOverflow.c:25
#define ok_ntstatus(status, expected)
Definition: atltest.h:135
#define ok_long(expression, result)
Definition: atltest.h:133
#define ok_ptr(expression, result)
Definition: atltest.h:108
LONG NTSTATUS
Definition: precomp.h:26
Definition: bufpool.h:45
#define NULL
Definition: types.h:112
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Status
Definition: gdiplustypes.h:25
#define sprintf
Definition: sprintf.c:45
@ MemoryBasicInformation
Definition: mmtypes.h:183
#define PAGE_ROUND_DOWN(x)
Definition: mmtypes.h:36
#define PAGE_READWRITE
Definition: nt_native.h:1307
#define MEM_PRIVATE
Definition: nt_native.h:1321
#define NtCurrentProcess()
Definition: nt_native.h:1660
#define MEM_COMMIT
Definition: nt_native.h:1316
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:4374
#define STATUS_SUCCESS
Definition: shellext.h:65
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by infinite_recursive(), and START_TEST().

◆ START_TEST()

START_TEST ( StackOverflow  )

Definition at line 63 of file StackOverflow.c.

64{
66 MEMORY_BASIC_INFORMATION MemoryBasicInfo;
67
68 /* Get the base of the stack */
71 &Status,
73 &MemoryBasicInfo,
74 sizeof(MemoryBasicInfo),
75 NULL);
77 StackAllocationBase = MemoryBasicInfo.AllocationBase;
78 trace("Stack allocation base is %p.\n", StackAllocationBase);
79 StackSize = MemoryBasicInfo.RegionSize;
80
81 /* Check TEB attributes */
82 ok_ptr(NtCurrentTeb()->DeallocationStack, StackAllocationBase);
83 ok_ptr(NtCurrentTeb()->NtTib.StackBase, (PVOID)((ULONG_PTR)MemoryBasicInfo.BaseAddress + MemoryBasicInfo.RegionSize));
84#ifdef _WIN64
85 ok_ptr(NtCurrentTeb()->NtTib.StackLimit, (PVOID)((ULONG_PTR)MemoryBasicInfo.BaseAddress - 2 * PAGE_SIZE));
86#else
87 ok_ptr(NtCurrentTeb()->NtTib.StackLimit, (PVOID)((ULONG_PTR)MemoryBasicInfo.BaseAddress - PAGE_SIZE));
88#endif
89 trace("Guaranteed stack size is %lu.\n", NtCurrentTeb()->GuaranteedStackBytes);
90
91 /* Get its size */
96 &MemoryBasicInfo,
97 sizeof(MemoryBasicInfo),
98 NULL);
100
101 /* This is the complete stack size */
102 StackSize += MemoryBasicInfo.RegionSize;
103 trace("Stack size is 0x%lx.\n", StackSize);
104
105 trace("Stack limit %p, stack base %p.\n", NtCurrentTeb()->NtTib.StackLimit, NtCurrentTeb()->NtTib.StackBase);
106
107 /* Take a look at what is beyond the stack limit */
110 NtCurrentTeb()->NtTib.StackLimit,
112 &MemoryBasicInfo,
113 sizeof(MemoryBasicInfo),
114 NULL);
116
117 ok_ptr(MemoryBasicInfo.BaseAddress, NtCurrentTeb()->NtTib.StackLimit);
118 ok_ptr(MemoryBasicInfo.AllocationBase, StackAllocationBase);
119 ok_long(MemoryBasicInfo.AllocationProtect, PAGE_READWRITE);
120#ifdef _WIN64
121 ok_long(MemoryBasicInfo.RegionSize, 3 * PAGE_SIZE);
122#else
123 ok_long(MemoryBasicInfo.RegionSize, 2 * PAGE_SIZE);
124#endif
125 ok_long(MemoryBasicInfo.State, MEM_COMMIT);
126 ok_long(MemoryBasicInfo.Protect, PAGE_READWRITE);
127 ok_long(MemoryBasicInfo.Type, MEM_PRIVATE);
128
129 /* Accessing below stack limit is OK, as long as we don't starve the reserved space. */
131 {
132 volatile CHAR* Pointer = (PVOID)((ULONG_PTR)NtCurrentTeb()->NtTib.StackLimit - PAGE_SIZE / 2);
133 CHAR Value = *Pointer;
134 (void)Value;
136 }
138 {
140 }
141 _SEH2_END;
143
145 {
147 }
149 {
150 trace("Exception after %d iteration.\n", iteration);
152 }
153 _SEH2_END;
154
156
157 /* Windows lets 2 pages between the reserved memory and the smallest possible stack address */
159#ifdef _WIN64
161#else
163#endif
164
165 /* And in fact, this is the true condition of the stack overflow */
167
168 trace("Stack limit %p, stack base %p.\n", NtCurrentTeb()->NtTib.StackLimit, NtCurrentTeb()->NtTib.StackBase);
169
170 /* Of course, accessing above the stack limit is OK. */
172 {
173 volatile CHAR* Pointer = (PVOID)((ULONG_PTR)NtCurrentTeb()->NtTib.StackLimit + PAGE_SIZE / 2);
174 CHAR Value = *Pointer;
175 (void)Value;
177 }
179 {
181 }
182 _SEH2_END;
184
185 /* But once stack is starved, it's starved. */
187 {
188 volatile CHAR* Pointer = (PVOID)((ULONG_PTR)NtCurrentTeb()->NtTib.StackLimit - PAGE_SIZE / 2);
189 CHAR Value = *Pointer;
190 (void)Value;
192 }
194 {
195 trace("Exception after %d iteration.\n", iteration);
197 }
198 _SEH2_END;
200}
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define STATUS_ACCESS_VIOLATION
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define NtCurrentTeb
#define STATUS_STACK_OVERFLOW
Definition: ntstatus.h:583
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:204
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
void * PVOID
Definition: typedefs.h:50
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
char CHAR
Definition: xmlstorage.h:175

Variable Documentation

◆ iteration

◆ LastStackAllocation

PVOID LastStackAllocation
static

Definition at line 20 of file StackOverflow.c.

Referenced by infinite_recursive(), and START_TEST().

◆ StackAllocationBase

PVOID StackAllocationBase
static

Definition at line 19 of file StackOverflow.c.

Referenced by infinite_recursive(), and START_TEST().

◆ StackSize