Buffer overflow-unspecified-sized array index out of bounds

Like ABV.GENERAL, the ABV.ANY_SIZE_ARRAY checker is a generic checker that looks for array bounds violations-any access to an array element that is outside of the bounds of that array. ABV.ANY_SIZE_ARRAY checks for defects when the code references an array of unspecified size, which will typically be determined at run time.

The following example shows different C-standard techniques used in defining arrays. The C99 style is used when the array size will be determined when memory is allocated later in the code. This is the situation that will result in an ABV.ANY_SIZE_ARRAY flag from Klocwork.

1  struct OldStyle{
2  /* other fields */
3  unsigned char array[1];
4  };
5  struct GccStyle{
6  /* other fields */
7  unsigned char array[0];
8  };
10 struct C99Style{
11 /* other fields */
12 unsigned char array[];
13 };

ABV.ANY_SIZE_ARRAY is often used to filter out defects in cases of arrays of unspecified size from the checker results when you're using the C99 technique. If you don't want this defect flagged or if you want it filtered from other ABV defects, you can turn off this checker.

Vulnerability and risk

Consequences of buffer overflow include valid data being overwritten and execution of arbitrary and potentially malicious code. However, it's often best to switch off the ABV.ANY_SIZE_ARRAY checker when you're using any-sized arrays and managing them closely.

Code example 1

1  typedef struct NumericData {
2      int           varlen;
3      char          n_data[1];
4  } NumericData;
6  #define MAX_LEN 2048
7  void init(char *data) {
8      if (strlen(data) > MAX_LEN) return;
9      NumericData *X = (NumericData*)malloc(sizeof(NumericData) + strlen(data));
10      X->varlen = strlen(data);
11      int k;
12      for (k = 0; k < strlen(data); k++) {X->n_data[k] = data[k];}
13      X->n_data[k-1] = '\0';
14  }

Klocwork produces a buffer overflow report for line 13 indicating that the index of variable length array 'n_data' may be out of bounds: array 'n_data' of unspecified size may use index value -1. However, it's actually correct usage of the coding technique, so this is a typical case in which the designer may not want the defect reported, and disables the ABV.ANY_SIZE_ARRAY checker.

Code example 2

1  #define MAXL 255
2  typedef struct info_t_{
3    unsigned char code;
4    unsigned char length[2];
5    unsigned char value[1];
6  } info_t;
8  int getshort(unsigned char *l);
10 void foo(info_t *id){
11   unsigned char buf[MAXL];
12   int len = getshort(id->length);
13   if ((len > 0) && (len <= MAXL)) {
14      memcpy(buf, &id->value[0], len);
15   }
16 }

This is another example in which the defect is reported despite correct usage. Klocwork produces a buffer overflow report for line 14, indicating that the index of variable length array 'id->value' may be out of bounds: array '&id->value[0]' of unspecified size may use index values 0..254.

Security training

Application security training materials provided by Secure Code Warrior.


This checker can be extended through the Klocwork knowledge base. See Tuning C/C++ analysis for more information.