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

offset safety check is overly restrictive for ZSTs #3896

Closed
carolynzech opened this issue Feb 21, 2025 · 1 comment · Fixed by #3897
Closed

offset safety check is overly restrictive for ZSTs #3896

carolynzech opened this issue Feb 21, 2025 · 1 comment · Fixed by #3897
Assignees
Labels
[C] Bug This is a bug. Something isn't working.

Comments

@carolynzech
Copy link
Contributor

I tried this code:

#[kani::proof]
fn main() {
    let mut x = ();
    let ptr: *mut () = &mut x as *mut ();
    let count: usize = (isize::MAX as usize) + 1;
    let res = unsafe { ptr.add(count) };
}

using the following command line invocation:

cargo kani

with Kani version: 0.59

I expected to see this happen: verification succeeds because for ZSTs, the offset can overflow isize.

Instead, this happened: Kani failed with this safety check:

kani::safety_check(false, "Offset value overflows isize");

@carolynzech carolynzech added the [C] Bug This is a bug. Something isn't working. label Feb 21, 2025
@carolynzech carolynzech self-assigned this Feb 21, 2025
@carolynzech
Copy link
Contributor Author

Note that in Miri, this snippet runs without errors. If I change the pointee type to a non-ZST, I get:

error: Undefined Behavior: overflowing pointer arithmetic: the total offset in bytes does not fit in an `isize`
 --> src/main.rs:5:24
  |
5 |     let res = unsafe { ptr.add(count) };
  |                        ^^^^^^^^^^^^^^ overflowing pointer arithmetic: the total offset in bytes does not fit in an `isize`
  |
  = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
  = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
  = note: BACKTRACE:
  = note: inside `main` at src/main.rs:5:24: 5:38

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

github-merge-queue bot pushed a commit that referenced this issue Feb 21, 2025
#3755 introduced additional safety checks for the `offset` intrinsic,
including a check for whether `count` overflows `isize`. However, such
overflow is allowed for ZSTs. This PR changes the model to check for
ZSTs before computing the offset to avoid triggering an overflow failure
for ZSTs.

I also moved an existing test called `offset-overflow` into another
test, since #3755 changed the failure for that test to be about an out
of bounds allocation, not an isize overflow.

Resolves #3896

By submitting this pull request, I confirm that my contribution is made
under the terms of the Apache 2.0 and MIT licenses.
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