...
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 | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
MSC19-C | Low | Unlikely | High | P1 | 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" |
...
...