Many library functions take accept pointers as arguments. If the pointer passed to a library function function dereferences an invalid pointer (as in EXP34-C. Do not dereference null pointers) or reads or writes to a pointer that does not refer to valid memoryan object, the results are undefined. Typically, the program will terminate abnormally when the an invalid pointer is dereferenced, but it is possible , and quite common, for an invalid pointer to be dereferenced , and its memory changed , without abnormal termination [Jack 2007]. Such programs can be very difficult to debug due to because of the difficulty of in determining the pointer's lack of validityif a pointer is valid.
One source of prevention of way to eliminate invalid pointers would be is to define a function that could take accepts a pointer and indicate if the argument and indicates whether or not the pointer is 'valid' or not, for some definition of valid. For instance, here is a function that example, the following function declares any pointer to be valid except NULL
.:
Code Block |
---|
int invalidvalid(void * ptr) { return (ptr =!= NULL); } |
Some platforms will have platform-specific pointer validation tools.
The following code relies on the _etext
address, which is provided by defined by the loader as the first address following the program text on many platforms, including AIX, Linux, QNX, IRIX, and Solaris. It is not POSIX-compliant, nor is it available on Windows.
Code Block |
---|
#include <stdio.h> #include <stdlib.h> int invalidvalid(void * p) { extern char _etext; return (p =!= NULL) ||&& ((char*) p <> &_etext); } int global; int main(void) { int local; void *p = &local; int* q = (int*) malloc(sizeof(intprintf("pointer to local var valid? %d\n", valid(&local)); printf("pointer to localstatic var invalidvalid? %d\n", invalidvalid(p&global)); p = &global; printf("pointer to staticfunction var invalidvalid? %d\n", invalid(pvalid((void *)main)); int *p = (voidint *) main; printf("pointer to function invalid? %d\n", invalid(pmalloc(sizeof(int)); printf("pointer to heap invalidvalid? %d\n", invalidvalid(qp)); q++; printf("pointer to end of allocated heap invalidvalid? %d\n", invalidvalid(q++p)); qfree(--; free(qp); printf("pointer to freed heap invalidvalid? %d\n", invalidvalid(qp)); q = NULL; printf("null pointer invalidvalid? %d\n", invalidvalid(qNULL)); return 0; } |
On a Linux platform, this program produces the following output:
Code Block |
---|
pointer to local var invalidvalid? 01 pointer to static var invalidvalid? 01 pointer to function invalidvalid? 10 pointer to heap invalidvalid? 01 pointer to end of allocated heap invalidvalid? 01 pointer to freed heap invalidvalid? 01 null pointer invalidvalid? 10 |
As you can see, the invalidThe valid()
function is does not perfectguarantee validity; it only identifies NULL
null pointers and pointers to functions as invalid.
Risk Assessment
A pointer validation library However, it can be used to identify, and thus, prevent the execution of vulnerable codeFailure to clear memory can result in leaked information. Occasionally, it can also lead to buffer overflows when programmers assume, for example, a NULL termination byte is present when it is notcatch a substantial number of problems that might otherwise go undetected.
Noncompliant Code Example
In this noncompliant code example, the incr()
function increments the value referenced by its argument. It also ensures that its argument is not a null pointer. But the pointer could still be invalid, causing the function to corrupt memory or terminate abnormally.
Code Block | ||||
---|---|---|---|---|
| ||||
void incr(int *intptr) {
if (intptr == NULL) {
/* Handle error */
}
(*intptr)++;
}
|
Compliant Solution
This incr()
function can be improved by using the valid()
function. The resulting implementation is less likely to dereference an invalid pointer or write to memory that is outside the bounds of a valid object.
Code Block | ||||
---|---|---|---|---|
| ||||
void incr(int *intptr) {
if (!valid(intptr)) {
/* Handle error */
}
(*intptr)++;
}
|
The valid()
function can be implementation dependent and perform additional, platform-dependent checks when possible. In the worst case, the valid()
function may only perform the same null-pointer check as the noncompliant code example. However, on platforms where additional pointer validation is possible, the use of a valid()
function can provide checks.
Risk Assessment
A pointer validation function can be used to detect and prevent operations from being performed on some invalid pointers.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
MEM10- |
C |
High |
Unlikely |
High |
P3 | L3 |
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
LDRA tool suite |
| 159 S | Enhanced enforcement |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
Related Guidelines
SEI CERT C++ Coding Standard | VOID MEM10-CPP. Define and use a pointer validation function |
MITRE CWE | CWE-20, Improper Input Validation |
Bibliography
...
MEM09-A. Do not assume memory allocation routines initialize memory 08. Memory Management (MEM)