Heap

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 has real memory assigned to it and 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 (on-demand) paging, it is built up of text, data, uninitialized data (bss), heap and stack. Of these the heap and stack can grow nearly endlessly. 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. The heap is at an address higher than text and data and grows upwards in address space. The sbrk(2) system call is used to grow the heap when memory is needed by the malloc(3) routines. A process would be nearly 4 gigabytes in size when heap and stack meet, this was thought of as unlikely in early implementations of UNIX due to the restrictions in memory. Today 64 bit systems widen the margin of stack and heap ever meeting.



Heap Overflows
Due to bad programming some programs allow writing past the end of a buffer that has been allocated on the heap. This can result in the overwriting of other buffers and/or text. Another explanation is here.

OpenBSD's removal of the Heap
OpenBSD has done away with a heap growing upwards in version 3.8. Instead they mmap a region at a random location while making sure that other mapped regions are never adjacent creating a gap of uninitialized memory. This gap they call "guard pages" and they serve the function that when a buffer is overwritten that it will write into the guard page and cause a SIGSEGV signal saving the program from a successful heap attack.