How does a buffer overrun corrupt the return address? I got stuck on the following note while reading a paper about computer security:

The stack mixes program data and control data
– by overrunning buffers on the stack we can corrupt the return  addresses!


In fact, I didn't understand how a buffer overrun corrupts the return address within a stack frame. Also the use of the term buffers was not very clear to me - what do they mean?
When your code calls a function, the called function usually allocates memory for its variables, just before the memory where the return address is stored (the address of the caller). 

Let's say you have an array int a[100], and a double variable x. The compiler may quite reasonably allocate memory for x either just before or just after the memory for a. In the first case, setting a [-1] = 100; a [-2] = 1000; will likely change x. In the latter case, setting a [100] = 100; a [101] = 1000; will do the same thing. Trying to store into an array, using an index that is too small or too large, is called a "buffer overflow". 

Now if you store a [102] = 0; or a [103] = 0; then chances are that this overwrites the memory where the caller's return address was stored. And if the function tries to return, the processor will start running code at the address that you stored into a [102] and a [103] with all kinds of negative consequences.