...
Code Block |
---|
|
static int *table = NULL;
static size_t size = 0;
int insert_in_table(size_t pos, int value) {
if (size < pos) {
int *tmp;
size = pos + 1;
tmp = (int*)realloc(table, sizeof *table * size);
if (NULLtmp == tmpNULL) {
return -1; /* indicate failure */
}
table = tmp;
}
table[pos] = value;
return 0;
}
|
...
Code Block |
---|
|
static int *table = NULL;
static size_t size = 0;
int insert_in_table(size_t pos, int value) {
if (size <= pos) {
int *tmp = (int*)realloc(table, sizeof *table * (pos + 1));
if (NULLtmp == tmpNULL) {
return -1; /* indicate failure */
}
/* Modify size only after realloc succeeds */
size = pos + 1;
table = tmp;
}
table[pos] = value;
return 0;
}
|
...
Code Block |
---|
|
struct S {
size_t len;
char buf[]; /* flexible array member */
};
char * find(const struct S *s, int c) {
char *first = s->buf;
char *last = s->buf + s->len;
while (first++ != last) /* undefined behavior here */
if (*first == (unsigned char)c)
return first;
return NULL;
}
voidint g() {
struct S *s = (struct S*)malloc(sizeof (struct S));
if (s->len == 0;
NULL) {
return -1; /* indicate ...error */
char}
*where s->len = 0;
/* ... */
char *where = find(s, '.');
/* ... */
return 0;
}
|
Compliant Solution
The following compliant solution avoids incrementing the pointer unless a value past the pointer's current value is known to exist:
Code Block |
---|
|
struct S {
size_t len;
char buf[]; /* flexible array member */
};
char * find(const struct S *s, int c) {
char *first = s->buf;
char *last = s->buf + s->len;
while (first != last) /* avoid incrementing here */
if (*++first == (unsigned char)c)
return first;
return NULL;
}
voidint g() {
struct S *s = (struct S*)malloc(sizeof (struct S)););
if (s == NULL) {
return -1; /* indicate error */
}
s->len = 0;
/* ... */
char *where = find(s, '.');
/* ... */
return 0;
}
|
Anchor |
---|
| Invalid Access by Library Function |
---|
| Invalid Access by Library Function |
---|
|
...
Code Block |
---|
|
struct big {
unsigned long long ull_1;
unsigned long long ull_2;
unsigned long long ull_3;
int si_4;
int si_5;
};
voidint 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; /* indicate ...failure */
}
memset(s + skip, 0, sizeof(struct big) - skip); /* violation */
/* ... */
return 0;
}
|
Compliant Solution
The following compliant solution does not scale skip
:
Code Block |
---|
|
struct big {
unsigned long long ull_1;
unsigned long long ull_2;
unsigned long long ull_3;
int si_4;
int si_5;
};
voidint 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; /* ...indicate failure */
}
memset(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.
...