...
The type size_t
generally covers the entire address space. The C Standard, Annex K (normative), "Bounds-checking interfaces" [ISO/IEC 9899:2011], ," introduces a new type, rsize_t
, defined to be size_t
but explicitly used to hold the size of a single object [Meyers 2004]. In code that documents this purpose by using the type rsize_t
, the size of an object can be checked to verify that it is no larger than RSIZE_MAX
, the maximum size of a normal single object, which provides additional input validation for library functions. See STR07-C. Use the bounds-checking interfaces for remediation of existing string manipulation code for additional discussion of C11 Annex K.
...
Signed integer overflow causes undefined behavior. The following are two possible conditions under which this code constitutes a serious vulnerability:
sizeof(size_t) == sizeof(int)
...
In this noncompliant code example, the value of length
is read from a network connection and passed as an argument to a wrapper to malloc()
to allocate the appropriate data block. Provided that the size of an unsigned long
is equal to the size of an unsigned int
, and both sizes are equal to or smaller than the size of size_t
, this code runs as expected. However, if the size of an unsigned long
is greater than the size of an unsigned int
, the value stored in length
may be truncated when passed as an argument to alloc()
. Both read functions return zero on success and nonzero on failure.
Code Block | ||||
---|---|---|---|---|
| ||||
void *alloc(unsigned int blocksize) { return malloc(blocksize); } int read_counted_string(int fd) { unsigned long length; unsigned char *data; if (read_integer_from_network(fd, &length) < 0) { return -1; } data = (unsigned char*)alloc(length+1); if (data == NULL) { return -1; /* Indicate failure */ } if (read_network_data(fd, data, length) < 0) { free(data); return -1; } data[length-1] = '\0'; /* ... */ free( data); return 0; } |
...
Code Block | ||||
---|---|---|---|---|
| ||||
void *alloc(rsize_t blocksize) { if (blocksize == 0 || blocksize > RSIZE_MAX) { return NULL; /* Indicate failure */ } return malloc(blocksize); } int read_counted_string(int fd) { rsize_t length; unsigned char *data; if (read_integer_from_network(fd, &length) < 0) { return -1; } data = (unsigned char*)alloc(length+1); if (data == NULL) { return -1; /* Indicate failure */ } if (read_network_data(fd, data, length) < 0) { free(data); return -1; } data[length-1] = '\0'; /* ... */ free( data); return 0; } |
...
The improper calculation or manipulation of an object's size can result in exploitable vulnerabilities.
Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
INT01-C |
Medium |
Probable |
Medium | P8 | L2 |
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Axivion Bauhaus Suite |
| CertC-INT01 | |||||||
CodeSonar |
| LANG.TYPE.BASIC | Basic numerical type used | ||||||
Compass/ROSE |
Can detect violations of this recommendation. In particular, it catches comparisons and operations where one operand is of type |
5.0
size_t
is not |
93 S
Fully implemented
Splint |
|
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
SEI CERT C++ |
Coding Standard | VOID INT01-CPP. Use rsize_t or size_t for all integer values representing the size of an object |
Bibliography
...
...
...