In computer science—and specifically in fuzzing and exploitation—the terms Overflow and Underflow mean different things depending on whether you are talking about Numbers (Arithmetic) or Memory (Buffers).
Here is the breakdown of the differences.
1. Arithmetic (Integer) Context
This refers to the value of a number going beyond what the variable type can hold.
Integer Overflow (Too Big)
Occurs when you try to store a value larger than the maximum limit. The value “wraps around” to the minimum.
- Analogy: A car odometer at
999,999rolling over to000,000. - Example (8-bit unsigned): The max value is 255.
255 + 1 = 0
- Security Risk: If you calculate
size = num_elements * 10and it overflows to a small number (e.g., 4), you might allocate only 4 bytes of memory but try to copy huge amounts of data into it, causing a heap overflow.
Integer Underflow (Too Small)
Occurs when you try to go below the minimum limit. The value “wraps around” to the maximum.
- Analogy: Rolling a car odometer backward from
000,000to999,999. - Example (8-bit unsigned): The min value is 0.
0 - 1 = 255
- Security Risk: If you have a check like
if (packet_len < header_len) return;, and you dopayload_size = packet_len - header_len, an underflow could makepayload_sizea massive number (like 4 billion), causing a massive copy loop.
2. Memory / Buffer Context
This refers to accessing memory outside the bounds of an array or buffer. This is the most common target for AFL/fuzzing.
Buffer Overflow (Going “Forward”)
Writing data past the end of the allocated buffer (towards higher memory addresses).
- Direction: Low Address $\to$ High Address.
- Code:
buf[10] = 'A'(when size is 10). - Impact on Stack: Since the Stack grows down (High to Low), but buffers index up (Low to High), a buffer overflow overwrites data “above” it in the stack frame.
- Main Thread: Overwrites the Return Address (saved LR).
- Secondary Thread: Writes towards the TCB (Thread Control Block) and
stack_guard.
Buffer Underflow (Going “Backward”)
Writing data before the start of the allocated buffer (towards lower memory addresses).
- Direction: High Address $\to$ Low Address.
- Code:
buf[-1] = 'A'. - Impact on Stack: This writes deeper into the stack (into unused space or the next function’s frame), which is usually less immediately dangerous than an overflow, but can still cause logic bugs.
3. The “Stack” Special Case
There are two specific terms related to the Stack structure itself (Push/Pop).
- Stack Overflow: The stack grows so large (usually due to infinite recursion) that it hits the limit of the OS-allocated memory region (the “Guard Page”). This causes a
SEGFAULT. - Stack Underflow: The program tries to
POPitems off the stack when the stack is empty. This usually only happens in handwritten assembly or ROP (Return Oriented Programming) chains, not in normal C code.
Summary Table
| Context | Term | What happens? | Direction / Result |
|---|---|---|---|
| Arithmetic | Overflow | Value > Max | Wraps to Min (0) |
| Arithmetic | Underflow | Value < Min | Wraps to Max (Huge number) |
| Memory | Overflow | Index > Size | Writes to Higher Address |
| Memory | Underflow | Index < 0 | Writes to Lower Address |
Relating to your previous question (The TCB)
In the context of the Secondary Thread layout I described previously:
- Buffer Overflow: If you have a buffer on the stack and you write past the end (
buf[1000]), you write towards Higher Addresses.- Because the TCB is located at the top (High Address) of the thread’s memory block, a massive Buffer Overflow on the stack allows you to corrupt the TCB,
stack_guard, or TLS pointers.
- Because the TCB is located at the top (High Address) of the thread’s memory block, a massive Buffer Overflow on the stack allows you to corrupt the TCB,
- Buffer Underflow: If you write to
buf[-1], you write towards Lower Addresses.- This moves away from the TCB and towards the Stack Guard Page at the bottom.