Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 31 Jul 2026 13:29:24 +0000
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 459aa032e872 - main - malloc: Refactor redzone and sanitizer handling
Message-ID:  <6a6ca334.1990d.4d2bf785@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=459aa032e87275ebe10847592ea2ddea0c3ed693

commit 459aa032e87275ebe10847592ea2ddea0c3ed693
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2026-07-31 12:55:59 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-07-31 12:55:59 +0000

    malloc: Refactor redzone and sanitizer handling
    
    malloc_large() duplicates redzone and KASAN handling that is also
    present in malloc() and malloc_domainset().  Refactor the
    implementations to reduce this a bit.
    
    Also normalize KMSAN map handling: make malloc() and malloc_domainset()
    consistent, and do not update the KMSAN shadow map, as we can rely on
    UMA and kmem_malloc() to handle that.
    
    Reviewed by:    rlibby
    MFC after:      3 weeks
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D58272
---
 sys/kern/kern_malloc.c | 136 +++++++++++++++++++------------------------------
 1 file changed, 52 insertions(+), 84 deletions(-)

diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c
index fcbfbe64f854..0be0a417e19c 100644
--- a/sys/kern/kern_malloc.c
+++ b/sys/kern/kern_malloc.c
@@ -108,14 +108,6 @@ dtrace_malloc_probe_func_t __read_mostly	dtrace_malloc_probe;
 #define	MALLOC_DEBUG	1
 #endif
 
