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

Tracking Issue: Automatically ensure validity invariants of unsafe operations #2998

Open
4 tasks
celinval opened this issue Feb 7, 2024 · 1 comment
Open
4 tasks
Assignees
Labels
[C] Feature / Enhancement A new feature request or enhancement to an existing feature.

Comments

@celinval
Copy link
Contributor

celinval commented Feb 7, 2024

Requested feature: Kani should automatically check if unsafe operations can break validity invariants which can trigger UB. According to the Rust reference, producing an invalid value, even in private fields and locals is undefined behavior. "Producing" a value happens any time a value is assigned to or read from a place, passed to a function/primitive operation or returned from a function/primitive operation.
Use case: Checking that unsafe code doesn't trigger UB.
Link to relevant documentation (Rust reference, Nomicon, RFC): Rust UB reference and definition of validity invariant.

Test case:

#[kani::requires(!ptr.is_null())]
#[kani::ensures(!result.as_ptr().is_null())] // Compiler warns that this should always be nonnull().
pub unsafe fn new_unchecked<T>(ptr: *mut T) -> NonNull<T> {
    NonNull::<T>::new_unchecked(ptr)
}

Since it is not possible to programmatically verify undefined behavior, Kani compiler must insert checks before the UB actually happens.

Tasks

  • RFC for UB checks
  • Implement basic checks
  • Mitigate checks that aren't implemented yet
  • Add tests
@celinval celinval added the [C] Feature / Enhancement A new feature request or enhancement to an existing feature. label Feb 7, 2024
@celinval celinval self-assigned this Feb 7, 2024
@celinval
Copy link
Contributor Author

celinval commented Feb 22, 2024

Note for self: We should use implement rust-lang/project-stable-mir#58 and use the valid range from Scalar type. We would need to traverse structures to add proper checks. Maybe experiment with transforming StableMIR instead of regular MIR. This would play well since we want the monomorphic version to add validity checks. Here are a few good places to see how rustc / MIRI handle these things:

@celinval celinval changed the title Automatically ensure validity invariants of unsafe operations Tracking Issue: Automatically ensure validity invariants of unsafe operations Mar 19, 2024
celinval added a commit that referenced this issue Mar 25, 2024
This is still incomplete, but hopefully it can be merged as an unstable
feature. I'll publish an RFC shortly.

This instruments the function body with assertion checks to see if users
are generating invalid values. This covers:
  - Union access
  - Raw pointer dereference
  - Transmute value
  - Field assignment of struct with invalid values
  - Aggregate assignment

Things not covered today should trigger ICE or a delayed verification
failure due to unsupported feature.

## Design

This change has two main design changes which are inside the new
`kani_compiler::kani_middle::transform` module:
1- Instance body should now be retrieved from the `BodyTransformation`
structure. This structure will run transformation passes on instance
bodies (i.e.: monomorphic instances) and cache the result.
2- Create a new transformation pass that instruments the body of a
function for every potential invalid value generation.
3- Create a body builder which contains all elements of a function body
and mutable functions to modify them accordingly.


Related to #2998
Fixes #301 

---------

Co-authored-by: Zyad Hassan <88045115+zhassan-aws@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[C] Feature / Enhancement A new feature request or enhancement to an existing feature.
Projects
None yet
Development

No branches or pull requests

1 participant