The following example can be found in many places on the internet:
The following code excerpt from OpenSSH 3.3 demonstrates a classic case of integer overflow: (bad code) Example Language: C
nresp = packet_get_int();
if (nresp > 0) {
response = xmalloc(nresp*sizeof(char*));
for (i = 0; i < nresp; i++) response[i] = packet_get_string(NULL);
}
If nresp has the value 1073741824 and sizeof(char*) has its typical value of 4, then the result of the operation
nresp*sizeof(char*)overflows, and the argument to xmalloc() will be 0. Most malloc() implementations will happily allocate a 0-byte buffer, causing the subsequent loop iterations to overflow the heap buffer response.
If nresp is an int and sizeof() returns a size_t, which in x86_64 is essentially unsigned long, the result should be unsigned long. Is the problem with the above that the argument for xmalloc is an int? Or does the example assume IA32? If not, what's the problem?
sizeof(char *)has its typical value of 4" — it's 8 on 64-bit systems. And on such systems,sizeof(size_t) == 8so there isn't arithmetic overflow with thenrespvalue you quote. A bigger problem is that the code doesn't check that the space was allocated successfully — that's an invitation for disaster. The code should be designed so that values that are to large are eliminated before they cause trouble. However, much code does not take such issues seriously.size_tcan never belong, as it must be unsigned.)size_tis neverlong; it is always an unsigned type. Often it is equivalent tounsigned long, which may be 32-bits or 64-bits, depending on the platform. Beware Windows 64 —longis still a 32-bit type, even though pointers are 64-bit types.