Pointer arithmetic is only appropriate when the pointer argument refers to an array ARR37-C. Do not add or subtract an integer to a pointer to a non-array object. When performing pointer arithmetic, the size of the value to add or subtract to a pointer is automatically scaled to the size of the type of the referenced array object. Adding or subtracting a scaled integer value to a pointer is insecure because it may result in a pointer that does not point to an element within or one past the end of the array. This is contraindicated by ARR38-C. Do not add or subtract an integer to a pointer if the resulting value does not refer to a valid array element.
Violations of this guidelines are indicated when a pointer to an array is added to the result of the {{sizeof}} operator or {{offsetof}} macro which return a size and offset, respectively. However, adding an array pointer to the number of array elements, for example by using the {{arr\[sizeof(arr)/sizeof(arr\[0\])\])}} idiom, is allowed, provided that {{arr}} refers to an array and not a pointer. |
In this noncompliant code example, the pointer buf is added to sizeof(buf). This is noncompliant because sizeof(buf) is scaled by int and is scaled again when added to buf.
int buf[INTBUFSIZE];
int *buf_ptr = buf;
while (havedata && buf_ptr < (buf + sizeof(buf))) {
*buf_ptr++ = parseint(getdata);
}
|
In this noncompliant code example, skip is added to the pointer s. However, skip represents the byte offset of ull_2 in struct big. When added to s, skip is scaled by the size of struct big.
struct big {
unsigned long long ull_1; /* typically 8 bytes */
unsigned long long ull_2; /* typically 8 bytes */
unsigned long long ull_3; /* typically 8 bytes */
int si_4; /* typically 4 bytes */
int si_5; /* typically 4 bytes */
};
/* ... */
size_t skip = offsetof(struct big, ull_2);
struct big *s = (struct big *)malloc(sizeof(struct big));
if (!s) {
/* Handle malloc error */
}
memset(s + skip, 0, sizeof(struct big) - skip);
/* ... */
free(s);
s = NULL;
|
In this noncompliant code example, wcslen(error_msg) * sizeof(wchar_t) bytes are scaled by the size of wchar_t when added to error_msg.
/* ... */ wchar_t error_msg[WCHAR_BUF]; wcscpy(error_msg, L"Error: "); fgetws(error_msg + wcslen(error_msg) * sizeof(wchar_t), WCHAR_BUF - 7, stdin); /* ... */ |
\[[Dowd 06|AA. Bibliography#Dowd 06]\] Chapter 6, "C Language Issues" \[[ISO/IEC PDTR 24772|AA. Bibliography#ISO/IEC PDTR 24772]\] "HFC Pointer casting and pointer type changes" and "RVG Pointer Arithmetic" \[[MISRA 04|AA. Bibliography#MISRA 04]\] Rules 17.1-17.4 \[[MITRE 07|AA. Bibliography#MITRE 07]\] [CWE ID 468|http://cwe.mitre.org/data/definitions/468.html], "Incorrect Pointer Scaling" \[[Murenin 07|AA. Bibliography#Murenin 07]\] |