When performing pointer arithmetic, the size of the computation is automatically scaled to the size of the pointer type. For instance, a pointer to a four-byte integer will be scaled by four bytes at a time.
Improper use of pointer arithmetic can lead to miscalculations that result in subtle and hard to spot coding errors.
Non-Compliant Code Example
In this example, taken from dowd, buf_ptr
is used to insert new integers into buf
, which is an array of 1024 integers. If there is data to be inserted into buf
(which is indicated by havedata()
) and buf_ptr
has not been incremented past buf + sizeof(buf)
, then an integer is inserted into buf
via buf_ptr
. However, the sizeof
operator returns the total number of bytes in buf
, which, assuming four-byte integers, is 4096 bytes. This value is then scaled to the size of an integer and added to buf
. As a result, it is possible to write integers past the end of buf
and cause a buffer overflow.
int buf[1024]; int *buf_ptr = buf; while (havedata() && buf_ptr < buf + sizeof(buf)) { *buf_ptr++ = parseint(getdata()); }
Compliant Code Example
1)
int buf[BUF_LEN]; int *buf_ptr = buf; while (havedata() && buf_ptr < buf[BUF_LEN-1]) { *buf_ptr = parseint(getdata()); buf_ptr++; }
2)
int buf[1024]; int *b = buf; while (havedata() && b < buf+sizeof(buf)) { *b++ = parseint(getdata()); }
These corrected versions:
- eliminate the coding error of the original code
- maintain clarity of intended result while reading code
Risk Analysis
Failure to notice a coding error of this variety would easily become a buffer overflow vulnerability. In a worst case scenario this could lead to arbitrary code execution and thus hold severe risk.