Integer overflow (CWE-190) occurs when arithmetic produces a value too large for its type, wrapping to a small number. When this happens in size calculations passed to malloc, the result is an undersized allocation and a heap overflow. This guide covers the vulnerable patterns, how to detect them, and safe alternatives.
Integer overflow happens when a calculation produces a result beyond the range of its integer type. For a 32-bit unsigned integer, adding 1 to 0xFFFFFFFF wraps to 0x00000000. For a signed integer, overflow is undefined behavior in C — the compiler may optimize it in unexpected ways.
In security contexts, integer overflow is most dangerous when the overflowed value is used as a memory allocation size. Multiplying a user-controlled count by an element size without checking for overflow can produce a tiny allocation, setting up a heap buffer overflow when that buffer is filled with the intended number of elements.
| Pattern | Risky | Safe | Why |
|---|---|---|---|
| count * size before malloc | malloc(count * element_size) | calloc(count, element_size) | calloc checks for size overflow internally |
| User-controlled size arithmetic | malloc(user_len + HEADER_SIZE) | Check user_len <= SIZE_MAX - HEADER_SIZE before malloc | Addition can overflow if user_len is near SIZE_MAX |
| Loop counter as allocation size | malloc(n * sizeof(struct foo)) | __builtin_mul_overflow check or reallocarray() | reallocarray checks for overflow in n * size |
| Signed/unsigned mismatch | int count = ...; malloc(count * 4) | size_t count = ...; malloc(count * 4) | Negative int cast to size_t becomes huge allocation size |
Vulnerable
// count is user-controlled // If count = 0x40000001, then count * 4 overflows to 4 // malloc(4) succeeds but buffer is way too small void *buf = malloc(count * sizeof(int)); if (!buf) return NULL; // Subsequent copy of count elements overflows heap memcpy(buf, src, count * sizeof(int));
Secure
// Option 1: calloc checks overflow internally void *buf = calloc(count, sizeof(int)); if (!buf) return NULL; // Option 2: explicit overflow check if (count > SIZE_MAX / sizeof(int)) return NULL; void *buf = malloc(count * sizeof(int)); if (!buf) return NULL;
Vulnerable
#define HEADER_SIZE 16 // user_len near SIZE_MAX causes overflow char *buf = malloc(user_len + HEADER_SIZE);
Secure
#define HEADER_SIZE 16 // Check before adding if (user_len > SIZE_MAX - HEADER_SIZE) return NULL; char *buf = malloc(user_len + HEADER_SIZE);
-fsanitize=integer detects signed/unsigned overflow at runtime# Semgrep: flag malloc(a * b) where a or b may be user-controlled
rules:
- id: malloc-integer-overflow
pattern: malloc($A * $B)
message: >
Unchecked multiplication before malloc may overflow (CWE-190).
Use calloc($A, $B) or check for overflow before malloc.
severity: WARNING
languages: [c, cpp]Orbis AppSec identifies unchecked size arithmetic before allocation calls and opens automated fix pull requests replacing the pattern with calloc or adding explicit overflow guards.
Want Orbis AppSec to find and fix integer overflow issues in your GitHub repositories?
Try Orbis AppSecBrowse posts where Orbis AppSec detected and fixed integer overflow vulnerabilities in real open-source repositories:
View all memory safety case studiesInteger overflow occurs when an arithmetic operation produces a result that exceeds the maximum value for the integer type. The result wraps around, typically to a very small number.
CWE-190: Integer Overflow or Wraparound.
When an overflowed size is passed to malloc, the allocator receives a much smaller size than intended and allocates a too-small buffer. Subsequent writes to this buffer overflow the heap allocation, corrupting adjacent memory.
Use calloc(count, element_size) instead of malloc(count * size) — calloc checks for overflow internally. For addition, verify the operands don't exceed SIZE_MAX before adding. Use __builtin_mul_overflow or reallocarray for explicit overflow-safe multiplication.
Partially. Compiler flags like -ftrapv trap signed overflow at runtime. UndefinedBehaviorSanitizer (UBSan) detects integer overflow during testing. Static analyzers can flag unchecked size arithmetic before allocation calls.
Signed integer overflow is undefined behavior in C. Unsigned integer overflow is well-defined (wraps modulo 2^n) but can still lead to security bugs when the wrapped value is used as an allocation size.