Skip to content

Commit

Permalink
Auto merge of #3600 - tiif:non-null-posix-memalign, r=RalfJung
Browse files Browse the repository at this point in the history
Use non-null pointer for size 0 posix memalign

Fixes #3576
  • Loading branch information
bors committed May 12, 2024
2 parents 24fc363 + e1222e3 commit cda82c7
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 14 deletions.
16 changes: 6 additions & 10 deletions src/shims/unix/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)?;
}
}
Expand Down
14 changes: 14 additions & 0 deletions tests/fail-dep/libc/posix_memalign_size_zero_double_free.rs
Original file line number Diff line number Diff line change
@@ -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
}
}
25 changes: 25 additions & 0 deletions tests/fail-dep/libc/posix_memalign_size_zero_double_free.stderr
Original file line number Diff line number Diff line change
@@ -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

10 changes: 10 additions & 0 deletions tests/fail-dep/libc/posix_memalign_size_zero_leak.rs
Original file line number Diff line number Diff line change
@@ -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
}
15 changes: 15 additions & 0 deletions tests/fail-dep/libc/posix_memalign_size_zero_leak.stderr
Original file line number Diff line number Diff line change
@@ -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

7 changes: 3 additions & 4 deletions tests/pass-dep/libc/libc-mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down

0 comments on commit cda82c7

Please sign in to comment.