]> git.lizzy.rs Git - rust.git/commitdiff
use new isize_max method in FS accesses; also check full buffers for validity
authorRalf Jung <post@ralfj.de>
Sun, 17 Nov 2019 08:30:32 +0000 (09:30 +0100)
committerRalf Jung <post@ralfj.de>
Sun, 17 Nov 2019 08:54:09 +0000 (09:54 +0100)
src/shims/fs.rs

index 79e57cf2c8f5db79045d6623d5f0f5691c7dc1ad..9291f3a6e3b20d6c1204962b7b41cff49129c7ab 100644 (file)
@@ -3,7 +3,7 @@
 use std::fs::{remove_file, File, OpenOptions};
 use std::io::{Read, Write};
 
-use rustc::ty::layout::Size;
+use rustc::ty::layout::{Size, Align};
 
 use crate::stacked_borrows::Tag;
 use crate::*;
@@ -166,18 +166,20 @@ fn read(
 
         this.check_no_isolation("read")?;
 
-        let ptr_size = this.pointer_size().bits();
-
-        // We cap the number of read bytes to the largest value that we are able to fit in both the
-        // host's and target's `isize`.
+        let fd = this.read_scalar(fd_op)?.to_i32()?;
+        let buf = this.read_scalar(buf_op)?.not_undef()?;
         let count = this
             .read_scalar(count_op)?
-            .to_machine_usize(&*this.tcx)?
-            .min((1 << (ptr_size - 1)) - 1) // max value of target `isize`
-            .min(isize::max_value() as u64);
+            .to_machine_usize(&*this.tcx)?;
 
-        let fd = this.read_scalar(fd_op)?.to_i32()?;
-        let buf = this.read_scalar(buf_op)?.not_undef()?;
+        // Check that the *entire* buffer is actually valid memory.
+        this.memory.check_ptr_access(buf, Size::from_bytes(count), Align::from_bytes(1).unwrap())?;
+
+        // We cap the number of read bytes to the largest value that we are able to fit in both the
+        // host's and target's `isize`. This saves us from having to handle overflows later.
+        let count = count
+            .min(this.isize_max() as u64)
+            .min(isize::max_value() as u64);
 
         if let Some(handle) = this.machine.file_handler.handles.get_mut(&fd) {
             // This can never fail because `count` was capped to be smaller than
@@ -219,18 +221,20 @@ fn write(
 
         this.check_no_isolation("write")?;
 
-        let ptr_size = this.pointer_size().bits();
-
-        // We cap the number of read bytes to the largest value that we are able to fit in both the
-        // host's and target's `isize`.
+        let fd = this.read_scalar(fd_op)?.to_i32()?;
+        let buf = this.read_scalar(buf_op)?.not_undef()?;
         let count = this
             .read_scalar(count_op)?
-            .to_machine_usize(&*this.tcx)?
-            .min((1 << (ptr_size - 1)) - 1) // max value of target `isize`
-            .min(isize::max_value() as u64);
+            .to_machine_usize(&*this.tcx)?;
 
-        let fd = this.read_scalar(fd_op)?.to_i32()?;
-        let buf = this.read_scalar(buf_op)?.not_undef()?;
+        // Check that the *entire* buffer is actually valid memory.
+        this.memory.check_ptr_access(buf, Size::from_bytes(count), Align::from_bytes(1).unwrap())?;
+
+        // We cap the number of written bytes to the largest value that we are able to fit in both the
+        // host's and target's `isize`. This saves us from having to handle overflows later.
+        let count = count
+            .min(this.isize_max() as u64)
+            .min(isize::max_value() as u64);
 
         if let Some(handle) = this.machine.file_handler.handles.get_mut(&fd) {
             let bytes = this.memory.read_bytes(buf, Size::from_bytes(count))?;