The branch main has been updated by markj:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=06a53ecf24005b3a74b85ecc4b504a401ac26cd0

commit 06a53ecf24005b3a74b85ecc4b504a401ac26cd0
Author:     Mark Johnston <ma...@freebsd.org>
AuthorDate: 2021-04-13 21:40:27 +0000
Commit:     Mark Johnston <ma...@freebsd.org>
CommitDate: 2021-04-13 21:42:21 +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.
    
    MFC after:      2 weeks
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D29461
---
 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 7aa9bf79180c..e2a05c004637 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
@@ -815,7 +825,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)
 {
@@ -896,7 +906,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);
@@ -936,13 +946,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);
        }
@@ -997,16 +1009,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);
@@ -1207,7 +1225,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,
_______________________________________________
dev-commits-src-main@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-main
To unsubscribe, send any mail to "dev-commits-src-main-unsubscr...@freebsd.org"

Reply via email to