diff options
| author | tiif <pekyuan@gmail.com> | 2024-05-12 15:01:18 +0800 |
|---|---|---|
| committer | tiif <pekyuan@gmail.com> | 2024-05-12 15:01:18 +0800 |
| commit | bf5906fbb44f8bbe9707bf98ddb4d4705e4b302a (patch) | |
| tree | f8de9a07acc8ddb016c8fa067629e450609b918c | |
| parent | 32b22381749163da5a413283561c5c6509c538b4 (diff) | |
| download | rust-bf5906fbb44f8bbe9707bf98ddb4d4705e4b302a.tar.gz rust-bf5906fbb44f8bbe9707bf98ddb4d4705e4b302a.zip | |
Add non-null pointer for posix_memalign
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); } |
