make realloc with a size of zero fail

This commit is contained in:
Ralf Jung 2024-04-18 10:32:44 +02:00
parent 5697f731b4
commit 73e333ac44
4 changed files with 31 additions and 5 deletions

View file

@ -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 {
@ -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,

View file

@ -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());
}
}

View file

@ -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

View file

@ -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());
}