Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 1 Nov 2021 14:33:04 GMT
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 9710b74dd0f4 - stable/13 - malloc: Add state transitions for KASAN
Message-ID:  <202111011433.1A1EX4Qr021466@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=9710b74dd0f46c58a603c0bee7fad7f5bc71a80f

commit 9710b74dd0f46c58a603c0bee7fad7f5bc71a80f
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2021-04-13 21:40:27 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2021-11-01 14:03:36 +0000

    malloc: Add state transitions for KASAN
    
    - Reuse some REDZONE bits to keep track of the requested and allocated
      sizes, and use that to provide red zones.
    - As in UMA, disable memory trashing to avoid unnecessary CPU overhead.
    
    Sponsored by:   The FreeBSD Foundation
    
    (cherry picked from commit 06a53ecf24005b3a74b85ecc4b504a401ac26cd0)
---
 sys/kern/kern_malloc.c | 44 +++++++++++++++++++++++++++++++-------------
 1 file changed, 31 insertions(+), 13 deletions(-)

diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c
index 8f371d35f066..6adb16c95528 100644
--- a/sys/kern/kern_malloc.c
+++ b/sys/kern/kern_malloc.c
@@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/asan.h>
 #include <sys/kdb.h>
 #include <sys/kernel.h>
 #include <sys/lock.h>
@@ -110,7 +111,7 @@ dtrace_malloc_probe_func_t __read_mostly	dtrace_malloc_probe;
 #define	MALLOC_DEBUG	1
 #endif
 
-#ifdef DEBUG_REDZONE
+#if defined(KASAN) || defined(DEBUG_REDZONE)
 #define	DEBUG_REDZONE_ARG_DEF	, unsigned long osize
 #define	DEBUG_REDZONE_ARG	, osize
 #else
@@ -603,11 +604,12 @@ malloc_large(size_t *size, struct malloc_type *mtp, struct domainset *policy,
 	if (__predict_false(va == NULL)) {
 		KASSERT((flags & M_WAITOK) == 0,
 		    ("malloc(M_WAITOK) returned NULL"));
-	}
+	} else {
 #ifdef DEBUG_REDZONE
-	if (va != NULL)
 		va = redzone_setup(va, osize);
 #endif
+		kasan_mark((void *)va, osize, sz, KASAN_MALLOC_REDZONE);
+	}
 	return (va);
 }
 
@@ -633,7 +635,7 @@ void *
 	int indx;
 	caddr_t va;
 	uma_zone_t zone;
-#ifdef DEBUG_REDZONE
+#if defined(DEBUG_REDZONE) || defined(KASAN)
 	unsigned long osize = size;
 #endif
 
@@ -664,6 +666,10 @@ void *
 #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);
 #endif
 	return ((void *) va);
 }
@@ -699,7 +705,7 @@ malloc_domainset(size_t size, struct malloc_type *mtp, struct domainset *ds,
 	caddr_t va;
 	int domain;
 	int indx;
-#ifdef DEBUG_REDZONE
+#if defined(KASAN) || defined(DEBUG_REDZONE)
 	unsigned long osize = size;
 #endif
 
@@ -727,6 +733,10 @@ malloc_domainset(size_t size, struct malloc_type *mtp, struct domainset *ds,
 #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);
 #endif
 	return (va);
 }
@@ -745,7 +755,7 @@ void *
 malloc_domainset_exec(size_t size, struct malloc_type *mtp, struct domainset *ds,
     int flags)
 {
-#ifdef DEBUG_REDZONE
+#if defined(DEBUG_REDZONE) || defined(KASAN)
 	unsigned long osize = size;
 #endif
 #ifdef MALLOC_DEBUG
@@ -824,7 +834,7 @@ mallocarray_domainset(size_t nmemb, size_t size, struct malloc_type *type,
 	return (malloc_domainset(size * nmemb, type, ds, flags));
 }
 
-#ifdef INVARIANTS
+#if defined(INVARIANTS) && !defined(KASAN)
 static void
 free_save_type(void *addr, struct malloc_type *mtp, u_long size)
 {
@@ -905,7 +915,7 @@ free(void *addr, struct malloc_type *mtp)
 
 	if (__predict_true(!malloc_large_slab(slab))) {
 		size = zone->uz_size;
-#ifdef INVARIANTS
+#if defined(INVARIANTS) && !defined(KASAN)
 		free_save_type(addr, mtp, size);
 #endif
 		uma_zfree_arg(zone, addr, slab);
@@ -945,13 +955,15 @@ zfree(void *addr, struct malloc_type *mtp)
 
 	if (__predict_true(!malloc_large_slab(slab))) {
 		size = zone->uz_size;
-#ifdef INVARIANTS
+#if defined(INVARIANTS) && !defined(KASAN)
 		free_save_type(addr, mtp, size);
 #endif
+		kasan_mark(addr, size, size, 0);
 		explicit_bzero(addr, size);
 		uma_zfree_arg(zone, addr, slab);
 	} else {
 		size = malloc_large_size(slab);
+		kasan_mark(addr, size, size, 0);
 		explicit_bzero(addr, size);
 		free_large(addr, size);
 	}
@@ -1006,16 +1018,22 @@ realloc(void *addr, size_t size, struct malloc_type *mtp, int flags)
 		alloc = malloc_large_size(slab);
 
 	/* Reuse the original block if appropriate */
-	if (size <= alloc
-	    && (size > (alloc >> REALLOC_FRACTION) || alloc == MINALLOCSIZE))
+	if (size <= alloc &&
+	    (size > (alloc >> REALLOC_FRACTION) || alloc == MINALLOCSIZE)) {
+		kasan_mark((void *)addr, size, alloc, KASAN_MALLOC_REDZONE);
 		return (addr);
+	}
 #endif /* !DEBUG_REDZONE */
 
 	/* Allocate a new, bigger (or smaller) block */
 	if ((newaddr = malloc(size, mtp, flags)) == NULL)
 		return (NULL);
 
-	/* Copy over original contents */
+	/*
+	 * Copy over original contents.  For KASAN, the redzone must be marked
+	 * valid before performing the copy.
+	 */
+	kasan_mark(addr, size, size, 0);
 	bcopy(addr, newaddr, min(size, alloc));
 	free(addr, mtp);
 	return (newaddr);
@@ -1216,7 +1234,7 @@ mallocinit(void *dummy)
 		for (subzone = 0; subzone < numzones; subzone++) {
 			kmemzones[indx].kz_zone[subzone] =
 			    uma_zcreate(name, size,
-#ifdef INVARIANTS
+#if defined(INVARIANTS) && !defined(KASAN)
 			    mtrash_ctor, mtrash_dtor, mtrash_init, mtrash_fini,
 #else
 			    NULL, NULL, NULL, NULL,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202111011433.1A1EX4Qr021466>