-
Notifications
You must be signed in to change notification settings - Fork 135
Description
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.