Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: linked the Null Pointer Arithmetic example to UB 46

...

UB

Description

Example Code

46

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,
Improper Scaling, ARR30-C. Do not form or use out of bounds pointers or array subscripts

47

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 * operator that is evaluated.

Dereferencing Past the End Pointer, ARR30-C. Do not form or use out of bounds pointers or array subscripts

49

An array subscript is out of range, even if an object is apparently accessible with the given subscript (as in the lvalue expression a[1][7] given the declaration int a[4][5]).

ARR30-C. Do not form or use out of bounds pointers or array subscripts

62

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
bgColor#ccccff
langc
#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
Null Pointer Arithmetic
Null Pointer Arithmetic

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
bgColor#ffcccc
langc
#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.

...