Skip to content

Commit edd0157

Browse files
committed
Cap count twice
1 parent 6e37f2f commit edd0157

File tree

1 file changed

+12
-2
lines changed

1 file changed

+12
-2
lines changed

src/shims/fs.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,10 +168,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
168168

169169
let ptr_size = this.pointer_size().bits();
170170

171+
// We cap the number of read bytes to the largest value that we are able to fit in both the
172+
// host's and target's `isize`.
171173
let count = this
172174
.read_scalar(count_op)?
173175
.to_machine_usize(&*this.tcx)?
174-
.min(1 << (ptr_size - 1));
176+
.min(1 << (ptr_size - 1))
177+
.min(isize::max_value() as u64);
175178
// Reading zero bytes should not change `buf`.
176179
if count == 0 {
177180
return Ok(0);
@@ -180,6 +183,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
180183
let buf = this.read_scalar(buf_op)?.not_undef()?;
181184

182185
if let Some(handle) = this.machine.file_handler.handles.get_mut(&fd) {
186+
// This can never fail because `count` was capped to be smaller than
187+
// `isize::max_value()`.
183188
let count = isize::try_from(count).unwrap();
184189
// We want to read at most `count` bytes. We are sure that `count` is not negative
185190
// because it was a target's `usize`. Also we are sure that its smaller than
@@ -188,6 +193,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
188193
let result = handle
189194
.file
190195
.read(&mut bytes)
196+
// `File::read` never returns a value larger than `i64::max_value()`, so this
197+
// unwrap cannot fail.
191198
.map(|c| i64::try_from(c).unwrap());
192199

193200
match result {
@@ -218,10 +225,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
218225

219226
let ptr_size = this.pointer_size().bits();
220227

228+
// We cap the number of read bytes to the largest value that we are able to fit in both the
229+
// host's and target's `isize`.
221230
let count = this
222231
.read_scalar(count_op)?
223232
.to_machine_usize(&*this.tcx)?
224-
.min(1 << (ptr_size - 1));
233+
.min(1 << (ptr_size - 1))
234+
.min(isize::max_value() as u64);
225235
// Writing zero bytes should not change `buf`.
226236
if count == 0 {
227237
return Ok(0);

0 commit comments

Comments
 (0)