Never hardcode datatype sizes into an application. Instead, use the sizeof
operator to retrieve the size of a datatype.
When writing portable code, it is important to realize that different architectures may represent the same datatype in different manners. For example, a generic pointer (type void*
) is 32 bits on x86 and 64 bits on x64.
Datatype alignment requirements can also affect the size of structs. Consider the following code.
typedef struct s { int i; double d; } mystruct; size_t size = sizeof(mystruct); printf("Size of struct: %d bytes\n", size);
When compiled for Andrew Linux (x86), the output of this program is:
Size of struct: 12 bytes
When compiled for Windows (x86), the output of this program is:
Size of struct: 16 bytes
Non-Compliant Coding Example
This non-compliant example demonstrates the incorrect way to declare a triangular array of integers.
/* assuming 32-bit pointer, 32-bit integer */ int i; int** triarray = calloc(100, 4); for (i = 0; i < 100; i++) triarray[i] = calloc(i, 4);
Compliant Solution
The above example can be fixed by replacing the hard-coded value 4
with the actual size of the datatype as represented on the target platform. Remember to check the return value of the memory allocation routines.
int i; int** triarray = calloc(100, sizeof(int*)); if (!triarray) { /* perform cleanup, return error */ } for (i = 0; i < 100; i++) { triarray[i] = calloc(i, sizeof(int)); if (!triarray[i]) { /* perform cleanup, return error */ } }
Risk Assessment
If non-compliant code is ported to a different platform, it could introduce a heap or stack overflow vulnerability.
Rule |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
EXPxx-A |
3 (high) |
1 (unlikely) |
2 (medium) |
P6 |
L2 |
References
[[ISO/IEC 9899-1999]] Section 6.2.6, "Representations of types", and Section 6.5.3.4, "The sizeof operator"