...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdlib.h> struct S { size_t len; char buf[]; /* Flexible array member */ }; const char *find(const struct S *s, int c) { const char *first = s->buf; const char *last = s->buf + s->len; while (first != last) { /* Avoid incrementing here */ if (*++first == (unsigned char)c) { return first; } } return NULL; } void g(void) { struct S *s = (struct S *)malloc(sizeof(struct S)); if (s == NULL) { /* handle error */ } s->len = 0; find(s, 'a'); } |
...
Noncompliant Code Example (Improper Scaling)
In this noncompliant example, the integer skip
is scaled when added to the pointer s
and may point outside the bounds of the object referenced by s
:
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
struct big {
unsigned long long ull_1;
unsigned long long ull_2;
unsigned long long ull_3;
int si_4;
int si_5;
};
int g(void) {
size_t skip = offsetof(struct big, ull_2);
struct big *s = (struct big *)malloc(4 * sizeof(struct big));
if (s == NULL) {
return -1; /* Failure */
}
memset(s + skip, 0, sizeof(struct big) - skip);
return 0;
}
|
Compliant Solution
This compliant solution does not scale skip
:
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
struct big {
unsigned long long ull_1;
unsigned long long ull_2;
unsigned long long ull_3;
int si_4;
int si_5;
};
int g(void) {
size_t skip = offsetof(struct big, ull_2);
struct big *s = (struct big *)malloc(4 * sizeof(struct big));
if (s == NULL) {
return -1; /* Failure */
}
memset(((unsigned char *)s) + skip, 0,
sizeof(struct big) - skip);
return 0;
} |
Risk Assessment
Accessing out-of-range pointers or array subscripts for writing can result in a buffer overflow and the execution of arbitrary code with the permissions of the vulnerable process or unintended information disclosure.
...