model-checking / verify-rust-std

Verifying the Rust standard library
https://model-checking.github.io/verify-rust-std/
Other
161 stars 28 forks source link

Challenge 1: Verify `core` transmuting methods #19

Open tautschnig opened 5 months ago

tautschnig commented 5 months ago

This issue is a tracking issue for Challenge 1: Verify core transmuting methods.

Challenge link: https://model-checking.github.io/verify-rust-std/challenges/0001-core-transmutation.html

rahulku commented 5 months ago

Can we have an explicit link to the challenge...

AlexLB99 commented 2 months ago

Hi all, I'll be working on this alongside professor Patrick Lam (@patricklam) from the University of Waterloo. Will keep you updated on progress, and happy to collaborate with anyone else working on this!

AlexLB99 commented 1 month ago

Hi, I just had some questions about verifying the transmute function itself.

(1) Which combinations of input/output types specifically would we want to check for transmute? For instance, I saw another challenge (pointer manipulation proofs https://github.com/model-checking/verify-rust-std/discussions/100) was going with something like:

  • All integer types.
  • At least one dyn Trait.
  • At least one slice.
  • For unit type.
  • At least one composite type with multiple non-ZST fields.

Does something like this seem reasonable for transmute (e.g., one dyn Trait to another dyn Trait)?

(2) Also, in the comments of https://github.com/model-checking/verify-rust-std/discussions/100, it's mentioned that it's better to have separate harnesses for different input types. In the case of transmute, is it better to have separate harnesses for each combination of input/output types we want to test? For instance: transmute_type1_to_type2_harness(), transmute_type2_to_type1_harness(), transmute_type1_to_type3_harness(), etc.

Thank you!

celinval commented 3 weeks ago

Hi @AlexLB99, answering your questions:

(1) For the transmute challenge, I would suggest that you try difference layout combinations. For example, transmuting types with different sizes, types with zero size type, types with different validity requirements, with different padding bytes, as well as types with the same layout. (2) Yes, this is in fact a Kani limitation. When verifying contracts, you can only verify one instantiation of the target function. Thus, you need one harness per generic parameter combination.

momvart commented 6 days ago

I was reading the description, and the definition of soundness.

A value-to-value transmutation is sound if:

  1. the source value is a bit-valid instance of the destination type;
  2. violations of library safety invariants (e.g., invariants on a field's value) of the destination type are not violated by subsequent use of the transmuted value.

I was wondering if this definition includes the niche tag encoding for enums. Should it be interpreted as a case of bit-validity or as invariants on field's value?

While I think challenges #109 and #84 are related as the basic cases of it, you can imagine more complicated possible undefined behaviors when transmuting to enums like below (which also uses a niche encoding because of char):

enum Bar {
    A,
    B(Option<(u8, char)>),
    C,
}

BTW, we at SFU, would be happy to participate in these challenges under our project which is a tool performing concolic execution for MIR.

celinval commented 5 days ago

Hi @momvart, yes, this challenge does include niche tag encoding as part of the bit validity specification. Generating an invalid tag is UB, and generating an invalid variant value is also UB.

Let's say you transmute an array of u8 with same size as Bar. Users need to ensure that the tag value corresponds to one of the existing variants: A, B, or C. If B, the value of it's member must also be valid. The Option tag value maps to either Some or None, an so on.

celinval commented 5 days ago

Also, it's great to hear about SFU interest, @momvart. Please check the tool application process, and if you have further questions, please post them in the discussions.