A BufferOverflow can occurs when a program copies input data without checking its length into a buffer that's too short for the input in question, overwriting whatever is next in memory. This has been exploited to great effect in recent years due to sloppy C/C++ coding.

Because the Stack grows towards grows lower addresses ("down"), while buffers are written towards higher addresses ("upwards"), during function calls one of the next things in memory past a buffer usually is the address to return to from the call. By carefully chosing the value at the right place of your input data, you can overwrite this return address with a value that points into the buffer now filled with your input, thus causing the program to execute whatever data you provided once the function returns. Such input is usually carefully constructed malicious code.

Because of the wide applicability of this attack technique, it has been studied so thoroughly that construction of exploitative input has become an almost formulaic procedure. The timespan between the discovery of a BufferOverflow vulnerability and creation of an exploit is rarely longer than a day, and often a matter of only hours.

An obvious but shortsighted counter is to mark the memory area containing the Stack as non-executable. The problem is that even though you can't do conditionals this way, the input data could still be constructed to cause execution of arbitrary functions or a sequence thereof. F.ex, execution could "return" into system(3) with "rm -rf /" as a parameter on the stack. This is only a plump example; it is conceivable for an attacker to choose other calls so as to eg. gain access to a root shell.