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

Reasoning about ZST addresses #3129

Closed
nishanthkarthik opened this issue Apr 5, 2024 · 7 comments · Fixed by #3134
Closed

Reasoning about ZST addresses #3129

nishanthkarthik opened this issue Apr 5, 2024 · 7 comments · Fixed by #3134
Labels
[C] Bug This is a bug. Something isn't working. [F] Soundness Kani failed to detect an issue

Comments

@nishanthkarthik
Copy link

I assumed ZST addresses are dangling, so they may or may not be equal for different instances of a type.

I tried this code:

#[repr(C)]
#[derive(Copy, Clone)]
struct Z(i8, i64);

struct Y;

#[kani::proof]
fn test_z() -> Z {
	let m = Y;
	let n = Y;
	let zz = Z(1, -1);
	
	let ptr: *const Z = if &n as *const _ == &m as *const _ {
		std::ptr::null()
	} else {
		&zz
	};
	unsafe{ *ptr }
}

using the following command line invocation:

kani main.rs

with Kani version: 0.48.0

I expected to see this happen: An error because addresses to ZSTs are not guaranteed to have distinct addresses at runtime. Running this snippet crashes playground

Instead, this happened:

...
SUMMARY:
 ** 0 of 7 failed

VERIFICATION:- SUCCESSFUL

Thanks!

@nishanthkarthik nishanthkarthik added the [C] Bug This is a bug. Something isn't working. label Apr 5, 2024
@tautschnig
Copy link
Member

Thank you very much for your report. We will investigate how to fix this in Kani (CBMC as the underlying verification engine assumes that each object has a unique address), but ZST objects are a Rust peculiarity.

@tautschnig tautschnig added the [F] Soundness Kani failed to detect an issue label Apr 5, 2024
@nishanthkarthik
Copy link
Author

Thank you. Is there an easy way to see how a rust snippet is converted to a CBMC input file? I looked for something like kani --keep-temporary-files but I did not find any.

@tautschnig
Copy link
Member

You'll want kani --verbose --keep-temps -- the latter keeps the temporary files, and the --verbose will tell you the exact commands that were invoked on those files.

@celinval
Copy link
Contributor

celinval commented Apr 5, 2024

Hi @nishanthkarthik, I am not sure this assumption holds, do you have any reference on this?

AFAIK, a pointer to a ZST is still a thin pointer (at least for now, there has been discussions to change that). So I believe thin pointer comparison rules still apply to them (which are also not well defined).

The main difference when it comes to ZST pointers is that a ZST access is valid even for dangling points (rust-lang/unsafe-code-guidelines#472).

There is one interesting thing though that it is worth mentioning, you do have to be careful when it comes to relying on address values in Kani. They do translate to concrete values, and each allocation will always have its unique value, even if their lifetime do not overlap.

@celinval
Copy link
Contributor

celinval commented Apr 5, 2024

BTW, I ran your test case, and it also succeeds in MIRI, since there is no UB and each local variable is considered a different allocation.

@nishanthkarthik
Copy link
Author

I did not find a source that said pointers to different ZST objects are guaranteed to be distinct, so I assumed they would be havoc'd by default and consequently a program trace may set ptr to null.

Is comparing pointers of ZSTs UB (or just valid but unspecified behavior)?

tautschnig added a commit to tautschnig/kani that referenced this issue Apr 8, 2024
It seems that rustc does not necessarily create unique objects for
ZST-typed symbols, unless they are parameters.

Resolves: model-checking#3129
@adpaco-aws
Copy link
Contributor

Hi @nishanthkarthik , just wanted to let you know that @celinval and @tautschnig have been trying to get some clarity on guarantees over ZST pointers in rust-lang/unsafe-code-guidelines#503 . Please feel free to join the discussion if you have more questions yourself.

tautschnig added a commit that referenced this issue Apr 30, 2024
The Rust specification does not guarantee that ZST-typed symbols are
backed by unique objects, and `rustc` appears to make use of this as can
be demonstrated for both locals and statics. For parameters no such
example has been found, but as there remains a lack of a guarantee we
err on the safe side.

Resolves: #3129
zpzigi754 pushed a commit to zpzigi754/kani that referenced this issue May 8, 2024
…hecking#3134)

The Rust specification does not guarantee that ZST-typed symbols are
backed by unique objects, and `rustc` appears to make use of this as can
be demonstrated for both locals and statics. For parameters no such
example has been found, but as there remains a lack of a guarantee we
err on the safe side.

Resolves: model-checking#3129
qinheping pushed a commit to qinheping/kani that referenced this issue May 9, 2024
…hecking#3134)

The Rust specification does not guarantee that ZST-typed symbols are
backed by unique objects, and `rustc` appears to make use of this as can
be demonstrated for both locals and statics. For parameters no such
example has been found, but as there remains a lack of a guarantee we
err on the safe side.

Resolves: model-checking#3129
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. [F] Soundness Kani failed to detect an issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants