diff options
| author | Ralf Jung <post@ralfj.de> | 2025-07-19 13:16:42 +0200 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2025-07-19 15:39:04 +0200 |
| commit | 8acdee7bab65254f7cfc8f5e03ad180e65a45e9b (patch) | |
| tree | 38f48adfd2b01d417280586112b3c5818f278214 | |
| parent | eef454f89be3c48ba9ef3853054b16c800eabefc (diff) | |
| download | rust-8acdee7bab65254f7cfc8f5e03ad180e65a45e9b.tar.gz rust-8acdee7bab65254f7cfc8f5e03ad180e65a45e9b.zip | |
don't halt execution when we write to a read-only file
| -rw-r--r-- | src/tools/miri/src/shims/files.rs | 11 | ||||
| -rw-r--r-- | src/tools/miri/tests/pass/shims/fs.rs | 4 |
2 files changed, 14 insertions, 1 deletions
diff --git a/src/tools/miri/src/shims/files.rs b/src/tools/miri/src/shims/files.rs index 606d1ffbea6..f7419b6bca2 100644 --- a/src/tools/miri/src/shims/files.rs +++ b/src/tools/miri/src/shims/files.rs @@ -1,7 +1,7 @@ use std::any::Any; use std::collections::BTreeMap; use std::fs::{File, Metadata}; -use std::io::{IsTerminal, Seek, SeekFrom, Write}; +use std::io::{ErrorKind, IsTerminal, Seek, SeekFrom, Write}; use std::marker::CoercePointee; use std::ops::Deref; use std::rc::{Rc, Weak}; @@ -334,6 +334,15 @@ impl FileDescription for FileHandle { ) -> InterpResult<'tcx> { assert!(communicate_allowed, "isolation should have prevented even opening a file"); + if !self.writable { + // Linux hosts return EBADF here which we can't translate via the platform-independent + // code since it does not map to any `io::ErrorKind` -- so if we don't do anything + // special, we'd throw an "unsupported error code" here. Windows returns something that + // gets translated to `PermissionDenied`. That seems like a good value so let's just use + // this everywhere, even if it means behavior on Unix targets does not match the real + // thing. + return finish.call(ecx, Err(ErrorKind::PermissionDenied.into())); + } let result = ecx.write_to_host(&self.file, len, ptr)?; finish.call(ecx, result) } diff --git a/src/tools/miri/tests/pass/shims/fs.rs b/src/tools/miri/tests/pass/shims/fs.rs index 9d5725773e6..5e54cc38238 100644 --- a/src/tools/miri/tests/pass/shims/fs.rs +++ b/src/tools/miri/tests/pass/shims/fs.rs @@ -66,6 +66,10 @@ fn test_file() { assert!(!file.is_terminal()); + // Writing to a file opened for reading should error (and not stop interpretation). std does not + // categorize the error so we don't check for details. + file.write(&[]).unwrap_err(); + // Removing file should succeed. remove_file(&path).unwrap(); } |
