Skip to content

Commit 2e6216f

Browse files
committed
Fix ICE caused by seeking past i64::MAX
1 parent 314f7f2 commit 2e6216f

File tree

3 files changed

+51
-1
lines changed

3 files changed

+51
-1
lines changed

src/shims/unix/fs.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
395395
// Isolation check is done via `FileDescriptor` trait.
396396

397397
let seek_from = if whence == this.eval_libc_i32("SEEK_SET") {
398-
SeekFrom::Start(u64::try_from(offset).unwrap())
398+
// Be consistent with standard library.
399+
#[allow(clippy::cast_sign_loss)]
400+
SeekFrom::Start(i64::try_from(offset).unwrap() as u64)
399401
} else if whence == this.eval_libc_i32("SEEK_CUR") {
400402
SeekFrom::Current(i64::try_from(offset).unwrap())
401403
} else if whence == this.eval_libc_i32("SEEK_END") {
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//@ignore-target-windows: File handling is not implemented yet
2+
//@compile-flags: -Zmiri-disable-isolation
3+
4+
use std::fs::remove_file;
5+
use std::io::Seek;
6+
use std::panic::catch_unwind;
7+
8+
#[path = "../../utils/mod.rs"]
9+
mod utils;
10+
11+
fn main() {
12+
let path = utils::prepare("miri_test_fs_seek_i64_max_plus_1.txt");
13+
14+
let result = catch_unwind(|| {
15+
let mut f = std::fs::File::create(&path).unwrap();
16+
f.seek(std::io::SeekFrom::Start(i64::MAX as u64 + 1)).unwrap();
17+
});
18+
19+
// Make sure it panics.
20+
assert!(result.is_err());
21+
22+
// Cleanup
23+
remove_file(&path).unwrap();
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
thread 'main' panicked at $DIR/issue-miri-3680.rs:LL:CC:
2+
called `Result::unwrap()` on an `Err` value: Os { code: 22, kind: InvalidInput, message: "invalid input parameter" }
3+
stack backtrace:
4+
0: std::panicking::begin_panic_handler
5+
at RUSTLIB/std/src/panicking.rs:LL:CC
6+
1: core::panicking::panic_fmt
7+
at RUSTLIB/core/src/panicking.rs:LL:CC
8+
2: std::result::unwrap_failed
9+
at RUSTLIB/core/src/result.rs:LL:CC
10+
3: std::result::Result::unwrap
11+
at RUSTLIB/core/src/result.rs:LL:CC
12+
4: main::{closure#0}
13+
at $DIR/issue-miri-3680.rs:LL:CC
14+
5: std::panicking::r#try::do_call
15+
at RUSTLIB/std/src/panicking.rs:LL:CC
16+
6: std::panicking::r#try
17+
at RUSTLIB/std/src/panicking.rs:LL:CC
18+
7: std::panic::catch_unwind
19+
at RUSTLIB/std/src/panic.rs:LL:CC
20+
8: main
21+
at $DIR/issue-miri-3680.rs:LL:CC
22+
9: <fn() as std::ops::FnOnce<()>>::call_once - shim(fn())
23+
at RUSTLIB/core/src/ops/function.rs:LL:CC
24+
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

0 commit comments

Comments
 (0)