-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Why would je_calloc not return zero-initialized memory? #1844
Description
I'm working on a ARM-to-x86 translation layer for android-x86 [1], and I'm facing a really odd behavior whereby je_calloc in the emulated layer returns memory that is not zero-initialized.
The code is based on AOSP/Android-Q, which uses jemalloc from here [2]. The emulation layer is based on QEMU, which operates in user mode, with a minimal ARM-compiled runtime environment and a set of interface libraries that bridge the emulated environment and the native Android OS.
Maybe of importance is that there are 2 versions of jemalloc operating at the same time:
- the regular Android native jemalloc (x86)
- the jemalloc version in the emulated runtime environment (arm)
I've been tracking a series of crashes that all point to the same root cause: at some point during the execution, the emulated code performs a calloc call, but the returned memory is not fully zero-initialized. I've patched libc.so (in the emulated environment) with the following snippet to verify it.
--- a/libc/bionic/malloc_common.cpp
+++ b/libc/bionic/malloc_common.cpp
@@ -67,10 +67,19 @@ extern "C" void* calloc(size_t n_elements, size_t elem_size) {
if (__predict_false(result == nullptr)) {
warning_log("calloc(%zu, %zu) failed: returning null pointer", n_elements, elem_size);
}
+ for (size_t i = 0; i < (n_elements * elem_size); i++) {
+ if (((char*)result)[i] != 0) {
+ warning_log("calloc(%zu, %zu): %p byte %zu is not zero!!! [calloc=%p]", n_elements, elem_size, result, i, Malloc(calloc));
+ break;
+ }
+ }
return result;
}
I would appreciate if you could help me understand in what circumstances such behavior could ever happen?
[1] https://github.com/goffioul/ax86-nb-qemu
[2] https://android.googlesource.com/platform/external/jemalloc_new/+/refs/tags/android-10.0.0_r2