Skip to content
This repository was archived by the owner on Sep 30, 2024. It is now read-only.

Bounds safe interfaces

David Tarditi edited this page Sep 30, 2018 · 12 revisions

Overview

Checked C is designed so that programs can be changed to use checked pointers and arrays in an incremental fashion. A programmer can change just a few lines at a time and still have a working program. This matches the way that software is developed and maintained. Checked C also allows libraries and consumers of libraries to be modified in an incremental fashion. This reflects the reality that libraries may be modified in a slow fashion, if at all.

To allow incremental modification, a programmer uses bounds-safe interfaces to specify the requirements and expected behavior with respect to bounds of existing functions, global variables, and data structures. These requirements are enforced at compile-time when checked pointers and arrays are used. They are not enforced at compile-time when unchecked pointers and arrays are used. Code that uses unchecked pointers and arrays is compiled as though the bounds-safe interfaces were not present.

To add a bounds-safe interface to an existing declaration, a programmer redeclares the declared entity with additional information. The msot common annotation is the itype annotation, which gives an alternate checked type for a declaration. For example, strcmp is redeclared as:

int strcmp(const char *src1 : itype(_Nt_array_ptr<const char>),
           const char *src2 : itype(_Nt_array_ptr<const char>));

This allows strcmp to be called with checked pointers to null-terminated arrays of characters. When type checking an argument, the compiler first tries the declared type and then tries the type declared by the itypeannotation. However strcmp cannot be called with checked pointers to arrays of characters. These might not be null-terminated and passing such an argument could cause a buffer overrrun:

void f(_Nt_array_ptr<const char> arg1, _Nt_array_ptr<const char> arg2) {
  if (strcmp(arg1, arg2)) // OK,
      ...
}

void g(_Array_ptr<const char> arg1, _Array_ptr<const char> arg2) {
  if (strcmp(arg1, arg2)) // Error.
      ...
}

Here are examples of other standard C library functions annotated with itype declarations:

size_t strlen(const char *s : itype(_Nt_array_ptr<const char>));
int atoi(const char *s : itype(_Nt_array_ptr<const char>));
double modf(double value, double *iptr : itype(_Ptr<double>));
int fclose(FILE *stream : itype(_Ptr<FILE>));
FILE *tmpfile(void) : itype(_Ptr<FILE>);

Clone this wiki locally