Stack

A process covers the entire address space for the size of a pointer (32 bit in 32 bit architectures, 64 bit for 64 bit architectures). Since virtual memory is being used, not all areas of a process have real memory assigned to it, only some parts (access to parts that have no memory results in a SIGSEGV signal and the process is killed). A process may start small and grow by use of paging, which is built up of text, data, uninitialized data, heap and stack. Of these, the heap and stack can grow almost indefinitely. The stack is at a high address (0xfff00000 according to design and implementation of the 4.4BSD Operating System, but this has most likely changed) and grows downward toward the beginning of the address space, until it meets the heap. When a function (a memory region containing executable code) is called in a process the stack is added on with information about the last address location of the current function, this is needed so that when the called function returns the program knows where to jump back to. Also, the registers are "spilled" to the stack when they are required by the new function (because they have to be restored to their last state when the called function returns). As well, dynamic variables and buffers are allocated on the stack, as compared to static variables which are usually placed into the data section of the process.



Buffer Overflows on the stack
Due to shoddy programming, some programs allow buffers to be overwritten and if they are dynamic and reside on the stack a lot of crucial information can be clobbered. Attackers usually (and ingeniously) place executable code into the buffer and make sure that the address of this code is written into the function return pointer on the stack. When the function then returns the malicious code will be executed. More about this can be read here.

Stack Protection in OpenBSD
OpenBSD has designed buffer overflow protection called W xor X (W^X) meaning that an area in the stack can either be executable or writeable but not both. This is supposed to stop an attacker from writing their malicious code into the buffer. When a buffer is detected as having been overwritten, the process quits with a SIGABRT signal and dumps core. More on this is here. Other mechanism are Stack Ghost and Stack Gap to evade exploitation.