integer-overflow · git:20260920.c098895 · 2026-09-20 · sha256 75b571544c4187ff
integer-overflow git:20260920.c098895A
Immutable. This exact content never changes and is served at /api/v1/blob/75b571544c4187ff.
--- name: integer-overflow description: Classify integer overflow evidence — ARITH_OVERFLOW events from size calculations feeding malloc/memcpy. Maps to CWE-190. license: MIT compatibility: opencode,claude code,DSH metadata: cwe: CWE-190 severity: HIGH domain: semantic --- ## Integer Overflow Analysis (CWE-190) ### Evidence Pattern An integer-overflow candidate has: - **ARITH_OVERFLOW event**: An arithmetic operation (a + b, a * b) on size-typed values - **Sink context**: The result flows into `malloc`, `calloc`, `realloc`, `memcpy`, `memset` - **No overflow check**: No guard checking `a > SIZE_MAX - b` before the operation The `category` field encodes the confidence tier the pipeline already computed: | Category | Pattern | Static verdict | |----------|---------|----------------| | `size_calc_overflow` | `malloc(n * m)` / `malloc(n * sizeof(T))` / `calloc(n, m)` | suspected | | `size_mul_const_overflow` | `malloc(n * K)`, n is a function parameter and `K >= 256` | suspected | | `integer_overflow` | wraparound inside a bounds check | possible | ### Dangerous Patterns | Pattern | Risk | Why | |---------|------|-----| | `malloc(count * elem_size)` | Overflow → small alloc | `count * elem_size` wraps to small value | | `calloc(count, size)` | Overflow → small alloc | implicit `count * size` wraps | | `char buf[n * m]` | Overflow → small stack array | VLA with wrapped size | ### Safe Patterns (P0 Exclusion) | Safe Pattern | Why Safe | |---------------|----------| | `malloc(sizeof(dst))` | Constant size, no arithmetic | | `malloc(count * sizeof(type))` with checked `count` | Count validated before multiply | | `if (a > SIZE_MAX - b) return NULL; total = a + b;` | Explicit overflow check | | `__builtin_add_overflow(a, b, &result)` | Compiler-checked overflow | ### Classification Rules | Condition | Classification | |-----------|---------------| | Arithmetic on sizes + flows to malloc + no overflow check | **confirmed** | | Arithmetic on sizes + flows to malloc + checked bounds | **false-positive** | | `count * elem_size` with user-controlled `count`, no check | **confirmed** | | Constant expression (no variables) | **false-positive** | | A size variable assigned a single small constant (`size_t n = 10; malloc(n * n)`) — the convergence range flow proves it bounded and suppresses it | **false-positive** | | Arithmetic on `int` (signed) feeding malloc | **dismissed** (sign issues) | | `size_mul_const_overflow` where the parameter is raw user input and `K >= 256` | **confirmed** | | `size_mul_const_overflow` where the parameter is provably bounded to `< SIZE_MAX / K` by a guard | **false-positive** | Note: `malloc(n + 1)` / `malloc(n - 1)` (null-terminator / off-by-one idioms) and `malloc(n * K)` with a small `K < 256` (doubling, small magic numbers) are NOT emitted — their overflow requires an operand within one bit of the type maximum, which is implausible, so the detector no longer surfaces them. ### Fix Suggestions - Use `size_t` for all size calculations (never `int`) - Check before multiply: `if (count > SIZE_MAX / elem_size) return NULL;` - Check before add: `if (a > SIZE_MAX - b) return NULL;` - Use compiler builtins: `__builtin_mul_overflow(count, elem_size, &total)` - Use checked-allocation wrappers that validate internally - Clamp `count` to a reasonable maximum before arithmetic ### Severity Matrix `status` and `severity` are independent: `status` = evidence verdict (confirmed/dismissed), `severity` = impact (low/medium/high/critical). `metadata.severity` is the type default, not a ceiling. The verdict is binary (confirmed/dismissed); dismissed → `low`. | Shape | Severity | |-------|----------| | Overflow feeds an allocation/copy size with an attacker-controlled operand → undersized alloc → later heap overflow | CRITICAL | | Overflow feeds malloc/memcpy size, bounded operand, no check | HIGH | | `possible` tier (unsigned wraparound inside a bounds check, not proven reachable) | MEDIUM (possible) | | Signed `int` arithmetic feeding malloc (sign-conversion risk) | MEDIUM (dismissed) |