Pointer arithmetic in C is a powerful feature when working with many data structures, however it can lead to subtle and hard to spot coding errors. This is due to the importance of context (the type of the pointer in question) which is likely declared outside the pointer arithmetic expression. In the case of bounds checking to determine if there is space in a region of memory, this can lead to buffer overflow vulnerabilities.
Background
Pointer arithmetic is based around the concept of scaling computation to the size of the pointer type. When working with arrays this allows for easily accessing elements.
Exploitable Code due to coding error
int buf[1024]; int *buf_ptr = buf; while (havedata() && buf_ptr < buf + sizeof(buf)) { *buf_ptr = parseint(getdata()); buf_ptr++; }
While at first look this code appears correct and that it will prevent overflowing the allocated buffer, in fact buf + sizeof(buf) returns a value 3 times further past the end of the buffer, thus allowing overflow.
Better version
int buf[1024]; int *buf_ptr = buf; while (havedata() && buf_ptr < (char *)buf + sizeof(buf)) { *buf_ptr = parseint(getdata()); buf_ptr++; }
In this version we explicitly cast buf as a char pointer this serves two goals:
- It eliminates the coding error of the original code
- The intended result of the expression remains clear