Skip to content

Commit fd5e037

Browse files
committed
Auto merge of #3600 - tiif:non-null-posix-memalign, r=RalfJung
Use non-null pointer for size 0 posix memalign Fixes #3576
2 parents 32b2238 + bf5906f commit fd5e037

File tree

6 files changed

+73
-14
lines changed

6 files changed

+73
-14
lines changed

src/tools/miri/src/shims/unix/foreign_items.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -259,16 +259,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
259259
let einval = this.eval_libc_i32("EINVAL");
260260
this.write_int(einval, dest)?;
261261
} else {
262-
if size == 0 {
263-
this.write_null(&ret)?;
264-
} else {
265-
let ptr = this.allocate_ptr(
266-
Size::from_bytes(size),
267-
Align::from_bytes(align).unwrap(),
268-
MiriMemoryKind::C.into(),
269-
)?;
270-
this.write_pointer(ptr, &ret)?;
271-
}
262+
let ptr = this.allocate_ptr(
263+
Size::from_bytes(size),
264+
Align::from_bytes(align).unwrap(),
265+
MiriMemoryKind::C.into(),
266+
)?;
267+
this.write_pointer(ptr, &ret)?;
272268
this.write_null(dest)?;
273269
}
274270
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//@ignore-target-windows: No posix_memalign on Windows
2+
3+
use std::ptr;
4+
5+
fn main() {
6+
let mut ptr: *mut libc::c_void = ptr::null_mut();
7+
let align = 64;
8+
let size = 0;
9+
unsafe {
10+
let _ = libc::posix_memalign(&mut ptr, align, size);
11+
libc::free(ptr);
12+
libc::free(ptr); //~ERROR: dangling
13+
}
14+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling
2+
--> $DIR/posix_memalign_size_zero_double_free.rs:LL:CC
3+
|
4+
LL | libc::free(ptr);
5+
| ^^^^^^^^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling
6+
|
7+
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
8+
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
9+
help: ALLOC was allocated here:
10+
--> $DIR/posix_memalign_size_zero_double_free.rs:LL:CC
11+
|
12+
LL | let _ = libc::posix_memalign(&mut ptr, align, size);
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
14+
help: ALLOC was deallocated here:
15+
--> $DIR/posix_memalign_size_zero_double_free.rs:LL:CC
16+
|
17+
LL | libc::free(ptr);
18+
| ^^^^^^^^^^^^^^^
19+
= note: BACKTRACE (of the first span):
20+
= note: inside `main` at $DIR/posix_memalign_size_zero_double_free.rs:LL:CC
21+
22+
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
23+
24+
error: aborting due to 1 previous error
25+
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//@ignore-target-windows: No posix_memalign on Windows
2+
3+
use std::ptr;
4+
5+
fn main() {
6+
let mut ptr: *mut libc::c_void = ptr::null_mut();
7+
let align = 64;
8+
let size = 0;
9+
let _ = unsafe { libc::posix_memalign(&mut ptr, align, size) }; //~ERROR: memory leak
10+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error: memory leaked: ALLOC (C heap, size: 0, align: 64), allocated here:
2+
--> $DIR/posix_memalign_size_zero_leak.rs:LL:CC
3+
|
4+
LL | let _ = unsafe { libc::posix_memalign(&mut ptr, align, size) };
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: BACKTRACE:
8+
= note: inside `main` at $DIR/posix_memalign_size_zero_leak.rs:LL:CC
9+
10+
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
11+
12+
note: the evaluated program leaked memory, pass `-Zmiri-ignore-leaks` to disable this check
13+
14+
error: aborting due to 1 previous error
15+

src/tools/miri/tests/pass-dep/libc/libc-mem.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -190,11 +190,10 @@ fn test_memalign() {
190190
let align = 64;
191191
let size = 0;
192192
assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0);
193-
// We are not required to return null if size == 0, but we currently do.
194-
// It's fine to remove this assert if we start returning non-null pointers.
195-
assert!(ptr.is_null());
193+
// Non-null pointer is returned if size == 0.
194+
// (This is not a guarantee, it just reflects our current behavior.)
195+
assert!(!ptr.is_null());
196196
assert!(ptr.is_aligned_to(align));
197-
// Regardless of what we return, it must be `free`able.
198197
libc::free(ptr);
199198
}
200199

0 commit comments

Comments
 (0)