git: 540da48d83fc - main - vm_kern: Update KMSAN shadow maps when allocating kmem memory

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Mon, 20 Jun 2022 17:00:28 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=540da48d83fc148c1d34136da34ca8a2985a2a27

commit 540da48d83fc148c1d34136da34ca8a2985a2a27
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2022-06-20 16:01:09 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2022-06-20 16:48:13 +0000

    vm_kern: Update KMSAN shadow maps when allocating kmem memory
    
    This addresses a couple of false positive reports for memory returned by
    malloc_large().
    
    Sponsored by:   The FreeBSD Foundation
---
 sys/vm/vm_kern.c | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c
index 669dc194759b..ac132f8ec0f3 100644
--- a/sys/vm/vm_kern.c
+++ b/sys/vm/vm_kern.c
@@ -77,6 +77,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/kernel.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>
+#include <sys/msan.h>
 #include <sys/proc.h>
 #include <sys/rwlock.h>
 #include <sys/sysctl.h>
@@ -171,6 +172,23 @@ kva_free(vm_offset_t addr, vm_size_t size)
 	vmem_free(kernel_arena, addr, size);
 }
 
+/*
+ * Update sanitizer shadow state to reflect a new allocation.  Force inlining to
+ * help make KMSAN origin tracking more precise.
+ */
+static __always_inline void
+kmem_alloc_san(vm_offset_t addr, vm_size_t size, vm_size_t asize, int flags)
+{
+	if ((flags & M_ZERO) == 0) {
+		kmsan_mark((void *)addr, asize, KMSAN_STATE_UNINIT);
+		kmsan_orig((void *)addr, asize, KMSAN_TYPE_KMEM,
+		    KMSAN_RET_ADDR);
+	} else {
+		kmsan_mark((void *)addr, asize, KMSAN_STATE_INITED);
+	}
+	kasan_mark((void *)addr, size, asize, KASAN_KMEM_REDZONE);
+}
+
 static vm_page_t
 kmem_alloc_contig_pages(vm_object_t object, vm_pindex_t pindex, int domain,
     int pflags, u_long npages, vm_paddr_t low, vm_paddr_t high,
@@ -249,7 +267,7 @@ kmem_alloc_attr_domain(int domain, vm_size_t size, int flags, vm_paddr_t low,
 		    prot | PMAP_ENTER_WIRED, 0);
 	}
 	VM_OBJECT_WUNLOCK(object);
-	kasan_mark((void *)addr, size, asize, KASAN_KMEM_REDZONE);
+	kmem_alloc_san(addr, size, asize, flags);
 	return (addr);
 }
 
@@ -332,7 +350,7 @@ kmem_alloc_contig_domain(int domain, vm_size_t size, int flags, vm_paddr_t low,
 		tmp += PAGE_SIZE;
 	}
 	VM_OBJECT_WUNLOCK(object);
-	kasan_mark((void *)addr, size, asize, KASAN_KMEM_REDZONE);
+	kmem_alloc_san(addr, size, asize, flags);
 	return (addr);
 }
 
@@ -511,7 +529,7 @@ retry:
 			m->oflags |= VPO_KMEM_EXEC;
 	}
 	VM_OBJECT_WUNLOCK(object);
-
+	kmem_alloc_san(addr, size, size, flags);
 	return (KERN_SUCCESS);
 }