-
Notifications
You must be signed in to change notification settings - Fork 97
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement memory initialization state copy functionality (#3350)
This PR adds support of copying memory initialization state without checks in-between. Every time a copy is performed, the tracked byte is non-deterministically switched. Resolves #3347 By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.
- Loading branch information
1 parent
f27a5ed
commit e6f8a62
Showing
20 changed files
with
397 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Complete - 1 successfully verified harnesses, 0 failures, 1 total. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// Copyright Kani Contributors | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
// kani-flags: -Z uninit-checks | ||
|
||
#[repr(C)] | ||
#[derive(kani::Arbitrary)] | ||
struct S(u32, u8); // 5 bytes of data + 3 bytes of padding. | ||
|
||
#[kani::proof] | ||
/// This checks that reading copied initialized bytes verifies correctly. | ||
unsafe fn copy_without_padding() { | ||
let from: S = kani::any(); | ||
let mut to: u64 = kani::any(); | ||
|
||
let from_ptr = &from as *const S; | ||
let to_ptr = &mut to as *mut u64; | ||
|
||
// This should not cause UB since `copy` is untyped. | ||
std::ptr::copy(from_ptr as *const u8, to_ptr as *mut u8, std::mem::size_of::<u32>()); | ||
|
||
// Since the previous copy only copied 4 bytes, no padding was copied, so no padding is read. | ||
let data: u64 = std::ptr::read(to_ptr); | ||
} |
11 changes: 11 additions & 0 deletions
11
tests/expected/uninit/copy/expose_padding_via_copy.expected
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
std::ptr::read::<u64>.assertion.1\ | ||
- Status: FAILURE\ | ||
- Description: "Undefined Behavior: Reading from an uninitialized pointer of type `*const u64`"\ | ||
|
||
std::ptr::read::<u64>.assertion.2\ | ||
- Status: FAILURE\ | ||
- Description: "Undefined Behavior: Reading from an uninitialized pointer of type `u64`"\ | ||
|
||
Summary: | ||
Verification failed for - expose_padding_via_copy | ||
Complete - 0 successfully verified harnesses, 1 failures, 1 total. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// Copyright Kani Contributors | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
// kani-flags: -Z uninit-checks | ||
|
||
#[repr(C)] | ||
#[derive(kani::Arbitrary)] | ||
struct S(u32, u8); // 5 bytes of data + 3 bytes of padding. | ||
|
||
/// This checks that reading copied uninitialized bytes fails an assertion. | ||
#[kani::proof] | ||
unsafe fn expose_padding_via_copy() { | ||
let from: S = kani::any(); | ||
let mut to: u64 = kani::any(); | ||
|
||
let from_ptr = &from as *const S; | ||
let to_ptr = &mut to as *mut u64; | ||
|
||
// This should not cause UB since `copy` is untyped. | ||
std::ptr::copy(from_ptr as *const u8, to_ptr as *mut u8, std::mem::size_of::<S>()); | ||
|
||
// This reads uninitialized bytes, which is UB. | ||
let padding: u64 = std::ptr::read(to_ptr); | ||
} |
11 changes: 11 additions & 0 deletions
11
tests/expected/uninit/copy/expose_padding_via_copy_convoluted.expected
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
std::ptr::read::<u64>.assertion.1\ | ||
- Status: FAILURE\ | ||
- Description: "Undefined Behavior: Reading from an uninitialized pointer of type `*const u64`"\ | ||
|
||
std::ptr::read::<u64>.assertion.2\ | ||
- Status: FAILURE\ | ||
- Description: "Undefined Behavior: Reading from an uninitialized pointer of type `u64`"\ | ||
|
||
Summary: | ||
Verification failed for - expose_padding_via_copy_convoluted | ||
Complete - 0 successfully verified harnesses, 1 failures, 1 total. |
42 changes: 42 additions & 0 deletions
42
tests/expected/uninit/copy/expose_padding_via_copy_convoluted.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// Copyright Kani Contributors | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
// kani-flags: -Z uninit-checks | ||
|
||
#[repr(C)] | ||
#[derive(kani::Arbitrary)] | ||
struct S(u32, u8); // 5 bytes of data + 3 bytes of padding. | ||
|
||
/// This checks that reading copied uninitialized bytes fails an assertion even if pointer are | ||
/// passed around different functions. | ||
#[kani::proof] | ||
unsafe fn expose_padding_via_copy_convoluted() { | ||
unsafe fn copy_and_read_helper(from_ptr: *const S, to_ptr: *mut u64) -> u64 { | ||
// This should not cause UB since `copy` is untyped. | ||
std::ptr::copy(from_ptr as *const u8, to_ptr as *mut u8, std::mem::size_of::<S>()); | ||
// This reads uninitialized bytes, which is UB. | ||
let padding: u64 = std::ptr::read(to_ptr); | ||
padding | ||
} | ||
|
||
unsafe fn partial_copy_and_read_helper(from_ptr: *const S, to_ptr: *mut u64) -> u32 { | ||
// This should not cause UB since `copy` is untyped. | ||
std::ptr::copy(from_ptr as *const u8, to_ptr as *mut u8, std::mem::size_of::<u32>()); | ||
// This does not read uninitialized bytes. | ||
let not_padding: u32 = std::ptr::read(to_ptr as *mut u32); | ||
not_padding | ||
} | ||
|
||
let flag: bool = kani::any(); | ||
|
||
let from: S = kani::any(); | ||
let mut to: u64 = kani::any(); | ||
|
||
let from_ptr = &from as *const S; | ||
let to_ptr = &mut to as *mut u64; | ||
|
||
if flag { | ||
copy_and_read_helper(from_ptr, to_ptr); | ||
} else { | ||
partial_copy_and_read_helper(from_ptr, to_ptr); | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
tests/expected/uninit/copy/expose_padding_via_non_byte_copy.expected
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
std::ptr::read::<u64>.assertion.1\ | ||
- Status: FAILURE\ | ||
- Description: "Undefined Behavior: Reading from an uninitialized pointer of type `*const u64`"\ | ||
|
||
std::ptr::read::<u64>.assertion.2\ | ||
- Status: FAILURE\ | ||
- Description: "Undefined Behavior: Reading from an uninitialized pointer of type `u64`"\ | ||
|
||
Summary: | ||
Verification failed for - expose_padding_via_non_byte_copy | ||
Complete - 0 successfully verified harnesses, 1 failures, 1 total. |
23 changes: 23 additions & 0 deletions
23
tests/expected/uninit/copy/expose_padding_via_non_byte_copy.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// Copyright Kani Contributors | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
// kani-flags: -Z uninit-checks | ||
|
||
#[repr(C)] | ||
#[derive(kani::Arbitrary)] | ||
struct S(u32, u8); // 5 bytes of data + 3 bytes of padding. | ||
|
||
/// This checks that reading copied uninitialized bytes after a multi-byte copy fails an assertion. | ||
#[kani::proof] | ||
unsafe fn expose_padding_via_non_byte_copy() { | ||
let from: S = kani::any(); | ||
let mut to: u64 = kani::any(); | ||
|
||
let from_ptr = &from as *const S; | ||
let to_ptr = &mut to as *mut u64; | ||
|
||
// This should not cause UB since `copy` is untyped. | ||
std::ptr::copy(from_ptr as *const u64, to_ptr as *mut u64, 1); | ||
|
||
// This reads uninitialized bytes, which is UB. | ||
let padding: u64 = std::ptr::read(to_ptr); | ||
} |
1 change: 1 addition & 0 deletions
1
tests/expected/uninit/copy/non_byte_copy_without_padding.expected
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Complete - 1 successfully verified harnesses, 0 failures, 1 total. |
Oops, something went wrong.