In 2005, I wrote that "Integers represent a growing and underestimated source of vulnerabilities in C and C++ programs" as the lead sentence in the "Integer Security" chapter of Secure Coding in C and C++. This prediction has been borne out in a recent study published by MITRE on the types of errors that lead to publicly reported vulnerabilities. "Integer overflows, barely in the top 10 overall in the past few years, are in the top 3 for OS vendor advisories".
An Integer Story
A vulnerability in bash versions 1.14.6 and earlier that resulted in the release of CERT Advisory CA-1996-22 provides an example of a programming error resulting from the incorrect use of integers.
The GNU Project's Bourne Again Shell (bash) is a drop-in replacement for the UNIX Bourne shell (/bin/sh). It has the same syntax as the standard shell but provides additional functionality such as job control, command-line editing, and history. Although bash can be compiled and installed on almost any UNIX platform, its most prevalent use is on Linux, where it has been installed as the default shell for most applications. The bash source code is freely available from many sites on the Internet.
There is a variable declaration error in the yy_string_get() function in the parse.y module of the bash source code:
static int yy_string_get() { register char *string; register int c; string = bash_input.location.string; c = EOF; /* If the string doesn't exist, or is empty, EOF found. */ if (string && *string) { c = *string++; bash_input.location.string = string; } return (c); }
This function is responsible for parsing the user-provided command line into separate tokens. The error involves the variable string, which has been declared to be of type char *.
The string variable is used to traverse the character string containing the command line to be parsed. As characters are retrieved from this pointer, they are stored in a variable of type int. For compilers in which the char type defaults to signed char, this value is sign-extended when assigned to the int variable. For character code 255 decimal (-1 in two's complement form), this sign extension results in the value -1 being assigned to the integer.
However, -1 is used in other parts of the parser to indicate the end of a command. Thus, the character code 255 decimal (377 octal) serves as an unintended command separator for commands given to bash via the -c option. For example:
bash -c 'ls\377who'
(where \377 represents the single character with value 255 decimal) will execute two commands, ls and who.
This example is interesting in that the vulnerability is entirely the result of an error in handling an integer value. More commonly, integer errors result in vulnerabilities by causing an exploitable buffer overflow.