...
Code Block | ||
---|---|---|
| ||
#include <stdint.h> #include <stdio.h> struct obj { char c; int i; }; void func(FILE *f, struct obj *objs, size_t num_objs) { if (num_objs > (SIZE_MAX / sizeof(*objs)) || num_objs != fwrite(objs, sizeof(*objs), num_objs, f)) { /* Handle error */ } } |
Noncompliant Code Example (One Pointer + Two Integers)
In this noncompliant code example, the function f()
calls fread()
to read nitems
of type wchar_t
, each size
bytes in size, into an array of BUFSIZ
elements, wbuf
. However, the expression used to compute the value of nitems
fails to account for the fact that, unlike the size of char
, the size of wchar_t
may be greater than 1. Consequently, fread()
could attempt to form pointers past the end of wbuf
and use them to assign values to nonexistent elements of the array. Such an attempt results in undefined behavior 109. . A likely consequence of this undefined behavior is a buffer overflow. For a discussion of this programming error in the Common Weakness Enumeration database, see CWE-121, "Access of memory location after end of buffer," and CWE-805, "Buffer access with incorrect length value."
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stddef.h>
#include <stdio.h>
void f(FILE *file) {
wchar_t wbuf[BUFSIZ];
const size_t size = sizeof(*wbuf);
const size_t nitems = sizeof(wbuf);
size_t nread;
nread = fread(wbuf, size, nitems, file);
}
|
Compliant Solution (One Pointer + Two Integers)
This compliant solution correctly computes the maximum number of items for fread()
to read from the file:
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stddef.h>
#include <stdio.h>
void f(FILE *file) {
wchar_t wbuf[BUFSIZ];
const size_t size = sizeof(*wbuf);
const size_t nitems = sizeof(wbuf) / size;
size_t nread;
nread = fread(wbuf, size, nitems, file);
} |
Risk Assessment
Depending on the library function called, an attacker may be able to use a heap or stack overflow vulnerability to run arbitrary code.
...
C Secure Coding Standard | API00-C. Functions should validate their parameters ARR01-C. Do not apply the sizeof operator to a pointer when taking the size of an array INT30-C. Ensure that unsigned integer operations do not wrap |
ISO/IEC TS 17961 | Forming invalid pointers by library functions [libptr] |
MITRE CWE
| CWE-121, Stack-based buffer overflow |
Bibliography
[ISO/IEC TS 17961] | Programming Languages, Their Environments and System Software Interfaces |
...