Skip to content

Commit 334ca6d

Browse files
authored
Update blog examples to avoid using Invariant (rust-lang#1523)
* Remove `Invariant` from stdlib example * Remove `Invariant` from Firecracker example * Format * Use `Self` and remove trivial `is_valid` methods * Remove leftover semicolon
1 parent 0ae8eb0 commit 334ca6d

File tree

2 files changed

+46
-38
lines changed

2 files changed

+46
-38
lines changed

tests/cargo-kani/firecracker-block-example/src/main.rs

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ impl GuestMemoryMmap {
4646
// ANCHOR: read_obj
4747
fn read_obj<T>(&self, addr: GuestAddress) -> Result<T, Error>
4848
where
49-
T: ByteValued + kani::Invariant + ReadObjChecks<T>,
49+
T: ByteValued + kani::Arbitrary + ReadObjChecks<T>,
5050
// This generic_const_exprs feature lets Rust know the size of generic T.
5151
[(); std::mem::size_of::<T>()]:,
5252
{
@@ -64,9 +64,9 @@ impl GuestMemoryMmap {
6464
#[derive(Default, Clone, Copy)]
6565
pub struct GuestAddress(pub u64);
6666

67-
unsafe impl kani::Invariant for GuestAddress {
68-
fn is_valid(&self) -> bool {
69-
true
67+
impl kani::Arbitrary for GuestAddress {
68+
fn any() -> Self {
69+
GuestAddress(kani::any())
7070
}
7171
}
7272

@@ -91,9 +91,9 @@ struct Descriptor {
9191

9292
unsafe impl ByteValued for Descriptor {}
9393

94-
unsafe impl kani::Invariant for Descriptor {
95-
fn is_valid(&self) -> bool {
96-
true
94+
impl kani::Arbitrary for Descriptor {
95+
fn any() -> Self {
96+
Descriptor { addr: kani::any(), len: kani::any(), flags: kani::any(), next: kani::any() }
9797
}
9898
}
9999

@@ -218,14 +218,15 @@ impl RequestHeader {
218218
pub fn new(request_type: u32, sector: u64) -> RequestHeader {
219219
RequestHeader { request_type, _reserved: 0, sector }
220220
}
221+
221222
fn read_from(memory: &GuestMemoryMmap, addr: GuestAddress) -> Result<Self, Error> {
222223
memory.read_obj(addr)
223224
}
224225
}
225226

226-
unsafe impl kani::Invariant for RequestHeader {
227-
fn is_valid(&self) -> bool {
228-
true
227+
impl kani::Arbitrary for RequestHeader {
228+
fn any() -> Self {
229+
RequestHeader { request_type: kani::any(), _reserved: kani::any(), sector: kani::any() }
229230
}
230231
}
231232

@@ -296,24 +297,24 @@ pub enum Error {
296297
Persist, /*(crate::virtio::persist::Error)*/
297298
}
298299

299-
unsafe impl kani::Invariant for Error {
300-
fn is_valid(&self) -> bool {
301-
matches!(
302-
*self,
303-
Error::DescriptorChainTooShort
304-
| Error::DescriptorLengthTooSmall
305-
| Error::GetFileMetadata
306-
| Error::GuestMemory
307-
| Error::InvalidDataLength
308-
| Error::InvalidOffset
309-
| Error::UnexpectedReadOnlyDescriptor
310-
| Error::UnexpectedWriteOnlyDescriptor
311-
| Error::FileEngine
312-
| Error::BackingFile
313-
| Error::EventFd
314-
| Error::IrqTrigger
315-
| Error::RateLimiter
316-
) || matches!(*self, Error::Persist)
300+
impl kani::Arbitrary for Error {
301+
fn any() -> Error {
302+
match kani::any() {
303+
0 => Error::DescriptorChainTooShort,
304+
1 => Error::DescriptorLengthTooSmall,
305+
2 => Error::GetFileMetadata,
306+
3 => Error::GuestMemory,
307+
4 => Error::InvalidDataLength,
308+
5 => Error::InvalidOffset,
309+
6 => Error::UnexpectedReadOnlyDescriptor,
310+
7 => Error::UnexpectedWriteOnlyDescriptor,
311+
8 => Error::FileEngine,
312+
9 => Error::BackingFile,
313+
10 => Error::EventFd,
314+
11 => Error::IrqTrigger,
315+
12 => Error::RateLimiter,
316+
_ => Error::Persist,
317+
}
317318
}
318319
}
319320

tests/cargo-kani/vecdeque-cve/src/abstract_vecdeque.rs

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88
//! the underlying storage buffer and only model its `capacity`.
99
//!
1010
//! This is useful from a verification perspective because we can write proof
11-
//! harnesses that show that the (abstracted) methods of our queue maintain
12-
//! a resource invariant (using the kani::Invariant trait). This means that
13-
//! we have confidence that the fix to the CVE covers all possible cases.
11+
//! harnesses that show that the (abstracted) methods of our queue maintain a
12+
//! resource invariant. This means that we have confidence that the fix to the
13+
//! CVE covers all possible cases.
14+
15+
use kani::Arbitrary;
1416

1517
///
1618
/// Based on src/alloc/collections/vec_deque/mod.rs
@@ -24,14 +26,19 @@ struct AbstractVecDeque {
2426
buf: AbstractRawVec,
2527
}
2628

27-
unsafe impl kani::Invariant for AbstractVecDeque {
28-
fn is_valid(&self) -> bool {
29-
self.tail < self.cap() && self.head < self.cap() && is_nonzero_pow2(self.cap())
29+
impl kani::Arbitrary for AbstractVecDeque {
30+
fn any() -> Self {
31+
let value = AbstractVecDeque { tail: kani::any(), head: kani::any(), buf: kani::any() };
32+
kani::assume(value.is_valid());
33+
value
3034
}
3135
}
32-
use kani::Invariant;
3336

3437
impl AbstractVecDeque {
38+
fn is_valid(&self) -> bool {
39+
self.tail < self.cap() && self.head < self.cap() && is_nonzero_pow2(self.cap())
40+
}
41+
3542
// what we call the *buf capacity*
3643
fn cap(&self) -> usize {
3744
self.buf.capacity()
@@ -231,9 +238,9 @@ struct AbstractRawVec {
231238
/* alloc: A removed */
232239
}
233240

234-
unsafe impl kani::Invariant for AbstractRawVec {
235-
fn is_valid(&self) -> bool {
236-
true
241+
impl kani::Arbitrary for AbstractRawVec {
242+
fn any() -> Self {
243+
AbstractRawVec { cap: kani::any() }
237244
}
238245
}
239246

0 commit comments

Comments
 (0)