...
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <stdio.h>
enum { INV_SIZE=20 };
typedef struct {
size_t stockOfItem[INV_SIZE];
size_t length;
} Inventory;
size_t *getStock(Inventory iv);
int main(void) {
Inventory iv;
size_t *item;
iv.length = 0;
/*
* Other code that might modify the inventory but still
* leave no items in it upon completion.
*/
item = getStock(iv);
printf("Stock of first item in inventory: %d%zd\n", item[0]);
return 0;
}
size_t *getStock(Inventory iv) {
if (iv.length == 0) {
return NULL;
}
else {
return iv.stockOfItem;
}
}
|
...
This compliant solution eliminates the NULL return and simply returns the item array, even if it is zero-length. The main function can effectively handle this situation without exhibiting erroneous behavior. Since the array lives on the stack, it must prevent returning a value in the stack frame (as mandated by DCL30-C. Declare objects with appropriate storage durations). So the getStack() function also takes a pointer to Inventory, so that it can return a pointer to its contents safely.
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <stdio.h>
enum { INV_SIZE=20 };
typedef struct {
size_t stockOfItem[INV_SIZE];
size_t length;
} Inventory;
size_t *getStock(Inventory* iv);
int main(void) {
Inventory iv;
size_t i;
size_t *item;
iv.length = 0;
/*
* Other code that might modify the inventory but still
* leave no items in it upon completion.
*/
item = getStock(&iv);
if (iv.length != 0) {
printf("Stock of first item in inventory: %d%zd\n", item[0]);
}
return 0;
}
size_t *getStock(Inventory* iv) {
return iv.stockOfItem->stockOfItem;
}
|
Noncompliant Code Example (Sentinel Value)
...
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <stdio.h> #include <stdint.h> #include <malloc<stdlib.h> enum { FINAL_ITEM=SIZE_MAX, INV_SIZE=20 }; size_t *arraySort(size_t *array); int main(void) { size_t i; size_t stockOfItem[INV_SIZE]; size_t *sortedArray; /* Other code that might use stockarray but leaves it empty */ sortedArray = arraySort(stockOfItem); for (i = 0; sortedArray[i] != FINAL_ITEM; i++) { printf("Item stock: %d%zd", sortedArray[i]); } return 0; } /* Create new sorted array */ size_t *arraySort(size_t *array) { size_t i; size_t *sortedArray; for(i = 0; array[i] != FINAL_ITEM; i++); if (i == 0) { return NULL; } sortedArray = (size_t*) malloc(sizeof(size_t)*i); if (sortedArray == NULL) { /* Handle memory error */ } /* Add sorted data to array */ return sortedArray; } |
...
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <stdio.h>
#include <stdint.h>
#include <malloc.h>
enum { FINAL_ITEM=SIZE_MAX, INV_SIZE=20 };
size_t *arraySort(size_t *array);
int main(void) {
size_t i;
size_t stockOfItem[INV_SIZE];
size_t *sortedArray;
/* Other code that might use stockarray but leaves it empty */
sortedArray = arraySort(stockOfItem);
for (i = 0; sortedArray[i] != FINAL_ITEM; i++) {
printf("Item stock: %d%zd", sortedArray[i]);
}
return 0;
}
/* Create new sorted array */
size_t *arraySort(size_t *array) {
size_t i;
size_t *sortedArray;
for(i = 0; array[i] != FINAL_ITEM; i++);
if (i == 0) {
size_t *emptyArray = (size_t*) malloc(sizeof(size_t));
if(emptyArray == NULL) {
/* Handle memory error */
}
emptyArray[0] = FINAL_ITEM;
return emptyArray;
}
sortedArray = (size_t*) malloc(sizeof(size_t)*i);
if (sortedArray == NULL) {
/* Handle memory error */
}
/* Add sorted data to array */
return sortedArray;
}
|
...
Returning NULL rather than a zero-length array can lead to vulnerabilities when the client code does not handle NULL properly. Abnormal program termination can result when the calling function performs operations on NULL.
Rule | Severity | Likelihood | Detectable |
|---|
Repairable | Priority | Level |
|---|---|---|
MSC19-C | Low | Unlikely |
Yes | No |
P2 | L3 |
Automated Detection
Tool | Version | Checker | Description |
|---|---|---|---|
| Parasoft C/C++test |
| CERT_C-MSC19-a | Avoid accessing arrays out of bounds | |||||||
| PC-lint Plus |
| 413, 418, 419, 420, 473, | Partially supported |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this guideline on the CERT website.
Bibliography
| [Bloch 2008] | Item 43, "Return Empty Arrays or Collections, Not Nulls" |
...
...