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

proof_for_contracts making false positive failures with memcpy on drop #3798

Closed
ShoyuVanilla opened this issue Dec 29, 2024 · 2 comments
Closed
Labels
[C] Bug This is a bug. Something isn't working.

Comments

@ShoyuVanilla
Copy link
Contributor

ShoyuVanilla commented Dec 29, 2024

I found this while working on model-checking/verify-rust-std#234

I tried this code:

#[cfg(kani)]
pub mod verify {
    #[kani::ensures(|_| unsafe { *src == *dst })]
    pub fn foo(src: *const u8, dst: *mut u8) {
        struct CopyOnDrop {
            src: *const u8,
            dst: *mut u8,
        }

        impl Drop for CopyOnDrop {
            fn drop(&mut self) {
                unsafe {
                    std::ptr::copy_nonoverlapping(self.src, self.dst, 1);
                }
            }
        }

        let _drop_guard = CopyOnDrop { src, dst };
    }

    #[kani::proof]
    pub fn check_foo() {
        let src = 42;
        let mut dst = 0;
        foo(&raw const src, &raw mut dst);
        assert!(src == dst);
    }

    #[kani::proof_for_contract(foo)]
    pub fn check_foo_contract() {
        let src = 42;
        let mut dst = 0;
        foo(&raw const src, &raw mut dst);
    }
}

using the following command line invocation:

cargo kani -Zfunction-contracts

with Kani version: 0.57.0

I expected to see this happen: Both harnesses succeed

Instead, this happened: check_foo_contract falis with the following;

Check 16: memcpy.assigns.2
         - Status: FAILURE
         - Description: "Check that array_replace((const void *)(char *)dst, ...) is allowed by the assigns clause"
         - Location: <builtin-library-memcpy>:46 in function memcpy
@ShoyuVanilla ShoyuVanilla added the [C] Bug This is a bug. Something isn't working. label Dec 29, 2024
@BusyBeaver-42
Copy link

Hi @ShoyuVanilla, when writing a contract for a function, if it writes to some memory then you have to declare it in the contract using the modifies macro (see also write sets).

In your case, you have to write your contract like this.

#[kani::modifies(dst)]
#[kani::ensures(|_| unsafe { *src == *dst })]
pub fn foo(src: *const u8, dst: *mut u8) {
    // snip
}

@ShoyuVanilla
Copy link
Contributor Author

ShoyuVanilla commented Dec 29, 2024

Oh, thanks! I should have read the docs more carefully 😅

@ShoyuVanilla ShoyuVanilla closed this as not planned Won't fix, can't repro, duplicate, stale Dec 29, 2024
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

No branches or pull requests

2 participants