ABV.ANY_SIZE_ARRAY
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.
struct OldStyle{
/* other fields */
unsigned char array[1];
};
struct GccStyle{
/* other fields */
unsigned char array[0];
};
struct C99Style{
/* other fields */
unsigned char array[];
};
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
typedef struct NumericData {
int varlen;
char n_data[1];
} NumericData;
#define MAX_LEN 2048
void init(char *data) {
if (strlen(data) > MAX_LEN) return;
NumericData *X = (NumericData*)malloc(sizeof(NumericData) + strlen(data));
X->varlen = strlen(data);
int k;
for (k = 0; k < strlen(data); k++) {X->n_data[k] = data[k];}
X->n_data[k-1] = '\0';
}
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
#define MAXL 255
typedef struct info_t_{
unsigned char code;
unsigned char length[2];
unsigned char value[1];
} info_t;
int getshort(unsigned char *l);
void foo(info_t *id){
unsigned char buf[MAXL];
int len = getshort(id->length);
if ((len > 0) && (len <= MAXL)) {
memcpy(buf, &id->value[0], len);
}
}
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.
Related checkers
External guidance
- CERT ARR00-C: Understand how arrays work
- CERT ARR30-C: Do not form or use out-of-bounds pointers or array subscripts
- CERT CTR50-CPP: Guarantee that container indices and iterators are within the valid range
- CERT ENV01-C: Do not make assumptions about the size of an environment variable
- CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer
- CWE-124: Buffer Underwrite ('Buffer Underflow')
- CWE-125: Out-of-bounds Read
- CWE-787: Out-of-bounds Write
- CWE-788: Access of Memory Location After End of Buffer
- CWE-805: Buffer Access with Incorrect Length Value
- STIG-ID:APP3590.1 Application is vulnerable to buffer overflows
Security training
Application security training materials provided by Secure Code Warrior.
Extension
This checker can be extended through the Klocwork knowledge base. See Tuning C/C++ analysis for more information.