Do not hard - code the size of a type into an application. Because of alignment, padding, and differences in basic types (e.g., 32-bit versus 64-bit pointers), the size of most types can vary between compilers and even version versions of the same compiler. Using the sizeof operator to determine sizes improves the clarity of what is meant and ensures that changes between compilers or version versions will not affect the code.
Type alignment requirements can also affect the size of structs. Consider structures. For example, the size of the following structure is implementation-defined:
| Code Block |
|---|
struct s { int i; double d; }; |
Depending on the compiler and platform, this structure could be any of a variety of sizes. Assuming 32-bit integers and 64-bit doubles, for example, the size might be 12 or can range from 12 to 16 bytes, depending on alignment rules.
...
Noncompliant Code Example
This non-compliant example demonstrates the incorrect way noncompliant code example attempts to declare a triangular two-dimensional array of integers with variable length rows. On a platform with 64-bit integers, the loop will access memory outside the allocated memory section.
| Code Block | ||||
|---|---|---|---|---|
| ||||
int f(void) { /* assumingAssuming 32-bit pointer, 32-bit integer */ size_t i; int **matrix triarray= =(int **)calloc(100, 4); if (triarraymatrix == NULL) { return -1; /* Indicate handlecalloc() errorfailure */ } for (i = 0; i < 100; i++) { triarray matrix[i] = (int *)calloc(i, 4); if (triarraymatrix[i] == NULL) { return -1; /* Indicate handlecalloc() errorfailure */ } } return 0; } |
Compliant Solution
The above example can be fixed by replacing This compliant solution replaces the hard-coded value 4 with the size of the type using sizeof. sizeof(int *):
| Code Block | ||||
|---|---|---|---|---|
| ||||
int f(void) { size_t i; int **triarraymatrix = (int **)calloc(100, sizeof(int *matrix)); if (!triarraymatrix == NULL) { return -1; /* Indicate handlecalloc() errorfailure */ } for (i = 0; i < 100; i++) { triarraymatrix[i] = (int *)calloc(i, sizeof(int**matrix)); if (!triarraymatrix[i] == NULL) { return -1; /* Indicate handlecalloc() errorfailure */ } } return 0; } |
Risk Assessment
If non-compliant code is ported to a different platform, it could introduce a buffer or stack overflow vulnerability.
Also see MEM02-C. Immediately cast the result of a memory allocation function call into a pointer to the allocated type for a discussion on the use of the sizeof operator with memory allocation functions.
Exceptions
EXP09-C-EX1: The C Standard explicitly declares sizeof(char) == 1, so any sizes based on characters or character arrays may be evaluated without using sizeof. This does not apply to char* or any other data types.
Risk Assessment
Porting code with hard-coded sizes can result in a buffer overflow or related vulnerability.
Recommendation | Severity | Likelihood | Detectable | Repairable |
|---|
Rule
Severity
Likelihood
Priority | Level |
|---|
EXP09- |
3 (high)
1 (unlikely)
C | High | Unlikely | No | Yes | P6 | L2 |
References
Automated Detection
Tool | Version | Checker | Description | ||||||
|---|---|---|---|---|---|---|---|---|---|
| Astrée |
| alloc-without-sizeof | Partially checked | ||||||
| Compass/ROSE | Can detect violations of this recommendation. In particular, it looks for the size argument of | ||||||||
| ECLAIR |
| CC2.EXP09 | Can detect violations of this recommendation. In particular, it considers when the size of a type is used by malloc(), calloc() or realloc() and flags these functions if either the size argument does not use a sizeof operator, or the size argument uses sizeof, but the type of the returned value is not a pointer to the type of the argument to sizeof. It does not flag if the returned value is assigned to a char * | ||||||
| Helix QAC |
| C0701 | |||||||
| LDRA tool suite |
| 201 S | Partially implemented | ||||||
| CERT C: Rec. EXP09-C | Checks for hard-coded object size used to manipulate memory (rec. fully covered) | |||||||
| RuleChecker |
| alloc-without-sizeof | Partially checked | ||||||
| Security Reviewer - Static Reviewer |
| C38 C39 C40 C42 C44 C45 C46 C46 | Fully implemented |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
| SEI CERT C++ Coding Standard | VOID EXP09-CPP. Use sizeof to determine the size of a type or variable |
| MITRE CWE | CWE-805, Buffer access with incorrect length value |
...
\[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]\] Section 6.2.6, "Representations of types," and Section 6.5.3.4, "The sizeof operator"Wiki Markup