Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: REM Cost Reform

A data model defines the sizes assigned to standard data types. It is important to understand the data models used by your implementation. However, if your code depends on any assumptions not guaranteed by the standard, you should provide static assertions (see to ensure that your assumptions are valid. (See DCL03-AC. Use a static assertion to test the value of a constant expression) to ensure that your assumptions are valid. .) Assumptions concerning integer sizes may become invalid, for example, when porting from a 32-bit architecture to a 64-bit architecture.

Common Data Models

Data Type

iAPX68

iAPX86

IA-32

IA-64

SPARC-64

ARM-32

Alpha

64-bit Linux, FreeBSD,
NetBSD, and OpenBSD

char

8

8

8

8

8

8

8

short

16

16

16

16

16

16

16

int

16

32

32

32

32

32

32

long

32

32

32

64

32

64

64

long long

N/A

64

64

64

64

64

64

pointer

Pointer

16/32

32

64

64

32

64

64

Wiki MarkupCode frequently embeds assumptions about data models. For example, there are some code bases that require pointer and {{long}} to have the same size, while whereas other large code bases require {{int}} and {{long}} to be the same size \[ [van de Voort 07|AA. C References#van de Voort 07]\Voort 2007]. These types of assumptions, while common, make the code difficult to port and make the ports error - prone. One solution is to avoid any implementation-defined behavior. However, this practice can result in inefficient code. Another solution is to include either static or runtime assertions near any platform-specific assumptions , so they can be easily detected and corrected during porting.

<limits.h>

Possibly more important than knowing the number of bits for a given type is knowing that limits.h defines macros that can be used to determine the integral ranges of the standard integer types for any conforming implementation. For example, UINT_MAX is the largest possible value of an unsigned int, and LONG_MIN is the smallest possible value of a long int.

<stdint.h>

The stdint.h header introduces types with specific size restrictions that can be used to avoid dependence on a particular data model. For example, int_least32_t is the smallest signed integer type supported by the implementation that contains at least 32 bits. The type uint_fast16_t is the fastest unsigned integer type supported by the implementation that contains at least 16 bits. The type intmax_t is the largest signed integer, and uintmax_t is the largest unsigned type, supported by the implementation. The following types are required to be available on all implementations.:

Smallest Types

signed

Signed

unsigned

Unsigned

8 bits

int_least8_t

uint_least8_t

16 bits

int_least16_t

uint_least16_t

32 bits

int_least32_t

uint_least32_t

64 bits

int_least64_t

uint_least64_t

Fastest Types

signed

Signed

unsigned

Unsigned

8 bits

int_fast8_t

uint_fast8_t

16 bits

int_fast16_t

uint_fast16_t

32 bits

int_fast32_t

uint_fast32_t

64 bits

int_fast64_t

uint_fast64_t

Largest Types

signed

Signed

unsigned

Unsigned

maximum

Maximum

intmax_t

uintmax_t

Additional types may be supported by an implementation, such as int8_t, a type of exactly 8 bits, and uintptr_t, a type large enough to hold a converted void *, if such an integer exists in the implementation.

<inttypes.h>

The inttypes.h header declares functions for manipulating greatest-width integers and converting numeric character strings to greatest-width integers.

...

Noncompliant Code Example

This non-compliant noncompliant example attempts to read a long into an int. This code works for models where in which sizeof(int) == sizeof(long). For others, on others it causes an unexpected memory write similar to a buffer overflow.

Code Block
bgColor#FFcccc
langc
int f(void) {
  FILE *fp;
  int x;
/* ... */
  if (fscanf(fp, "%ld", &x) < 1) {
    return -1; /* handleIndicate errorfailure */
  }

/* ... */
  return 0;
}

Some compilers are able to can generate warnings if a constant format string does not match the argument types.

Compliant Solution

This compliant solution uses the correct format for the type being used.:

Code Block
bgColor#ccccff
langc
int f(void) {
  FILE *fp;
  int x;
/* Initialize ...fp */
  if (fscanf(fp, "%d", &x) < 1) {
    return -1; /* handleIndicate errorfailure */
  }

...

/* ... */
  return 0;
}

Noncompliant Code Example

This non-compliant noncompliant code attempts to guarantee that all bits of a multiplication of two unsigned int values are retained by performing arithmetic in the type unsigned long. This practice works for some machinesplatforms, such as 64-bit Linux, but fails for others, such as 64-bit Microsoft Windows.

Code Block
bgColor#FFcccc
langc

unsigned int a, b;
unsigned long c;
/* ...Initialize a and b */
c = (unsigned long)a * b; /* notNot guaranteed to fit */

Compliant Solution

This compliant solution uses the largest unsigned integer type available , if it is guaranteed to hold the result.   If it is not, another solution must be found, as discussed in INT32-C. Ensure that operations on signed integers do not result in overflow.

Code Block
bgColor#ccccff
langc

#if UINT_MAX > UINTMAX_MAX/UINT_MAX
#error No safe type is available.
#endif
/* ... */
unsigned int a, b;
uintmax_t c;
/* ... Initialize a and b */
c = (uintmax_t)a * b; /* guaranteedGuaranteed to fit, verified above */

Risk Assessment

Understanding the data model used by your implementation is necessary to avoid making errors about the sizes of integer types and the range of values that they can represent. Making assumptions about the sizes of data types may lead to buffer-overflow-style attacks.

Recommendation

Severity

Likelihood

Remediation Cost

Detectable

Repairable

Priority

Level

INT00-

A

C

High

high

Unlikely

unlikely

No

high

No

P3

L3

Automated Detection

Tool

Version

Checker

Description

Axivion Bauhaus Suite

Include Page
Axivion Bauhaus Suite_V
Axivion Bauhaus Suite_V

CertC-INT00
PC-lint Plus

Include Page
PC-lint Plus_V
PC-lint Plus_V

559, 705, 706, 2403

Assistance provided: Reports data type inconsistencies in format strings

Polyspace Bug Finder

Include Page
Polyspace Bug Finder_V
Polyspace Bug Finder_V

CERT C: Rec. INT00-C


Checks for:

  • Use of basic numerical types instead of typedef-s
  • Integer overflow or integer constant overflow
  • Format string specifiers and arguments mismatch

Rec. partially covered.

PVS-Studio

Include Page
PVS-Studio_V
PVS-Studio_V

V629, V5004

Related Vulnerabilities

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

References

Wiki Markup
\[[van de Voort 07|AA. C References#van de Voort 07]\]
\[[Open Group 97|AA. C References#Open Group 97b]\]

Related Guidelines

Bibliography


...

Image Added Image Added Image Added04. Integers (INT)      04. Integers (INT)       INT01-A. Use rsize_t or size_t for all integer values representing the size of an object