-#if defined(KASAN) || defined(DEBUG_REDZONE)
-#define	DEBUG_REDZONE_ARG_DEF	, unsigned long osize
-#define	DEBUG_REDZONE_ARG	, osize
-#else
-#define	DEBUG_REDZONE_ARG_DEF
-#define	DEBUG_REDZONE_ARG
-#endif
-
 typedef	enum {
 	SLAB_COOKIE_SLAB_PTR		= 0x0,
 	SLAB_COOKIE_MALLOC_LARGE	= 0x1,
@@ -541,7 +533,7 @@ contigfree(void *addr, unsigned long size __unused, struct malloc_type *type)
 
 #ifdef MALLOC_DEBUG
 static int
-malloc_dbg(caddr_t *vap, size_t *sizep, struct malloc_type *mtp,
+malloc_dbg(void **vap, size_t *sizep, struct malloc_type *mtp,
     int flags)
 {
 	KASSERT(mtp->ks_version == M_VERSION, ("malloc: bad malloc type version"));
@@ -611,12 +603,13 @@ malloc_large_size(uma_slab_t slab)
 }
 
 static caddr_t __noinline
-malloc_large(size_t size, struct malloc_type *mtp, struct domainset *policy,
-    int flags DEBUG_REDZONE_ARG_DEF)
+malloc_large(size_t *sizep, struct malloc_type *mtp, struct domainset *policy,
+    int flags)
 {
 	void *va;
+	size_t size;
 
-	size = roundup(size, PAGE_SIZE);
+	size = roundup(*sizep, PAGE_SIZE);
 	va = kmem_malloc_domainset(policy, size, flags);
 	if (va != NULL) {
 		/* Use low bits unused for slab pointers. */
@@ -624,15 +617,7 @@ malloc_large(size_t size, struct malloc_type *mtp, struct domainset *policy,
 		uma_total_inc(size);
 	}
 	malloc_type_allocated(mtp, va == NULL ? 0 : size);
-	if (__predict_false(va == NULL)) {
-		KASSERT((flags & M_WAITOK) == 0,
-		    ("malloc(M_WAITOK) returned NULL"));
-	} else {
-#ifdef DEBUG_REDZONE
-		va = redzone_setup(va, osize);
-#endif
-		kasan_mark(va, osize, size, KASAN_MALLOC_REDZONE);
-	}
+	*sizep = size;
 	return (va);
 }
 
@@ -657,13 +642,14 @@ free_large(void *addr, size_t size)
 void *
 (malloc)(size_t size, struct malloc_type *mtp, int flags)
 {
-	int indx;
-	caddr_t va;
 	uma_zone_t zone;
+	void *va;
+	int indx;
 #if defined(DEBUG_REDZONE) || defined(KASAN)
 	unsigned long osize = size;
 #endif
 
+	/* We don't want to handle this rare case in a hot path. */
 	MPASS((flags & M_EXEC) == 0);
 
 #ifdef MALLOC_DEBUG
@@ -672,36 +658,34 @@ void *
 		return (va);
 #endif
 
-	if (__predict_false(size > kmem_zmax))
-		return (malloc_large(size, mtp, DOMAINSET_RR(), flags
-		    DEBUG_REDZONE_ARG));
-
-	if (size & KMEM_ZMASK)
-		size = (size & ~KMEM_ZMASK) + KMEM_ZBASE;
-	indx = kmemsize[size >> KMEM_ZSHIFT];
-	zone = kmemzones[indx].kz_zone[mtp_get_subzone(mtp)];
-	va = uma_zalloc_arg(zone, zone, flags);
-	if (va != NULL) {
-		size = zone->uz_size;
-		if ((flags & M_ZERO) == 0) {
-			kmsan_mark(va, size, KMSAN_STATE_UNINIT);
-			kmsan_orig(va, size, KMSAN_TYPE_MALLOC, KMSAN_RET_ADDR);
-		}
-	}
-	malloc_type_zone_allocated(mtp, va == NULL ? 0 : size, indx);
-	if (__predict_false(va == NULL)) {
-		KASSERT((flags & M_WAITOK) == 0,
-		    ("malloc(M_WAITOK) returned NULL"));
+	if (__predict_false(size > kmem_zmax)) {
+		va = malloc_large(&size, mtp, DOMAINSET_RR(), flags);
+	} else {
+		if (size & KMEM_ZMASK)
+			size = (size & ~KMEM_ZMASK) + KMEM_ZBASE;
+		indx = kmemsize[size >> KMEM_ZSHIFT];
+		zone = kmemzones[indx].kz_zone[mtp_get_subzone(mtp)];
+		va = uma_zalloc_arg(zone, zone, flags);
+		if (va != NULL)
+			size = zone->uz_size;
+		malloc_type_zone_allocated(mtp, va == NULL ? 0 : size, indx);
 	}
+	KASSERT(va != NULL || (flags & M_WAITOK) == 0,
+	    ("malloc(M_WAITOK) returned NULL"));
+
 #ifdef DEBUG_REDZONE
 	if (va != NULL)
 		va = redzone_setup(va, osize);
 #endif
 #ifdef KASAN
 	if (va != NULL)
-		kasan_mark((void *)va, osize, size, KASAN_MALLOC_REDZONE);
+		kasan_mark(va, osize, size, KASAN_MALLOC_REDZONE);
+#endif
+#ifdef KMSAN
+	if (va != NULL && (flags & M_ZERO) == 0)
+		kmsan_orig(va, size, KMSAN_TYPE_MALLOC, KMSAN_RET_ADDR);
 #endif
-	return ((void *) va);
+	return (va);
 }
 
 static void *
@@ -732,50 +716,49 @@ malloc_domainset(size_t size, struct malloc_type *mtp, struct domainset *ds,
     int flags)
 {
 	struct vm_domainset_iter di;
-	caddr_t va;
+	void *va;
 	int domain;
-	int indx;
 #if defined(KASAN) || defined(DEBUG_REDZONE)
 	unsigned long osize = size;
 #endif
 
-	MPASS((flags & M_EXEC) == 0);
-
 #ifdef MALLOC_DEBUG
 	va = NULL;
 	if (malloc_dbg(&va, &size, mtp, flags) != 0)
 		return (va);
 #endif
 
-	if (__predict_false(size > kmem_zmax))
-		return (malloc_large(size, mtp, DOMAINSET_RR(), flags
-		    DEBUG_REDZONE_ARG));
-
-	indx = -1;
-	va = NULL;
-	if (vm_domainset_iter_policy_init(&di, ds, &domain, &flags) == 0)
-		do {
-			va = malloc_domain(&size, &indx, mtp, domain, flags);
-		} while (va == NULL && vm_domainset_iter_policy(&di, &domain) == 0);
-	malloc_type_zone_allocated(mtp, va == NULL ? 0 : size, indx);
-
-	if (__predict_false(va == NULL)) {
-		KASSERT((flags & M_WAITOK) == 0,
-		    ("malloc(M_WAITOK) returned NULL"));
+	if (__predict_false(size > kmem_zmax || (flags & M_EXEC) != 0)) {
+		va = malloc_large(&size, mtp, DOMAINSET_RR(), flags);
+	} else {
+		int indx;
+
+		indx = -1;
+		va = NULL;
+		if (vm_domainset_iter_policy_init(&di, ds, &domain,
+		    &flags) == 0) {
+			do {
+				va = malloc_domain(&size, &indx, mtp, domain,
+				    flags);
+			} while (va == NULL &&
+			    vm_domainset_iter_policy(&di, &domain) == 0);
+		}
+		malloc_type_zone_allocated(mtp, va == NULL ? 0 : size, indx);
 	}
+	KASSERT(va != NULL || (flags & M_WAITOK) == 0,
+	    ("malloc(M_WAITOK) returned NULL"));
+
 #ifdef DEBUG_REDZONE
 	if (va != NULL)
 		va = redzone_setup(va, osize);
 #endif
 #ifdef KASAN
 	if (va != NULL)
-		kasan_mark((void *)va, osize, size, KASAN_MALLOC_REDZONE);
+		kasan_mark(va, osize, size, KASAN_MALLOC_REDZONE);
 #endif
 #ifdef KMSAN
-	if ((flags & M_ZERO) == 0) {
-		kmsan_mark(va, size, KMSAN_STATE_UNINIT);
+	if (va != NULL && (flags & M_ZERO) == 0)
 		kmsan_orig(va, size, KMSAN_TYPE_MALLOC, KMSAN_RET_ADDR);
-	}
 #endif
 	return (va);
 }
@@ -794,22 +777,7 @@ void *
 malloc_domainset_exec(size_t size, struct malloc_type *mtp, struct domainset *ds,
     int flags)
 {
-#if defined(DEBUG_REDZONE) || defined(KASAN)
-	unsigned long osize = size;
-#endif
-#ifdef MALLOC_DEBUG
-	caddr_t va;
-#endif
-
-	flags |= M_EXEC;
-
-#ifdef MALLOC_DEBUG
-	va = NULL;
-	if (malloc_dbg(&va, &size, mtp, flags) != 0)
-		return (va);
-#endif
-
-	return (malloc_large(size, mtp, ds, flags DEBUG_REDZONE_ARG));
+	return (malloc_domainset(size, mtp, ds, flags | M_EXEC));
 }
 
 void *


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a6ca334.1990d.4d2bf785>