Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory predicates won't work if function with contract is compiled as a dependency #3612

Closed
celinval opened this issue Oct 17, 2024 · 1 comment · Fixed by #3687
Closed
Labels
[C] Bug This is a bug. Something isn't working.

Comments

@celinval
Copy link
Contributor

celinval commented Oct 17, 2024

Let's say you have a crate crate_a that defines a copy_val function that is annotated with contracts:

///----- Crate with contract
#[requires(kani::mem::can_dereference(ptr))]
pub unsafe fn copy_val<T: Copy>(ptr: *const T) -> T {
}

Now we have a crate crate_b that uses crate_a that we want to verify using Kani:

pub fn safe_copy<T: Copy>(x: &T) -> T {
    unsafe { copy_val(x) }
}

using the following command line invocation:

cargo kani --only-codegen

with Kani version: 0.56.0

I expected to see this happen: Compilation should succeed.

Instead, this happened: Kani will fail to compile crate_a due to missing trait bounds.

@celinval celinval added the [C] Bug This is a bug. Something isn't working. label Oct 17, 2024
@celinval
Copy link
Contributor Author

Actually, I can trigger the same issue with a normal harness:

extern crate kani;

#[derive(Clone, Copy, kani::Arbitrary)]
struct Wrapper<T: ?Sized> {
    _size: usize,
    _value: T,
}

mod verify {
    use super::*;
    use kani::mem::can_dereference;
    #[kani::proof]
    #[kani::should_panic]
    pub fn check_invalid_dyn_ptr() {
        let raw_ptr: *const Wrapper<dyn PartialEq<u8>> =
            unsafe { new_dead_ptr::<Wrapper<u8>>(kani::any()) };
        assert!(can_dereference(raw_ptr));
    }

    unsafe fn new_dead_ptr<T>(val: T) -> *const T {
        let local = val;
        &local as *const _
    }
}

Running Kani will fail compilation:

error[E0277]: the trait bound `std::ptr::DynMetadata<dyn std::cmp::PartialEq<u8>>: kani::mem::PtrProperties<Wrapper<dyn std::cmp::PartialEq<u8>>>` is not satisfied
  --> adt_with_metadata.rs:35:33
   |
35 |         assert!(can_dereference(raw_ptr));
   |                 --------------- ^^^^^^^ the trait `kani::mem::PtrProperties<Wrapper<dyn std::cmp::PartialEq<u8>>>` is not implemented for `std::ptr::DynMetadata<dyn std::cmp::PartialEq<u8>>`
   |                 |
   |                 required by a bound introduced by this call
   |
   = help: the trait `kani::mem::PtrProperties<dyn std::cmp::PartialEq<u8>>` is implemented for `std::ptr::DynMetadata<dyn std::cmp::PartialEq<u8>>`
   = help: for that trait implementation, expected `dyn std::cmp::PartialEq<u8>`, found `Wrapper<dyn std::cmp::PartialEq<u8>>`
note: required by a bound in `kani::mem::can_dereference`

github-merge-queue bot pushed a commit that referenced this issue Nov 22, 2024
This change fixes how we compute size of the object in our mem
predicates, and provide user visible methods to try to retrieve the size
of the object if known and valid (`checked_size_of_raw` and
`checked_align_of_raw`.

Fixes #3612
Fixes #3627

## Call-outs

To simplify this PR, I moved the following changes to their own PRs:
1. #3644
2. #3718

I also removed the fix for the intrinsics `size_of_val` and
`align_of_val` from this PR, and I will create a follow up PR once this
one is merged.

---------

Co-authored-by: Carolyn Zech <cmzech@amazon.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[C] Bug This is a bug. Something isn't working.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant