...
Code Block |
---|
|
enum { TABLESIZE = 100 };
static int table[TABLESIZE];
int * f(size_t index) {
if (index < TABLESIZE) {
return table + index;
}
return NULL;
}
|
Anchor |
---|
| #Dereferencing Past the End Pointer |
---|
| #Dereferencing Past the End Pointer |
---|
|
...
Code Block |
---|
|
#include <stdlib.h>
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 (tmp == NULL) {
return -1; /* indicateFailure failure */
}
table = tmp;
}
table[pos] = value;
return 0;
}
|
...
Code Block |
---|
|
#include <realloc.h>
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 (tmp == NULL) {
return -1; /* indicateFailure failure */
}
/* Modify size only after realloc succeeds. */
size = pos + 1;
table = tmp;
}
table[pos] = value;
return 0;
}
|
...
Code Block |
---|
|
static const size_t COLS = 5;
static const size_t ROWS = 7;
static int matrix[ROWS][COLS];
void init_matrix(int x) {
for (size_t i = 0; i != COLS; ++i) {
for (size_t j = 0; j != ROWS; ++j)
{
matrix[i][j] = x;
}
}
}
|
Compliant Solution
The following compliant solution avoids using out-of-range indices by initializing matrix
elements in the same row-major order as multidimensional objects are declared in C:
Code Block |
---|
|
static const size_t COLS = 5;
static const size_t ROWS = 7;
static int matrix[ROWS][COLS];
void init_matrix(int x) {
for (size_t i = 0; i != ROWS; ++i) {
for (size_t j = 0; j != COLS; ++j) {
matrix[i][j] = x;
}
}
}
|
Anchor |
---|
| Pointer Past Flexible Array Member |
---|
| Pointer Past Flexible Array Member |
---|
|
...
Code Block |
---|
|
#include <stddef.h>
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;
}
int g() {}
struct S *s = (struct S*)malloc(sizeof (struct S));
if (s == NULL)return NULL;
} |
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 {
return -1; /* indicate failure */
}
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;
}
int g() {
struct S *s = (struct S*)malloc(sizeof (struct S));
if (s == NULL) {
return -1; /* indicate failure */
}
s->len = 0;
/* ... */
char *where = find(s, '.');
/* ... */
return 0size_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;
}
|
Anchor |
---|
| Invalid Access by Library Function |
---|
| Invalid Access by Library Function |
---|
|
...
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
The following compliant solution correctly computes the maximum number of items for fread()
to read from the file:
Code Block |
---|
bgColor | #ccccff |
---|
lang | c |
---|
| #ccccff |
---|
lang | c |
---|
|
#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);
/* ... */
}
|
Noncompliant Code Example
...
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; /* indicateFailure failure */
}
memset(s + skip, 0, sizeof(struct big) - skip); /* violation */
/* ... */struct big) - skip);
return 0;
}
|
Compliant Solution
...
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; /* indicate failureFailure */
}
memset(((unsigned char *)s) + skip, 0,
sizeof(struct big) - skip);
/* ... */
return 0;
} |
Risk Assessment
...