From 3fe37e36faa6c76dd0e4b5051a9a59ec6a0bc140 Mon Sep 17 00:00:00 2001 From: David Carlier <devnexen@gmail.com> Date: Sun, 26 Mar 2023 08:33:30 +0100 Subject: [PATCH] reallocarray introduction available on glibc 2.26. allocates an array of m*n elements but checking for overflow. --- src/header/stdlib/mod.rs | 16 ++++++++++++++++ tests/expected/bins_static/stdlib/alloc.stdout | 2 ++ tests/stdlib/alloc.c | 16 ++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/src/header/stdlib/mod.rs b/src/header/stdlib/mod.rs index ee39ae05..59d6de50 100644 --- a/src/header/stdlib/mod.rs +++ b/src/header/stdlib/mod.rs @@ -812,6 +812,22 @@ pub unsafe extern "C" fn realloc(ptr: *mut c_void, size: size_t) -> *mut c_void new_ptr } +#[no_mangle] +pub unsafe extern "C" fn reallocarray(ptr: *mut c_void, m: size_t, n: size_t) -> *mut c_void { + //Handle possible integer overflow in size calculation + match m.checked_mul(n) { + Some(size) => { + realloc(ptr, size) + } + None => { + // For overflowing multiplication, we have to set errno here + platform::errno = ENOMEM; + ptr::null_mut() + + } + } +} + #[no_mangle] pub unsafe extern "C" fn realpath(pathname: *const c_char, resolved: *mut c_char) -> *mut c_char { let ptr = if resolved.is_null() { diff --git a/tests/expected/bins_static/stdlib/alloc.stdout b/tests/expected/bins_static/stdlib/alloc.stdout index e59a48d0..02ecd201 100644 --- a/tests/expected/bins_static/stdlib/alloc.stdout +++ b/tests/expected/bins_static/stdlib/alloc.stdout @@ -7,6 +7,8 @@ calloc (overflowing): pointer: (nil), error value: 12 = Out of memory realloc (size 0): (OK) realloc: pointer: (not NULL), error value: 0 = Success realloc (SIZE_MAX): pointer: (nil), error value: 12 = Out of memory +reallocarray: pointer: (not NULL), error value: 0 = Success +reallocarray (SIZE_MAX): pointer: (nil), error value: 12 = Out of memory memalign (size 0): (OK) memalign: pointer: (alignment OK), error value: 0 = Success memalign (SIZE_MAX): pointer: (nil), error value: 12 = Out of memory diff --git a/tests/stdlib/alloc.c b/tests/stdlib/alloc.c index 36660363..f15149b5 100644 --- a/tests/stdlib/alloc.c +++ b/tests/stdlib/alloc.c @@ -165,6 +165,22 @@ int main(void) { printf("realloc (SIZE_MAX): "); test_cannot_alloc(ptr_realloc_maxsize, realloc_maxsize_errno); free(ptr_realloc_maxsize); + + errno = 0; + char * ptr_reallocarray_maxsize = (char *)malloc(sample_alloc_size); + ptr_reallocarray_maxsize = (char *)reallocarray(ptr_reallocarray_maxsize, 2, sample_alloc_size); + int reallocarray_errno = errno; + printf("reallocarray: "); + test_non_null(ptr_reallocarray_maxsize, reallocarray_errno); + for(i = 0; i < sample_realloc_size; i++) { + ptr_realloc[i] = (char)i; + } + errno = 0; + ptr_reallocarray_maxsize = (char *)reallocarray(ptr_reallocarray_maxsize, 2, max_size); + reallocarray_errno = errno; + printf("reallocarray (SIZE_MAX): "); + test_cannot_alloc(ptr_reallocarray_maxsize, reallocarray_errno); + free(ptr_reallocarray_maxsize); errno = 0; char * ptr_memalign_size0 = (char *)memalign(aligned_alloc_alignment, zero_size); -- GitLab