Here are three attempts to prevent this buffer overflow problem:
-
The gets function in the gcc C library does some kind of check to see that the input string doesn't overwrite the stack state (old ebp and return address)
-
The gcc compiler can use a similar technique for arbitrary functions meeting some criteria.
-
The operating system can place different padding to the bottom of the stack each time the program is run.