checkedc icon indicating copy to clipboard operation
checkedc copied to clipboard

Possibility of using stack variables for nt_array bounds widening

Open yiyunliu opened this issue 3 years ago • 0 comments

Consider the following program:

#include <string_checked.h>
#include <stdchecked.h>
#include <stdlib_checked.h>
#pragma CHECKED_SCOPE ON
int main(int argc, nt_array_ptr<char> argv checked[] : count(argc)) {
  nt_array_ptr<char> str = "hello";
  // forget the precise bound information
  nt_array_ptr<char> str_0 : bounds(str_0,str_0) = str;
  if(* str_0) {
    str_0[1];
  }
  size_t x = 1;
  /* throws an error because the inserted dynamic check assumes the upper bound is still 0 */
  return str_0[x];
}

Currently, in the Clang Checked-C implementation, the program type-checks but raises an OOB error at runtime because the inserted dynamic check compares str_0+x against the statically determined upper bound str_0 when evaluating str_0[x].

However, we can also store the bounds of str_0 at some location on the stack (I'll refer to them as str_0.h, str_0.l) and mutate the bound at runtime (in the example above, increment str_0.h while entering the then branch). When evaluating str_0[x], we can compare str_0+x against str_0.l/h instead of the constant 0. The program would run successfully thanks to the less conservative dynamic check.

This alternative approach obviously introduces the use of fat pointers, but this particular use case could be legit since there is no function calls involved. Avoiding fat pointers is necessary for compatibility with plain C, but it can also have some performance impact. If the performance concern is not essential, then I don't see why we can't have this type of localized fat pointers.

yiyunliu avatar Apr 24 '21 23:04 yiyunliu