Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Wiki Markup
Many functions accept pointers as arguments. If the function dereferences an invalid pointer (see [EXP34-C. Ensure a null pointer is not dereferenced]), or reads or writes to a pointer that does not refer to an object, the results are [undefined|BB. Definitions#undefined]. Typically the program will terminate abnormally when the invalid pointer is dereferenced, but it is possible for an invalid pointer to be dereferenced, and its memory changed, without abnormal termination \[[Jack 07|AA. C References#Jack 07]\]. Such programs can be difficult to debug because of the difficulty in determining if a pointer is valid.

One source of prevention of way to eliminate invalid pointers is to define a function that could take accepts a pointer argument and indicate indicates if the pointer is valid or invalidnot, for some definition of valid. For instanceexample, the following function declares any pointer to be valid except NULL.

...

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;
  int *p;

  printf("pointer to local var invalidvalid? %d\n", invalidvalid(&local));
  printf("pointer to static var invalidvalid? %d\n", invalidvalid(&global));
  printf("pointer to function invalidvalid? %d\n", invalidvalid((void *)main));

  p = (int *)malloc(sizeof(int));
  printf("pointer to heap invalidvalid? %d\n", invalidvalid(p));
  printf("pointer to end of allocated heap invalidvalid? %d\n", invalidvalid(p++));
  printf("pointer to freed heap invalidvalid? %d\n", invalidvalid(p--));
  printf("null pointer invalidvalid? %d\n", invalidvalid(NULL));

  return 0;
}

On a Linux platform, this program produces the following output:

Code Block
pointer to local var invalid? 01
pointer to static var invalid? 01
pointer to function invalid? 10
pointer to heap invalid? 01
pointer to end of allocated heap invalid? 01
pointer to freed heap invalid? 01
null pointer invalid? 10

As you can see, the invalidThe valid() function is not perfect; does not guarantee validity (it only identifies null pointers and pointers to functions as invalid), but it can be used to catch a substantial number of problems that might otherwise go undetected.

Non-Compliant Code Example

...

Compliant Solution

By using the invalidvalid() function defined above, the function is less likely to modify memory outside its bounds.

Code Block
bgColor#ccccff
void incr(int *intptr) {
  if (invalid!valid( intptr)) {
    /* handle error */
  }
  *intptr++;
}

Compliant Solution (assert)

Since Because invalid pointers are often indicative of a bug defect in the program, one can use the assert() macro can be used to terminate immediately terminate if an invalid pointer is discovered (see MSC11-A. Incorporate diagnostic tests using assertions).

Code Block
bgColor#ccccff
#include <assert.h>

void incr(int *intptr) {
  assert(!invalidvalid( intptr));
  *intptr++;
}

Risk Assessment

...