...
UB | Description | Example Code |
---|---|---|
Addition or subtraction of a pointer into, or just beyond, an array object and an integer type produces a result that does not point into, or just beyond, the same array object. | ARR30-C. Do not form or use out of bounds pointers or array subscripts, | |
Addition or subtraction of a pointer into, or just beyond, an array object and an integer type produces a result that points just beyond the array object and is used as the operand of a unary | Dereferencing Past the End Pointer, ARR30-C. Do not form or use out of bounds pointers or array subscripts | |
An array subscript is out of range, even if an object is apparently accessible with the given subscript (as in the lvalue expression | ARR30-C. Do not form or use out of bounds pointers or array subscripts | |
An attempt is made to access, or generate a pointer to just past, a flexible array member of a structure when the referenced object provides no elements for that array. | ARR30-C. Do not form or use out of bounds pointers or array subscripts |
...
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'); } |
Anchor | ||||
---|---|---|---|---|
|
Noncompliant Code Example (Null Pointer Arithmetic)
This noncompliant code example is similar to an Adobe Flash Player vulnerability that was first exploited in 2008. This code allocates a block of memory, and initializes it with some data. The data does not belong at the beginning of the block, which is left uninitialized. Instead, it is placed offset
bytes within the block. The function ensures that the data fits within the allocated block.
Code Block | ||||
---|---|---|---|---|
| ||||
#include <string.h> #include <stdlib.h> char *init_block(size_t block_size, size_t offset, char *data, size_t data_size) { char *buffer = malloc(block_size); if (data_size > block_size || block_size - data_size > offset) { /* Data won't fit in buffer, handle error */ } memcpy(buffer + offset, data, data_size); return buffer; } |
This function fails to check if the allocation succeeds; a violation of ERR33-C. Detect and handle standard library errors. If the allocation fails, then malloc()
returns a null pointer. The call to memcpy()
does not dereference this pointer, but instead adds this pointer null pointer is added to offset
and attempts to write through the resulting pointerpassed as the destination argument to memcpy()
. Because a null pointer does not point to a valid object, the results are undefinedthe result of the pointer arithmetic is undefined behavior 46.
An attacker that can supply the arguments to this function can exploit it to write to execute arbitrary code. This can be accomplished by providing a sufficiently large value for block_size
to cause malloc()
to fail and return a null pointer. The offset
argument will then serve as the destination address to the call to memcpy()
. The data
and data_size
arguments can provide the address and length of the address respectively that the the attacker wishes to write into the memory referenced by offset
. Consequently, the call to memcpy()
can overwrite an address with an attacker supplied address; typically resulting in arbitrary code execution.
...