about summary refs log tree commit diff
diff options
context:
space:
mode:
authortiif <pekyuan@gmail.com>2024-05-12 15:01:18 +0800
committertiif <pekyuan@gmail.com>2024-05-12 15:01:18 +0800
commitbf5906fbb44f8bbe9707bf98ddb4d4705e4b302a (patch)
treef8de9a07acc8ddb016c8fa067629e450609b918c
parent32b22381749163da5a413283561c5c6509c538b4 (diff)
downloadrust-bf5906fbb44f8bbe9707bf98ddb4d4705e4b302a.tar.gz
rust-bf5906fbb44f8bbe9707bf98ddb4d4705e4b302a.zip
Add non-null pointer for posix_memalign
-rw-r--r--src/tools/miri/src/shims/unix/foreign_items.rs16
-rw-r--r--src/tools/miri/tests/fail-dep/libc/posix_memalign_size_zero_double_free.rs14
-rw-r--r--src/tools/miri/tests/fail-dep/libc/posix_memalign_size_zero_double_free.stderr25
-rw-r--r--src/tools/miri/tests/fail-dep/libc/posix_memalign_size_zero_leak.rs10
-rw-r--r--src/tools/miri/tests/fail-dep/libc/posix_memalign_size_zero_leak.stderr15
-rw-r--r--src/tools/miri/tests/pass-dep/libc/libc-mem.rs7
6 files changed, 73 insertions, 14 deletions
diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs
index 08f64e499b5..b5165548d1b 100644
--- a/src/tools/miri/src/shims/unix/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/foreign_items.rs
@@ -259,16 +259,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                     let einval = this.eval_libc_i32("EINVAL");
                     this.write_int(einval, dest)?;
                 } else {
-                    if size == 0 {
-                        this.write_null(&ret)?;
-                    } else {
-                        let ptr = this.allocate_ptr(
-                            Size::from_bytes(size),
-                            Align::from_bytes(align).unwrap(),
-                            MiriMemoryKind::C.into(),
-                        )?;
-                        this.write_pointer(ptr, &ret)?;
-                    }
+                    let ptr = this.allocate_ptr(
+                        Size::from_bytes(size),
+                        Align::from_bytes(align).unwrap(),
+                        MiriMemoryKind::C.into(),
+                    )?;
+                    this.write_pointer(ptr, &ret)?;
                     this.write_null(dest)?;
                 }
             }
diff --git a/src/tools/miri/tests/fail-dep/libc/posix_memalign_size_zero_double_free.rs b/src/tools/miri/tests/fail-dep/libc/posix_memalign_size_zero_double_free.rs
new file mode 100644
index 00000000000..b6b7b007f2b
--- /dev/null
+++ b/src/tools/miri/tests/fail-dep/libc/posix_memalign_size_zero_double_free.rs
@@ -0,0 +1,14 @@
+//@ignore-target-windows: No posix_memalign on Windows
+
+use std::ptr;
+
+fn main() {
+    let mut ptr: *mut libc::c_void = ptr::null_mut();
+    let align = 64;
+    let size = 0;
+    unsafe {
+        let _ = libc::posix_memalign(&mut ptr, align, size);
+        libc::free(ptr);
+        libc::free(ptr); //~ERROR: dangling
+    }
+}
diff --git a/src/tools/miri/tests/fail-dep/libc/posix_memalign_size_zero_double_free.stderr b/src/tools/miri/tests/fail-dep/libc/posix_memalign_size_zero_double_free.stderr
new file mode 100644
index 00000000000..3ed117c5a0a
--- /dev/null
+++ b/src/tools/miri/tests/fail-dep/libc/posix_memalign_size_zero_double_free.stderr
@@ -0,0 +1,25 @@
+error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling
+  --> $DIR/posix_memalign_size_zero_double_free.rs:LL:CC
+   |
+LL |         libc::free(ptr);
+   |         ^^^^^^^^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling
+   |
+   = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
+   = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
+help: ALLOC was allocated here:
+  --> $DIR/posix_memalign_size_zero_double_free.rs:LL:CC
+   |
+LL |         let _ = libc::posix_memalign(&mut ptr, align, size);
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: ALLOC was deallocated here:
+  --> $DIR/posix_memalign_size_zero_double_free.rs:LL:CC
+   |
+LL |         libc::free(ptr);
+   |         ^^^^^^^^^^^^^^^
+   = note: BACKTRACE (of the first span):
+   = note: inside `main` at $DIR/posix_memalign_size_zero_double_free.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/miri/tests/fail-dep/libc/posix_memalign_size_zero_leak.rs b/src/tools/miri/tests/fail-dep/libc/posix_memalign_size_zero_leak.rs
new file mode 100644
index 00000000000..1a4c9605fe0
--- /dev/null
+++ b/src/tools/miri/tests/fail-dep/libc/posix_memalign_size_zero_leak.rs
@@ -0,0 +1,10 @@
+//@ignore-target-windows: No posix_memalign on Windows
+
+use std::ptr;
+
+fn main() {
+    let mut ptr: *mut libc::c_void = ptr::null_mut();
+    let align = 64;
+    let size = 0;
+    let _ = unsafe { libc::posix_memalign(&mut ptr, align, size) }; //~ERROR: memory leak
+}
diff --git a/src/tools/miri/tests/fail-dep/libc/posix_memalign_size_zero_leak.stderr b/src/tools/miri/tests/fail-dep/libc/posix_memalign_size_zero_leak.stderr
new file mode 100644
index 00000000000..7ea0fa31469
--- /dev/null
+++ b/src/tools/miri/tests/fail-dep/libc/posix_memalign_size_zero_leak.stderr
@@ -0,0 +1,15 @@
+error: memory leaked: ALLOC (C heap, size: 0, align: 64), allocated here:
+  --> $DIR/posix_memalign_size_zero_leak.rs:LL:CC
+   |
+LL |     let _ = unsafe { libc::posix_memalign(&mut ptr, align, size) };
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: BACKTRACE:
+   = note: inside `main` at $DIR/posix_memalign_size_zero_leak.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+note: the evaluated program leaked memory, pass `-Zmiri-ignore-leaks` to disable this check
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/miri/tests/pass-dep/libc/libc-mem.rs b/src/tools/miri/tests/pass-dep/libc/libc-mem.rs
index 5df3ace7496..b36fb436b57 100644
--- a/src/tools/miri/tests/pass-dep/libc/libc-mem.rs
+++ b/src/tools/miri/tests/pass-dep/libc/libc-mem.rs
@@ -190,11 +190,10 @@ fn test_memalign() {
         let align = 64;
         let size = 0;
         assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0);
-        // We are not required to return null if size == 0, but we currently do.
-        // It's fine to remove this assert if we start returning non-null pointers.
-        assert!(ptr.is_null());
+        // Non-null pointer is returned if size == 0.
+        // (This is not a guarantee, it just reflects our current behavior.)
+        assert!(!ptr.is_null());
         assert!(ptr.is_aligned_to(align));
-        // Regardless of what we return, it must be `free`able.
         libc::free(ptr);
     }