CVE-2010-0405: bzip2 Integer Overflow

As we can read at Ubuntu’s USN-986-1 security advisory, the popular libbz2 open source bzip2 implementation is vulnerable in to an integer overflow vulnerability. So, first of all from the CHANGES file of the 1.0.6 version we can read that this vulnerability was reported by Mikolaj Izdebski and we can also notice the buggy code which resides in decompress.c source code file. Specifically, here is the code snippet that demonstrates the bug:

First of all, you can see that both variables ‘es’ and ‘N’ are 32-bit long signed integers. Now, the ‘DState’ pointer ‘s’ points to the save area in the main decompress code as we can read in its definition at bzlib_private.h header file. Next, moving to the code we can read that if the next symbol is the End-of-Block (aka. EOB), it will break of the loop; otherwise, it will check if the next ones value is set to ‘RUNA’ or ‘RUNB’ (these two constants are special values used by the run-length encoding to represent the run-length as a binary number greater than one). If this is the case, it will start calculating the ‘es’ and ‘N’ values and execute the MTF (Move to Front) transform to the symbol.
As Mikolaj Izdebski noticed, the ‘N’ value can result in overflowing the ‘es’ signed integer during the multiplication and thus leading to an integer overflow. To fix this, the following code was used:

As you can see in the initial code snippet, the possibly negative ‘es’ value is used to update the ‘s->unzftab[uc]’ value which would lead to initializing a ‘s->cftab[]’ value with an incorrect negative integer in the first ‘for’ loop of the above code. To avoid this, another check was added here too like this:

The newly added ‘for’ loop checks that the 255 values of the ‘s->unzftab[]’ array aren’t either negative or greater than the block size (stored in ‘nblock’ variable). At last, another check was placed before the code that makes a copy of the ‘cftab’ as you can read above to avoid any read out-of-bounds situation.