“Buffett Overflow” Integer Overflow in Berkshire Hathaway Stock
When we write code, we make all kinds of assumptions about our systems. One that catches people off guard is CWE-190: Integer Overflow or Wraparound, which can have some strange consequences. As part of a design, people make assumptions on how big their numbers are. One funny example is a tweet that showed an incorrect false value for stock in Berkshire Hathaway, the company run by Warren Buffett. The pun “Buffett Overflow” was peak bad punning.
This weakness was classically shown in the Y2K bug when almost everyone represented and displayed the year in two digits. Most designers did not think that their systems would last 10 to 20 years. Eventually, extensive work began to make sure that the year 2000 (00) was not interpreted as less than the year 1999 (99). This not only affected sorting but made all kinds of financial transactions and interest calculations fail in unexpected ways. How much principal is left on a mortgage that is -85 years old (e.g., 1985 to 2000)? [Author’s note] When I was writing code in the early ’90s someone once said, “Why not five instead of four digits?” I said, “If this system survives past the year 9,998, they can dig me up, and I’ll fix it for free.”
To avoid potential errors associated with rounding mathematically real numbers, Yahoo! Finance records a stock’s price via a system where each hundredth of a cent is represented by an integer. This approach worked well until a single stock value was greater than $429,496.72 (e.g., ²³²-1 hundredths of a cent). Based on the error that resulted, it looks like they used an unsigned 32-bit integer for representing the stock price. An unsigned value was a good choice as stocks cannot have a negative value, and this doubles the maximum possible value. When representing a number greater than the maximum, however, the computer places a 1, or more bits, outside of the memory, so the number will be represented without those higher order bits (–$429,496.72 would read as 0).
Unfortunately, this choice can result in two problems. First, the logic of the program causes errors. If someone were using this data to trade or the data was the value on the trading floor, many automated systems would try and buy and sell the stock at a price of 0. This would cause all kinds of chaos in the financial world. Second, the program could be writing a 1 binary digit to some memory location elsewhere. This could cause a number of errors leading to a variety of negative outcomes including potentially crashing. As trivial or complicated as this might sound, there are attackers that will line up memory to make sure that that one-bit change allows them to exploit the vulnerability. This attack pattern is described in CAPEC-92: Forced Integer Overflow
So, what would you do about this? First, there are compiler and interpreter options in many languages that abort if you overflow an integer. If you can afford the performance hit, using this option or writing your own custom integer checks are good ways to ensure that you are aware when an overflow occurs so you can respond accordingly. Of course, the weakness is still there, just not a hidden one when the attack is executed. Smart developers avoid the weakness entirely by implementing checks before even performing a calculation that could overflow.
Second, if you can spare the memory, use a larger number size. The maximum of an unsigned 64-bit number is 18,446,744,073,709,551,615, and a maximum of an unsigned 128-bit integer is over 3.40 × 1038. I doubt that a single stock will ever be worth that much. If a stock starts to get close, like a trillion dollars, you can have time to rewrite the code. You won’t have forever as on January 18, 2038 the number of seconds recorded since 1970 is larger than the value that can be held by a signed 32-bit integer, a common implementation in many systems. This overflow will set the date to December 13, 1901 (a Friday) causing all kinds of problems (e.g. 32-bit Android phones may crash and not be able to boot).
[Author’s note] If you are writing some code and expect a stock to go to a trillion dollars or more, quickly, please drop us a line. I would like to buy 1–2 shares, at least before 2038.