Auto merge of #3689 - adwinwhite:lseek64, r=RalfJung

Fix ICE caused by seeking past `i64::MAX`

Make Miri behave the same as standard library on file seeking offset.

Fixes #3680.
This commit is contained in:
bors 2024-06-21 09:44:08 +00:00
commit 4be2c66c42
2 changed files with 29 additions and 1 deletions

View file

@ -395,7 +395,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Isolation check is done via `FileDescriptor` trait.
let seek_from = if whence == this.eval_libc_i32("SEEK_SET") {
SeekFrom::Start(u64::try_from(offset).unwrap())
if offset < 0 {
// Negative offsets return `EINVAL`.
let einval = this.eval_libc("EINVAL");
this.set_last_error(einval)?;
return Ok(Scalar::from_i64(-1));
} else {
SeekFrom::Start(u64::try_from(offset).unwrap())
}
} else if whence == this.eval_libc_i32("SEEK_CUR") {
SeekFrom::Current(i64::try_from(offset).unwrap())
} else if whence == this.eval_libc_i32("SEEK_END") {

View file

@ -0,0 +1,21 @@
//@ignore-target-windows: File handling is not implemented yet
//@compile-flags: -Zmiri-disable-isolation
use std::fs::remove_file;
use std::io::{ErrorKind, Seek};
#[path = "../../utils/mod.rs"]
mod utils;
fn main() {
let path = utils::prepare("miri_test_fs_seek_i64_max_plus_1.txt");
let mut f = std::fs::File::create(&path).unwrap();
let error = f.seek(std::io::SeekFrom::Start(i64::MAX as u64 + 1)).unwrap_err();
// It should be error due to negative offset.
assert_eq!(error.kind(), ErrorKind::InvalidInput);
// Cleanup
remove_file(&path).unwrap();
}