Safeguard
Vulnerability Analysis

Integer overflow vulnerabilities explained

What integer overflow vulnerabilities are, how CWE-190 causes real breaches like Bitcoin's 2010 overflow bug, and how to detect and prevent them.

Hritik Sharma
Security Engineer
6 min read

On June 4, 1996, the European Space Agency's Ariane 5 rocket self-destructed 37 seconds after launch, taking a $370 million payload with it. The cause traced back to a single line of Ada code that converted a 64-bit floating-point velocity value into a 16-bit signed integer — a value too large for the target type, which overflowed and triggered a diagnostic exception the flight software misread as a fatal error. That's an integer overflow vulnerability: an arithmetic operation produces a result too large (or too small) for the variable type storing it, and the value silently wraps around to something the program never expected — zero, negative, or some unrelated number. In software, the same bug class shows up in memory allocation sizes, loop counters, buffer length checks, and financial calculations, and it has caused everything from crashed rockets to a Bitcoin bug that minted 184 billion coins in one transaction. Tracked as CWE-190, it remains one of the most persistent weaknesses in compiled and interpreted code alike.

What is an integer overflow vulnerability?

An integer overflow vulnerability is a defect where an arithmetic result exceeds the range a variable's data type can represent, causing the value to wrap around rather than raise an error. A 32-bit unsigned integer can hold values from 0 to 4,294,967,295; add 1 to the maximum and the result silently becomes 0, not 4,294,967,296. A signed 32-bit integer ranges from -2,147,483,648 to 2,147,483,647; add 1 to the max and it flips to -2,147,483,648. Languages like C and C++ perform this wraparound without complaint by default, which is why CWE-190 (Integer Overflow or Wraparound) has appeared in MITRE's CWE Top 25 Most Dangerous Software Weaknesses in every edition published since 2019, typically landing in the #14–#19 range. The danger isn't the wraparound arithmetic itself — it's what downstream code does with that unexpected value, especially when it flows into a memory allocation size, an array index, or a security check.

How does an integer overflow actually happen in a real codebase?

It happens when a calculation that looks safe on paper meets an attacker-controlled input at runtime. A textbook pattern: a function receives a user-supplied size parameter, computes total = size + header_length, and passes total to malloc(). If size is close to SIZE_MAX (18,446,744,073,709,551,615 on a 64-bit system), adding even a small header length wraps total around to a tiny number. The allocation then succeeds with far less memory than the code assumes it has, and a subsequent write into that buffer overflows the heap. This exact pattern — integer overflow feeding an undersized allocation — is how CVE-2002-0392 turned Apache's chunked-transfer-encoding handler into a remotely exploitable denial-of-service bug affecting Apache HTTP Server versions before 1.3.26 and 2.0.37, and it's the same mechanical shape behind dozens of image- and video-parser CVEs two decades later.

What's the difference between an integer overflow and a buffer overflow?

An integer overflow is a corrupted value; a buffer overflow is corrupted memory, and the first frequently causes the second. Integer overflow (CWE-190) happens purely in arithmetic — a number wraps around due to exceeding its type's bounds — and by itself just produces a wrong number sitting in a variable. Buffer overflow (CWE-120/CWE-787) happens when a program writes data past the boundary of an allocated buffer. The two are distinct weaknesses in the CWE taxonomy, but in memory-unsafe languages like C and C++ they're frequently chained: an overflowed length or size calculation causes an undersized buffer allocation or a bypassed bounds check, and the subsequent write overflows that buffer. Stagefright (CVE-2015-1538), disclosed in July 2015, followed exactly this chain — an integer overflow while parsing MP4 metadata in Android's libstagefright library led to a heap buffer overflow reachable via a single MMS message, putting an estimated 950 million Android devices at risk without any user interaction required.

Which real-world incidents were caused by integer overflow bugs?

At least four well-documented, high-impact incidents trace directly to integer overflow: Ariane 5 Flight 501 (1996), the Bitcoin value overflow incident (2010), Stagefright (2015), and the Boeing 787 generator control unit bug (2015). On August 15, 2010, an attacker exploited a missing overflow check in Bitcoin's transaction-verification code (later tracked as CVE-2010-5139) to create a transaction with two outputs of roughly 92.2 billion BTC each — the sum overflowed a 64-bit signed integer and wrapped to a tiny positive value, letting the transaction pass validation and instantly inflating the visible supply by 184.467 billion BTC. The Bitcoin network hard-forked within about five hours to invalidate the block and patch the check. Separately, in April 2015 the FAA issued an airworthiness directive after Boeing disclosed that the 787 Dreamliner's generator control units would enter a failed state and drop all AC electrical power if left continuously powered for 248 days, the result of an internal counter overflowing; airlines were instructed to power-cycle the units before hitting that threshold until a software fix shipped. None of these were exotic attacks — each was ordinary arithmetic hitting a boundary nobody checked for.

How do you detect and prevent integer overflow vulnerabilities?

You prevent integer overflow by checking arithmetic bounds before an operation executes, and you detect it with compiler instrumentation, fuzzing, and static/dynamic analysis rather than manual code review alone. On the prevention side, modern compilers offer built-ins like GCC and Clang's __builtin_add_overflow() family, which perform the addition and return whether it overflowed, letting code reject the result before it reaches an allocator or index. Rust's standard library defaults to panicking on overflow in debug builds and offers explicit checked_add, wrapping_add, and saturating_add variants so overflow behavior is a deliberate choice, not an accident — a language-level design decision credited with eliminating an entire class of CVE-190 findings compared to equivalent C code. On the detection side, UndefinedBehaviorSanitizer's -fsanitize=integer flag and AFL/libFuzzer-driven fuzzing campaigns (Google's OSS-Fuzz has flagged thousands of integer-overflow bugs across open-source projects like FFmpeg and libjpeg-turbo since 2016) catch the wraparound at the point it occurs, before it can cascade into a buffer overflow or logic error three function calls downstream.

How Safeguard Helps

Safeguard's reachability analysis traces whether an integer-overflow-prone function — say, an unchecked size calculation in a vendored parsing library — is actually reachable from your application's entry points, so your team fixes the CWE-190 findings that matter instead of triaging every CVE in a dependency tree. Griffin AI reads the surrounding code path to judge exploitability in context (is the overflowing value attacker-controlled, and does it flow into an allocation or bounds check) rather than flagging every arithmetic operation on principle. Safeguard's SBOM generation and ingest give you a live inventory of which components carry known integer-overflow CVEs like CVE-2002-0392-class chunked-encoding bugs or Stagefright-style media parsers, across every repo, without manual spreadsheet tracking. When a fix is available, Safeguard opens an auto-fix PR with the patched dependency version pinned, so the wraparound gets closed before it ever reaches production.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.