Skip to content

Add support for non-deterministic pointer #2300

@zpzigi754

Description

@zpzigi754

Requested feature: assuming the validity of pointers
Use case: system verification

Let's say that an object is allocated in one place (place A) and its pointer is passed through an external interface (e.g., user-kernel boundary) to an another place (place B). In this case where place B cannot keep track of place A's objects, how can place B assume that the passed pointer is valid?

If I try to use the passed pointer directly, it generates a series of dereference failure such as

Failed Checks: dereference failure: pointer NULL
Failed Checks: dereference failure: pointer invalid
Failed Checks: dereference failure: deallocated dynamic object
Failed Checks: dereference failure: dead object
Failed Checks: dereference failure: pointer outside object bounds
Failed Checks: dereference failure: invalid integer address

If I treat the passed pointer as dynamic object with __CPROVER_assume(__CPROVER_DYNAMIC_OBJECT(p));,
one failure still remains.

Failed Checks: dereference failure: pointer outside object bounds

How could I remove that remaining failure?

Test case:

# main.rs
pub struct Context {
    pub len: u32,
}

extern "C" {
    fn ffi_CPROVER_DYNAMIC_OBJECT(p: usize);
}

fn entry(a0: usize) -> Result<usize, ()> {
    unsafe { ffi_CPROVER_DYNAMIC_OBJECT(a0) };     // without this, more pointer-related errors would be generated

    let ctx = a0 as *mut Context;
    unsafe {
        if (*ctx).len > 10 {                // this is the violating condition
            return Err(());
        }
    }
    Ok((0))
}

#[kani::proof]
#[kani::unwind(64)]
fn main() {
    let r0 = kani::any();      // let's say that this value is passed from an external interface (e.g., hardware)
                               // and we want to assume the pointer's validity after some sanity checks 
    let ret = entry(r0);
}

To run the harness with the CPROVER functions, I've used the below stub

# stub64.c
struct Unit ffi_CPROVER_DYNAMIC_OBJECT(unsigned long p) {
    __CPROVER_assume(__CPROVER_DYNAMIC_OBJECT(p));
}

with the command cargo kani --enable-unstable --c-lib stub64.c.

Metadata

Metadata

Assignees

Labels

[C] Feature / EnhancementA new feature request or enhancement to an existing feature.

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions