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.
Non-Compliant Code Example
This non-compliant code illustrates possible undefined behavior associated with demoting floating point represented numbers.
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 corresponding to a region in memory beyond the allocated buffer. This is due to buf being an int pointer and the result of sizeof(buf) getting multiplied by sizeof(int) accordingly. Thus, this code is vulnerable to buffer overflow.
Compliant Code Examples
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[BUF_LEN]; int *buf_ptr = buf; int i = 0; while (havedata() && i < BUF_LEN) { buf[i] = parseint(getdata()); i++; }
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.