[Concept,24/37] mcheck: integrate mcheck into dlmalloc.c

Message ID 20251201170529.3237986-25-sjg@u-boot.org
State New
Headers
Series malloc: Import dlmalloc 2.8.6 |

Commit Message

Simon Glass Dec. 1, 2025, 5:05 p.m. UTC
  From: Simon Glass <simon.glass@canonical.com>

Add mcheck wrapper functions for dlmalloc, dlfree, dlrealloc,
dlmemalign, and dlcalloc. When MCHECK_HEAP_PROTECTION is enabled,
these wrappers call the mcheck hooks around the internal *_impl
functions to provide heap corruption detection.

Also add the mcheck() and mprobe() API functions.

Changes from original commit:
- Adapted for dlmalloc 2.8.6 function names (dl* instead of mALLOc)
- Updated function signatures (void* instead of Void_t*)

Signed-off-by: Eugene Uriev <eugeneuriev@gmail.com>
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
(cherry picked from commit 151493a875071448e2582489f6fa84d1630b3368)
---

 common/dlmalloc.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)
  

Patch

diff --git a/common/dlmalloc.c b/common/dlmalloc.c
index 4f88e48f4b0..102b6c2bf8d 100644
--- a/common/dlmalloc.c
+++ b/common/dlmalloc.c
@@ -5591,6 +5591,69 @@  size_t dlmalloc_usable_size(const void* mem) {
   return 0;
 }
 
+#ifdef MCHECK_HEAP_PROTECTION
+#include "mcheck_core.inc.h"
+
+void *dlmalloc(size_t bytes)
+{
+	size_t fullsz = mcheck_alloc_prehook(bytes);
+	void *p = dlmalloc_impl(fullsz);
+
+	if (!p)
+		return p;
+	return mcheck_alloc_posthook(p, bytes);
+}
+
+void dlfree(void *mem) { dlfree_impl(mcheck_free_prehook(mem)); }
+
+void *dlrealloc(void *oldmem, size_t bytes)
+{
+	if (bytes == 0) {
+		if (oldmem)
+			dlfree(oldmem);
+		return NULL;
+	}
+
+	if (oldmem == NULL)
+		return dlmalloc(bytes);
+
+	void *p = mcheck_reallocfree_prehook(oldmem);
+	size_t newsz = mcheck_alloc_prehook(bytes);
+
+	p = dlrealloc_impl(p, newsz);
+	if (!p)
+		return p;
+	return mcheck_alloc_noclean_posthook(p, bytes);
+}
+
+void *dlmemalign(size_t alignment, size_t bytes)
+{
+	return NULL;
+}
+
+/* dlpvalloc, dlvalloc redirect to dlmemalign, so they need no wrapping */
+
+void *dlcalloc(size_t n, size_t elem_size)
+{
+	/* NB: no overflow check here */
+	size_t fullsz = mcheck_alloc_prehook(n * elem_size);
+	void *p = dlcalloc_impl(1, fullsz);
+
+	if (!p)
+		return p;
+	return mcheck_alloc_noclean_posthook(p, n * elem_size);
+}
+
+/* mcheck API */
+int mcheck(mcheck_abortfunc_t f)
+{
+	mcheck_initialize(f, 0);
+	return 0;
+}
+
+enum mcheck_status mprobe(void *__ptr) { return mcheck_mprobe(__ptr); }
+#endif /* MCHECK_HEAP_PROTECTION */
+
 #endif /* !ONLY_MSPACES */
 
 /* ----------------------------- user mspaces ---------------------------- */