]> git.lizzy.rs Git - rust.git/commitdiff
Only check futex pointer in futex_wait and not in futex_wake.
authorMara Bos <m-ou.se@m-ou.se>
Thu, 1 Oct 2020 20:57:27 +0000 (22:57 +0200)
committerMara Bos <m-ou.se@m-ou.se>
Thu, 1 Oct 2020 20:57:27 +0000 (22:57 +0200)
futex_wake doesn't access the futex itself, so should accept pointers to
memory that's no longer there.

src/shims/posix/linux/sync.rs

index 23d3330c74e9e45ab3d3057b31eb537eb92f7d8c..d92fc0441c49d9b7ae2e3a7327a72894ca800687 100644 (file)
@@ -10,14 +10,12 @@ pub fn futex<'tcx>(
     if args.len() < 4 {
         throw_ub_format!("incorrect number of arguments for futex syscall: got {}, expected at least 4", args.len());
     }
-    let addr = this.read_scalar(args[1])?.check_init()?;
+    let addr = args[1];
+    let addr_scalar = this.read_scalar(addr)?.check_init()?;
+    let futex_ptr = this.force_ptr(addr_scalar)?.erase_tag();
     let op = this.read_scalar(args[2])?.to_i32()?;
     let val = this.read_scalar(args[3])?.to_i32()?;
 
-    this.memory.check_ptr_access(addr, Size::from_bytes(4), Align::from_bytes(4).unwrap())?;
-
-    let addr = addr.assert_ptr().erase_tag();
-
     let thread = this.get_active_thread();
 
     let futex_private = this.eval_libc_i32("FUTEX_PRIVATE_FLAG")?;
@@ -33,10 +31,11 @@ pub fn futex<'tcx>(
             if !this.is_null(timeout)? {
                 throw_ub_format!("miri does not support timeouts for futex operations");
             }
+            this.memory.check_ptr_access(addr_scalar, Size::from_bytes(4), Align::from_bytes(4).unwrap())?;
             let futex_val = this.read_scalar_at_offset(args[1], 0, this.machine.layouts.i32)?.to_i32()?;
             if val == futex_val {
                 this.block_thread(thread);
-                this.futex_wait(addr, thread);
+                this.futex_wait(futex_ptr, thread);
             } else {
                 let eagain = this.eval_libc("EAGAIN")?;
                 this.set_last_error(eagain)?;
@@ -45,7 +44,7 @@ pub fn futex<'tcx>(
         op if op == futex_wake => {
             let mut n = 0;
             for _ in 0..val {
-                if let Some(thread) = this.futex_wake(addr) {
+                if let Some(thread) = this.futex_wake(futex_ptr) {
                     this.unblock_thread(thread);
                     n += 1;
                 } else {