...
In this compliant solution, the length operand is upcast to unsigned long long, ensuring that the addition takes place in this size.:
| Code Block | ||||
|---|---|---|---|---|
| ||||
enum { BLOCK_HEADER_SIZE = 16 };
void *AllocateBlock(size_t length) {
struct memBlock *mBlock;
if ((unsigned long long)length + BLOCK_HEADER_SIZE > SIZE_MAX) {
return NULL;
}
mBlock = (struct memBlock *)malloc(
length + BLOCK_HEADER_SIZE
);
if (!mBlock) return NULL;
/* fill in block header and return data portion */
return mBlock;
}
|
...
In this noncompliant code example, the programmer attempts to prevent wrapping by allocating an unsigned long long integer called alloc and assigning it the result from cBlocks * 16.:
| Code Block | ||||
|---|---|---|---|---|
| ||||
void *AllocBlocks(size_t cBlocks) {
if (cBlocks == 0) return NULL;
unsigned long long alloc = cBlocks * 16;
return (alloc < UINT_MAX) ? malloc(cBlocks * 16) : NULL;
}
|
...
In this compliant solution, the cBlocks operand is upcast to unsigned long long, ensuring that the multiplication takes place in this size.:
| Code Block | ||||
|---|---|---|---|---|
| ||||
static_assert(
CHAR_BIT * sizeof(unsigned long long) >=
CHAR_BIT * sizeof(size_t) + 4,
"Unable to detect wrapping after multiplication"
);
void *AllocBlocks(size_t cBlocks) {
if (cBlocks == 0) return NULL;
unsigned long long alloc = (unsigned long long)cBlocks * 16;
return (alloc < UINT_MAX) ? malloc(cBlocks * 16) : NULL;
}
|
...
Tool | Version | Checker | Description | ||||||
|---|---|---|---|---|---|---|---|---|---|
Compass/ROSE |
|
| Can detect violations of this rule. It should look for patterns of
| ||||||
| Coverity | 6.5 | OVERFLOW_BEFORE_WIDEN | Fully Implemented | ||||||
Fortify SCA | 5.0 |
| Can detect violations of this rule with CERT C Rule Pack. | ||||||
| PRQA QA-C |
| 1890 | Partially implemented. |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
...