You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 45 Next »

When two pointers are subtracted, both must point to elements of the same array object or to one past the last element of the array object (C11, Section 6.5.6 [ISO/IEC 9899:2011]); the result is the difference of the subscripts of the two array elements. Otherwise, the operation results in undefined behavior . (See undefined behavior 48  of Appendix J.) This restriction exists because pointer subtraction in C produces the number of objects between the two pointers, not the number of bytes.

Similarly, comparing pointers using the relational operators <, <=, >=, and > gives the positions of the pointers relative to each other. Subtracting or comparing pointers that do not refer to the same array results in undefined behavior. (See undefined behavior 48 and undefined behavior 53 of Appendix J.)

Comparing pointers using the equality operators == and != has well-defined semantics regardless of whether or not either of the pointers is null, points into the same object, or points one past the last element of an array object or function.

It is acceptable to subtract or compare two member pointers within a single struct object, suitably cast because any object can be treated as an array of unsigned char. However, when doing so remember to account for the effects of alignment and padding on the structure.

Noncompliant Code Example

In this noncompliant code example, pointer subtraction is used to determine how many free elements are left in the nums array.

int nums[SIZE];
char *strings[SIZE];
int *next_num_ptr = nums;
int free_bytes;

/* increment next_num_ptr as array fills */

free_bytes = strings - (char **)next_num_ptr;

The first incorrect assumption is that the nums and strings arrays are necessarily contiguous in memory. The second is that free_bytes is the number of bytes available. The subtraction returns the number of elements between next_num_ptr and strings.

Compliant Solution

In this compliant solution, the number of free elements is kept as a counter and adjusted on every array operation. It is also calculated in terms of free elements instead of bytes. This prevents further mathematical errors.

int nums[SIZE];
char *strings[SIZE];
int *next_num_ptr = nums;
int free_bytes;

/* increment next_num_ptr as array fills */

free_bytes = (&(nums[SIZE]) - next_num_ptr) * sizeof(int);

Risk Assessment

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

ARR36-C

medium

probable

medium

P8

L2

Automated Detection

Tool

Version

Checker

Description

LDRA tool suite

9.7.1

438 S

Fully implemented.

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Related Guidelines

CERT C++ Secure Coding Standard: ARR36-CPP. Do not subtract or compare two pointers or iterators that do not refer to the same array or container

ISO/IEC 9899:2011 Section 6.5.6, "Additive operators"

ISO/IEC TR 17961 (Draft) Subtracting or comparing two pointers that do not refer to the same array [ptrobj]

MITRE CWE: CWE-469, "Use of pointer subtraction to determine size"

Bibliography

[Banahan 2003] Section 5.3, "Pointers," and Section 5.7, "Expressions involving pointers"


  • No labels