Skip to content

Commit

Permalink
make realloc with a size of zero fail
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed Apr 18, 2024
1 parent da8c5dd commit e8c5dc4
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 5 deletions.
6 changes: 4 additions & 2 deletions src/shims/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
let this = self.eval_context_mut();
let new_align = this.min_align(new_size, kind);
if this.ptr_is_null(old_ptr)? {
// Here we must behave like `malloc`.
if new_size == 0 {
Ok(Pointer::null())
} else {
Expand All @@ -287,8 +288,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
}
} else {
if new_size == 0 {
this.deallocate_ptr(old_ptr, None, kind.into())?;
Ok(Pointer::null())
// C, in their infinite wisdom, made this UB.
// <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2464.pdf>
throw_ub_format!("`realloc` with a size of zero");
} else {
let new_ptr = this.reallocate_ptr(
old_ptr,
Expand Down
10 changes: 10 additions & 0 deletions tests/fail-dep/realloc-zero.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//@ignore-target-windows: No libc on Windows

fn main() {
unsafe {
let p1 = libc::malloc(20);
// C made this UB...
let p2 = libc::realloc(p1, 0); //~ERROR: `realloc` with a size of zero
assert!(p2.is_null());
}
}
15 changes: 15 additions & 0 deletions tests/fail-dep/realloc-zero.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error: Undefined Behavior: `realloc` with a size of zero
--> $DIR/realloc-zero.rs:LL:CC
|
LL | let p2 = libc::realloc(p1, 0);
| ^^^^^^^^^^^^^^^^^^^^ `realloc` with a size of zero
|
= 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
= note: BACKTRACE:
= note: inside `main` at $DIR/realloc-zero.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

5 changes: 2 additions & 3 deletions tests/pass-dep/malloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,8 @@ fn main() {
}

unsafe {
let p1 = libc::malloc(20);

let p2 = libc::realloc(p1, 0);
// Realloc with size 0 is okay for the null pointer
let p2 = libc::realloc(ptr::null_mut(), 0);
assert!(p2.is_null());
}

Expand Down

0 comments on commit e8c5dc4

Please sign in to comment.