Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Never hardcode datatype sizes Do not hard code the size of a type into an application. Instead, use 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 versions of the same compiler. Using the sizeof operator to retrieve determine sizes improves 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.

clarity of what is meant and ensures that changes between compilers or versions will not affect the code.

Type Datatype alignment requirements can also affect the size of structs. Consider the following code.structures. For example, the size of the following structure is implementation-defined:

Code Block

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

Assuming 32-bit integers and 64-bit doubles, for example, the size can range from 12 to 16 bytes, depending on alignment rules.

Noncompliant Code Example

This noncompliant code example attempts to declare a 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 sectionThis non-compliant example demonstrates the incorrect way to declare a triangular array of integers.

Code Block
bgColor#FFcccc
langc
int f(void) { 
/* assumingAssuming 32-bit pointer, 32-bit integer */
int  size_t i;
  int **matrix triarray= =(int **)calloc(100, 4);
  if (matrix == NULL) {
    return -1; /* Indicate calloc() failure */
  }

  for (i = 0; i < 100; i++) {
    triarraymatrix[i] = (int *)calloc(i, 4);
    if (matrix[i] == NULL) {
      return -1; /* Indicate calloc() failure */
    }
  }
 return 0;
}

Compliant Solution

The above example can be fixed by replacing This compliant solution replaces 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. sizeof(int *):

Code Block
bgColor#ccccff
langc
int f(void) {
  size_t
int i;
  int **matrix triarray= =(int **)calloc(100, sizeof(int*matrix));
  if (!triarray)matrix == NULL) {
    {return -1; /* perform cleanup, return error */ }
Indicate calloc() failure */
  }

  for (i = 0; i < 100; i++) {
    triarraymatrix[i] = (int *)calloc(i, sizeof(int**matrix));
    if (!triarraymatrix[i] == NULL) {
      return -1; { /* perform cleanup, return error */Indicate calloc() failure */
    }
  }

  return 0;
}

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

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

Priority

Level

EXP09-C

High

Unlikely

No

Yes

P6

L2

Automated Detection

Tool

Version

Checker

Description

Astrée
Include Page
Astrée_V
Astrée_V
alloc-without-sizeof
Partially checked
Compass/ROSE



Can detect violations of this recommendation. In particular, it looks for the size argument of malloc(), calloc(), or realloc() and flags when it does not find a sizeof operator in the argument expression. It does not flag if the return value is assigned to a char *; in this case a string is being allocated, and sizeof is unnecessary because sizeof(char) == 1

ECLAIR
Include Page
ECLAIR_V
ECLAIR_V
CC2.EXP09Can 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

Include Page
Helix QAC_V
Helix QAC_V

C0701
LDRA tool suite
Include Page
LDRA_V
LDRA_V

201 S

Partially implemented

Polyspace Bug Finder

Include Page
Polyspace Bug Finder_V
Polyspace Bug Finder_V

CERT C: Rec. EXP09-CChecks for hard-coded object size used to manipulate memory (rec. fully covered)
RuleChecker

Include Page
RuleChecker_V
RuleChecker_V

alloc-without-sizeofPartially checked
Security Reviewer - Static Reviewer

Include Page
Security Reviewer - Static Reviewer_V
Security Reviewer - Static Reviewer_V

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


...

Image Added Image Added Image Added Wiki Markup\[[ISO/IEC 9899-1999|cplusplus:AA. C++ References#ISO/IEC 9899-1999]\] Section 6.2.6, "Representations of types," and Section 6.5.3.4, "The sizeof operator"