forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Audit for unchecked intrinsics (rust-lang#1076)
* Add positive test cases * Refactor `div_does_not_overflow` into fn, use in macro * Add negative test cases * Add negative tests for regular div/rem * Minor fixes for div/rem cases
- Loading branch information
1 parent
840b5e6
commit 4f7b5d4
Showing
15 changed files
with
268 additions
and
10 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
// kani-verify-fail | ||
|
||
// Check that division triggers overflow checks. | ||
// Covers the case where `a == T::MIN && b == -1`. | ||
|
||
#[kani::proof] | ||
fn main() { | ||
let a: i8 = i8::MIN; | ||
let b: i8 = kani::any(); | ||
kani::assume(b == -1); | ||
let _ = a / b; | ||
} |
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,14 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
// kani-verify-fail | ||
|
||
// Check that division triggers overflow checks. | ||
// Covers the case where `b == 0`. | ||
|
||
#[kani::proof] | ||
fn main() { | ||
let a: i8 = kani::any(); | ||
let b: i8 = kani::any(); | ||
kani::assume(b == 0); | ||
let _ = a / b; | ||
} |
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,14 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
// kani-verify-fail | ||
|
||
// Check that remainder triggers overflow checks. | ||
// Covers the case where `a == T::MIN && b == -1`. | ||
|
||
#[kani::proof] | ||
fn main() { | ||
let a: i8 = i8::MIN; | ||
let b: i8 = kani::any(); | ||
kani::assume(b == -1); | ||
let _ = a % b; | ||
} |
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,14 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
// kani-verify-fail | ||
|
||
// Check that remainder triggers overflow checks. | ||
// Covers the case where `b == 0`. | ||
|
||
#[kani::proof] | ||
fn main() { | ||
let a: i8 = kani::any(); | ||
let b: i8 = kani::any(); | ||
kani::assume(b == 0); | ||
let _ = a % b; | ||
} |
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,13 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
// kani-verify-fail | ||
|
||
// Check that `unchecked_add` triggers overflow checks. | ||
#![feature(core_intrinsics)] | ||
|
||
#[kani::proof] | ||
fn main() { | ||
let a: i32 = kani::any(); | ||
let b: i32 = kani::any(); | ||
unsafe { std::intrinsics::unchecked_add(a, b) }; | ||
} |
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,14 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
// kani-verify-fail | ||
|
||
// Check that `unchecked_div` triggers overflow checks. | ||
// Covers the case where `a == T::MIN && b == -1`. | ||
#![feature(core_intrinsics)] | ||
|
||
#[kani::proof] | ||
fn main() { | ||
let a: i32 = i32::MIN; | ||
let b: i32 = -1; | ||
unsafe { std::intrinsics::unchecked_div(a, b) }; | ||
} |
14 changes: 14 additions & 0 deletions
14
tests/kani/Intrinsics/Math/Arith/Unchecked/div_zero_fail.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,14 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
// kani-verify-fail | ||
|
||
// Check that `unchecked_div` triggers overflow checks. | ||
// Covers the case where `b == 0`. | ||
#![feature(core_intrinsics)] | ||
|
||
#[kani::proof] | ||
fn main() { | ||
let a: i32 = kani::any(); | ||
let b: i32 = 0; | ||
unsafe { std::intrinsics::unchecked_div(a, b) }; | ||
} |
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,13 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
// kani-verify-fail | ||
|
||
// Check that `unchecked_mul` triggers overflow checks. | ||
#![feature(core_intrinsics)] | ||
|
||
#[kani::proof] | ||
fn main() { | ||
let a: i32 = kani::any(); | ||
let b: i32 = kani::any(); | ||
unsafe { std::intrinsics::unchecked_mul(a, b) }; | ||
} |
57 changes: 57 additions & 0 deletions
57
tests/kani/Intrinsics/Math/Arith/Unchecked/no_overflows.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,57 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
// | ||
// Check that none of these operations trigger spurious overflow checks. | ||
#![feature(core_intrinsics)] | ||
use std::intrinsics::{ | ||
unchecked_add, unchecked_div, unchecked_mul, unchecked_rem, unchecked_shl, unchecked_shr, | ||
unchecked_sub, | ||
}; | ||
|
||
// `checked_shr` and `checked_shl` require `u32` for their argument. We use | ||
// `u32` in those cases and `u8` for the rest because they perform better. | ||
macro_rules! verify_no_overflow { | ||
($ty:ty, $cf: ident, $uf: ident) => {{ | ||
let a: $ty = kani::any(); | ||
let b: $ty = kani::any(); | ||
let checked = a.$cf(b); | ||
kani::assume(checked.is_some()); | ||
let unchecked = unsafe { $uf(a, b) }; | ||
assert!(checked.unwrap() == unchecked); | ||
}}; | ||
} | ||
|
||
#[kani::proof] | ||
fn test_unchecked_add() { | ||
verify_no_overflow!(u8, checked_add, unchecked_add); | ||
} | ||
|
||
#[kani::proof] | ||
fn test_unchecked_sub() { | ||
verify_no_overflow!(u8, checked_sub, unchecked_sub); | ||
} | ||
|
||
#[kani::proof] | ||
fn test_unchecked_mul() { | ||
verify_no_overflow!(u8, checked_mul, unchecked_mul); | ||
} | ||
|
||
#[kani::proof] | ||
fn test_unchecked_div() { | ||
verify_no_overflow!(u8, checked_div, unchecked_div); | ||
} | ||
|
||
#[kani::proof] | ||
fn test_unchecked_rem() { | ||
verify_no_overflow!(u8, checked_rem, unchecked_rem); | ||
} | ||
|
||
#[kani::proof] | ||
fn test_unchecked_shl() { | ||
verify_no_overflow!(u32, checked_shl, unchecked_shl); | ||
} | ||
|
||
#[kani::proof] | ||
fn test_unchecked_shr() { | ||
verify_no_overflow!(u32, checked_shr, unchecked_shr); | ||
} |
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,14 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
// kani-verify-fail | ||
|
||
// Check that `unchecked_rem` triggers overflow checks. | ||
// Covers the case where `a == T::MIN && b == -1`. | ||
#![feature(core_intrinsics)] | ||
|
||
#[kani::proof] | ||
fn main() { | ||
let a: i32 = i32::MIN; | ||
let b: i32 = -1; | ||
unsafe { std::intrinsics::unchecked_rem(a, b) }; | ||
} |
14 changes: 14 additions & 0 deletions
14
tests/kani/Intrinsics/Math/Arith/Unchecked/rem_zero_fail.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,14 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
// kani-verify-fail | ||
|
||
// Check that `unchecked_rem` triggers overflow checks. | ||
// Covers the case where `b == 0`. | ||
#![feature(core_intrinsics)] | ||
|
||
#[kani::proof] | ||
fn main() { | ||
let a: i32 = kani::any(); | ||
let b: i32 = 0; | ||
unsafe { std::intrinsics::unchecked_rem(a, b) }; | ||
} |
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,13 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
// kani-verify-fail | ||
|
||
// Check that `unchecked_shl` triggers overflow checks. | ||
#![feature(core_intrinsics)] | ||
|
||
#[kani::proof] | ||
fn main() { | ||
let a: u32 = kani::any(); | ||
let b: u32 = kani::any(); | ||
unsafe { std::intrinsics::unchecked_shl(a, b) }; | ||
} |
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,13 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
// kani-verify-fail | ||
|
||
// Check that `unchecked_shr` triggers overflow checks. | ||
#![feature(core_intrinsics)] | ||
|
||
#[kani::proof] | ||
fn main() { | ||
let a: u32 = kani::any(); | ||
let b: u32 = kani::any(); | ||
unsafe { std::intrinsics::unchecked_shr(a, b) }; | ||
} |
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,13 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
// kani-verify-fail | ||
|
||
// Check that `unchecked_sub` triggers overflow checks. | ||
#![feature(core_intrinsics)] | ||
|
||
#[kani::proof] | ||
fn main() { | ||
let a: i32 = kani::any(); | ||
let b: i32 = kani::any(); | ||
unsafe { std::intrinsics::unchecked_sub(a, b) }; | ||
} |