Skip to content

Back-end encoding of pointers corrupts large offsets #311

Open
@martin-cs

Description

@martin-cs

This bug gives a correctness error sv-benchmarks/c/array-memsafety/openbsd_cmemrchr-alloca_true-valid-memsafety.i

Pointers are represented as (object, offset) pairs. The back-end (bv_pointers.h) encodes these into config.ansi_c.pointer_width bit bvt's by using the top BV_ADDR_BITS (currently 8) for the object and the remaining bits for the offset. This means that if the offset uses more bits than that it will be truncated giving some really fun effects when the decode sign extends it.

It is not immediately clear how to fix this:

  1. Have offset be a full word and add BV_ADDR_BITS on the front. This means that pointers will no longer have the correct size.
  2. Another option is to make this limitation clearer by catching any offset large enough to trigger this problem. That would avoid this kind of silent mistake but its all shades of ugly.
  3. There might be a semi-fix in which we rely on knowing the object size to do the encoding / decoding. That way we should only get weirdness like this in cases where the program would allocate more than an addressible amount of memory. I'll see what I can do.
int main() { int n = nondet_int(); __CPROVER_assume( (n > 0) && (n > (1 << 23)) );

int nm = n-1;

char *base = __builtin_alloca (n);
//char works = *(base + nm);

char *last = base + nm;
signed offset = __CPROVER_POINTER_OFFSET(last);

__CPROVER_assert(0 <= offset && offset < n, "range check");

return 0;
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions