Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Fixed the possibility of dereferencing a NULL pointer in g(), plus a bit of clean up to make consistent.

...

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

...