Explain the stack layout and how overwriting the return address enables code execution.
A function's stack frame holds its buffer, the saved frame pointer, and the return address; overflowing the buffer upward lets you overwrite the return address, and the CPU blindly jumps to whatever value sits there on ret.

* Program stack after a buffer overflow — the oversized input has overwritten the saved return address, so the CPU jumps to attacker-chosen code on return. — Michael Lynn, Public domain, via Wikimedia Commons. *
The stack stores local variables, saved frame pointer, and return address — an overflow can overwrite all of them:
[Local variables (buffer)] ← Low address
[Saved frame pointer]
[Return address] ← Where to jump after function returns
[Caller's stack frame] ← High address
Normal execution: Function finishes, CPU reads return address, jumps back to caller.
Buffer overflow attack:
- Attacker provides input larger than the buffer
- Input overwrites past the buffer, through saved registers, reaching the return address
- Attacker places the address of their malicious code (shellcode) in that position
- Function returns → CPU jumps to attacker's address → shellcode executes
Why it works: The CPU blindly trusts the return address on the stack. It has no way to verify the address is legitimate. If an attacker controls that value, they control execution.
Go deeper:
Stack buffer overflow (Wikipedia) — the diagrams showing buffer → saved frame pointer → return address.
CWE-787: Out-of-bounds Write (MITRE) — the canonical weakness ID for the underlying memory-corruption bug.