Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 24 Jul 2026 22:36:25 +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: 666eab3afc52 - main - uma: Avoid allocating from free buckets when KASAN is enabled
Message-ID:  <6a63e8e9.189b3.7fcf0923@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=666eab3afc52bf20d57c24e98a6aa667433fb7c2

commit 666eab3afc52bf20d57c24e98a6aa667433fb7c2
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2026-07-24 21:12:21 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-07-24 21:12:21 +0000

    uma: Avoid allocating from free buckets when KASAN is enabled
    
    When uma_zalloc_arg() hits an empty alloc bucket in the per-CPU cache,
    it tries swapping the alloc and free buckets in the hope that the free
    bucket has some items available.  If not, it has to lock the zone.
    
    Disable this behaviour when KASAN is configured in order to further
    defer reuse of freed items.  This forces a free item to go to the
    per-domain full bucket cache before it becomes accessible to the
    allocator.
    
    Reviewed by:    rlibby
    MFC after:      1 month
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D58270
---
 sys/vm/uma_core.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c
index fb72fafe9abc..e5f7d92a4f2a 100644
--- a/sys/vm/uma_core.c
+++ b/sys/vm/uma_core.c
@@ -3782,6 +3782,7 @@ static __noinline bool
 cache_alloc(uma_zone_t zone, uma_cache_t cache, void *udata, int flags)
 {
 	uma_bucket_t bucket;
+	uint32_t zflags;
 	int curdomain, domain;
 	bool new;
 
@@ -3791,10 +3792,15 @@ cache_alloc(uma_zone_t zone, uma_cache_t cache, void *udata, int flags)
 	 * If we have run out of items in our alloc bucket see
 	 * if we can switch with the free bucket.
 	 *
-	 * SMR Zones can't re-use the free bucket until the sequence has
-	 * expired.
+	 * SMR zones can't re-use the free bucket until the sequence has
+	 * expired.  When KASAN is enabled, we want to avoid re-using free
+	 * items in order to improve reliability of use-after-free detection.
 	 */
-	if ((cache_uz_flags(cache) & UMA_ZONE_SMR) == 0 &&
+	zflags = cache_uz_flags(cache);
+	if ((zflags & UMA_ZONE_SMR) == 0 &&
+#ifdef KASAN
+	    (zflags & UMA_ZONE_NOKASAN) != 0 &&
+#endif
 	    cache->uc_freebucket.ucb_cnt != 0) {
 		cache_bucket_swap(&cache->uc_freebucket,
 		    &cache->uc_allocbucket);
@@ -3823,8 +3829,7 @@ cache_alloc(uma_zone_t zone, uma_cache_t cache, void *udata, int flags)
 	 * the critical section.
 	 */
 	domain = PCPU_GET(domain);
-	if ((cache_uz_flags(cache) & UMA_ZONE_ROUNDROBIN) != 0 ||
-	    VM_DOMAIN_EMPTY(domain))
+	if ((zflags & UMA_ZONE_ROUNDROBIN) != 0 || VM_DOMAIN_EMPTY(domain))
 		domain = zone_domain_highest(zone, domain);
 	bucket = cache_fetch_bucket(zone, cache, domain);
 	if (bucket == NULL && zone->uz_bucket_size != 0 && !bucketdisable) {
@@ -3849,7 +3854,7 @@ cache_alloc(uma_zone_t zone, uma_cache_t cache, void *udata, int flags)
 	critical_enter();
 	cache = &zone->uz_cpu[curcpu];
 	if (cache->uc_allocbucket.ucb_bucket == NULL &&
-	    ((cache_uz_flags(cache) & UMA_ZONE_FIRSTTOUCH) == 0 ||
+	    ((zflags & UMA_ZONE_FIRSTTOUCH) == 0 ||
 	    (curdomain = PCPU_GET(domain)) == domain ||
 	    VM_DOMAIN_EMPTY(curdomain))) {
 		if (new)


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a63e8e9.189b3.7fcf0923>