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
This commit is contained in:
Mark Johnston 2022-06-20 12:01:09 -04:00
parent a932a5a649
commit 540da48d83

View File

@ -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 @@ kmem_back_domain(int domain, vm_object_t object, vm_offset_t addr,
m->oflags |= VPO_KMEM_EXEC;
}
VM_OBJECT_WUNLOCK(object);
kmem_alloc_san(addr, size, size, flags);
return (KERN_SUCCESS);
}