PowerPC’s lack of divide by zero exception can lead to interesting bugs
Saturday, February 2nd, 2008The PowerPC architecture doesn’t have a divide by zero exception. When you divide by 0, it returns 0. When you do x % 0, it returns x.
This can lead to subtle errors, especially with the mod operation(%).
Example:
This program creates a buffer of user-specified length filled with ‘A’s, and overwrites one random character in the buffer with a ‘B’. If the user-specified length is 0, then it will write a ‘B’ to a random address, corrupting memory. This would be very unlikely to be exploitable, but it illustrates how memory corruption can occur when div by zero is not trapped, and you’re not expecting it. On Intel, the divide by zero would always result in a crash, with no possibility of anything worse.
$ cat test.c
int main(int argc, char **argv) {
char * buf;
//user-supplied size for buf
int untrusted_size = atoi(argv[1]);
buf = malloc(untrusted_size);
if (!buf) {
exit(-1);
}
srandomdev();
memset(buf, 'A', untrusted_size);
//get a random number from 0 to untrusted_size-1
//or if untrusted_size = 0, return a random number from 0 to RAND_MAX
int rnd_index = random() % untrusted_size;
printf("rnd_index = %d\n", rnd_index);
buf[rnd_index] = 'B';
printf("%s\n", buf);
return 0;
}
$ ./a.out 10
rnd_index = 8
AAAAAAAABA
$ ./a.out 0
rnd_index = 2098236498
Segmentation fault