Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: xfer fread NCCE from ARR30->ARR39

...

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');
}

...

Noncompliant Code Example (Invalid Access by Library Function)

In this noncompliant code example, the function f() calls fread() to read nitems of type wchar_t, each size bytes in size, into an array of BUFSIZ elements, wbuf. However, the expression used to compute the value of nitems fails to account for the fact that, unlike the size of char, the size of wchar_t may be greater than 1. Thus, fread() could attempt to form pointers past the end of wbuf and use them to assign values to nonexistent elements of the array. Such an attempt results in undefined behavior 109  . A likely manifestation of this undefined behavior is a classic buffer overflow, which is often exploitable by code injection attacks.

For a discussion of this programming error in the Common Weakness Enumeration database, see CWE-121, "Access of memory location after end of buffer," and CWE-805, "Buffer access with incorrect length value."

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

This compliant solution correctly computes the maximum number of items for fread() to read from the file:

Code Block
bgColor#ccccff
langc
#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);
}

Anchor
Improper Scaling
Improper Scaling

...

Code Block
bgColor#ffcccc
langc
#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;  /* Failure */
  }
 
  memset(s + skip, 0, sizeof(struct big) - skip);
 
  return 0;
}

Compliant Solution

This compliant solution does not scale skip:

...

ISO/IEC TR 24772:2013Arithmetic Wrap-around Error [FIF]
Unchecked Array Indexing [XYZ]
ISO/IEC TS 17961Forming or using out-of-bounds pointers or array subscripts [invptr]
MITRE CWECWE-119, Failure to constrain operations within the bounds of a memory buffer
CWE-121, Stack-based buffer overflow
CWE-122, Heap-based buffer overflow
CWE-129, Unchecked array indexing
CWE-788, Access of memory location after end of buffer
CWE-805, Buffer access with incorrect length value

Bibliography

[Finlay 2003] 
[Microsoft 2003] 
[Pethia 2003] 
[Seacord 2013]Chapter 1, "Running with Scissors"
[Viega 2005]Section 5.2.13, "Unchecked Array Indexing"
[xorl 2009 ]"CVE-2008-1517: Apple Mac OS X (XNU) Missing Array Index Validation"

...