Flexible array members are a special type of array where the last element of a structure with more than one named member has an incomplete array type; that is, the size of the array is not specified explicitly within the structure.
If a dynamically sized structure is needed, flexible array members should be used.
Non-Compliant Code Example
In the following non-compliant code, an array of size 1 is declared, but when the structure itself is instantiated, the size computed for malloc() is modified to take into account the full size of the dynamic array.
struct flexArrayStruct {
int num;
int data[1];
};
/* ... */
/* Space is allocated for the struct */
struct flexArrayStruct *structP = malloc(sizeof(struct flexArrayStruct) + sizeof(int) * (ARRAY_SIZE - 1));
if (!structP) {
/* handle malloc failure */
}
structP->num = SOME_NUMBER;
/* Access data[] as if it had been allocated as data[ARRAY_SIZE] */
for (i = 0; i < ARRAY_SIZE; i++) {
structP->data[i] = i;
}
However, in this non-compliant code example, the only member that is guaranteed to be valid, by strict C99 definition, is structP->data[0]. Consequently, for all i > 0, the results of the assignment are undefined.
Compliant Solution
This compliant solution uses the flexible array member to achieve a dynamically sized structure.
struct flexArrayStruct{
int num;
int data[];
};
/* ... */
/* Space is allocated for the struct */
struct flexArrayStruct *structP = malloc(sizeof(struct flexArrayStruct) + sizeof(int) * ARRAY_SIZE);
if (!structP) {
/* handle malloc failure */
}
structP->num = SOME_NUMBER;
/* Access data[] as if it had been allocated as data[ARRAY_SIZE] */
for (i = 0; i < ARRAY_SIZE; i++) {
structP->data[i] = i;
}
This compliant solution allows the structure to be treated as if it had declared the member data[] to be data[ARRAY_SIZE] in a manner that conforms to the C99 standard.
However, some restrictions do apply:
- The incomplete array type must be the last element within the structure.
- You cannot have an array of structure if the structure contains flexible array members.
- Structures that contain a flexible array member cannot be used as a member in the middle of another structure.
Risk Assessment
Although the non-compliant approach results in undefined behavior, it does work under most architectures.
Rule |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
|---|---|---|---|---|---|
MEM33-C |
1 (low) |
1 (unlikely) |
3 (low) |
P3 |
L3 |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
[[McCluskey 01]] ;login:, July 2001, Volume 26, Number 4
[[ISO/IEC 9899-1999]] Section 6.7.2.1, "Structure and union specifiers"