From nobody Mon Aug 24 16:29:49 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4hTGbL2MVxz6pbJf for ; Mon, 24 Aug 2026 16:29:50 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR2" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hTGbL0fgfz416t for ; Mon, 24 Aug 2026 16:29:50 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1787588990; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=tgU6AH6XIxLEPTpfMsbsvzfhPrsQzacHCxw+hGSDnI0=; b=gbHUUlYsAQr0J70JgalatEO91qcPr1mRASxzctkAoQI5e1fWrMjlHcgg1uvbBizdWUyYyF S5R0qRxZvxynF3+YZYikUhYJo2frYFK8w5SBGY2Qfq5sUWRl08KWxG6REgjjOr5q10BJya zB/9DXPRm2Kp4THy7ZJ1mbMJzjLPl+EQB7tPubgtOBbT1//uEO0vf3Gan63muF3Qk1DiKg K2zJ1+3rjHH/Eul4yWuk8Yaq8jLFsZ5bEipGVLIE+752Q5EVdVVAycgH0KBek26PE53yPN 48sj2krOrcjn7smSEqNfqzji1DdAE6CgIh1sJNkWO1wr7s9MDBXCuXIlnM0dhw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1787588990; a=rsa-sha256; cv=none; b=XdTHHvQh+/tVzB41y1KA0PUetlE4hoB8hJ39Lt8XHGrebb5r/rj3Ewd+NKoHAJ7oW8QqXA prDa2WUSvnMXGICbKZAFylC2gOt+vTWDInX46fXNibZByRjwPwpzYXxwCaI+C2a/sBTfvz ipZZyUZtIsWIkU7U07fVf4O9TQyR6yrIDlTR3DNp6skG5SFEEsrKJ9FCoACu/cIYA8WsyG ZsUUgyKCcOHgS8lakbDKfjHDyihLVgtJ1PDTlZJZHXtNqplmt1H+Ftq9hWRD51ExxDLEPW IFj/GxbzdW07vFGqYvxqClvXYSRyDOFDLxOoPJt0u78gAgA8sC0yg9FvIsZOQQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1787588990; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=tgU6AH6XIxLEPTpfMsbsvzfhPrsQzacHCxw+hGSDnI0=; b=PSaAKp/qA9PvhVnt456CKtPD1lFfgkjlWCL808bi8G5ecC1uRxCU5c1algHKtkEORDXzad y8WJEIoNqJRhX/RETozChycPTW/rcAYkwQd+9AJBz4Y0AAdCkLiII06ZYlkh2D20ShDKKc 8TvrwFY74o3yFthAqJ0X3kN/xlU4Ds5OYVKbftIhGzKigeSXGDixkbmET24ExufWAKvkVC 8uqef/4hmsdlFEJEBMmPGXbock3ROzaLZTQ7cSjKJ/p2hUoyYBQFAnDFsKXUzZOWrAlcZb 2HbF7CUxH8cxLa68wCifPtigmqNfF9p1202qGy6K1/kGpMTOZeLFEOLVfAp74w== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hTGbK6mjlz1Bcd for ; Mon, 24 Aug 2026 16:29:49 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 2248c by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Mon, 24 Aug 2026 16:29:49 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Mark Johnston Subject: git: 4400dcf2b1eb - stable/15 - uma: Insert KASAN redzones after slab-allocated items List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: markj X-Git-Repository: src X-Git-Refname: refs/heads/stable/15 X-Git-Reftype: branch X-Git-Commit: 4400dcf2b1eb3b54b55efdf9e27cac139c66717a Auto-Submitted: auto-generated Date: Mon, 24 Aug 2026 16:29:49 +0000 Message-Id: <6a8c717d.2248c.67d10b3f@gitrepo.freebsd.org> The branch stable/15 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=4400dcf2b1eb3b54b55efdf9e27cac139c66717a commit 4400dcf2b1eb3b54b55efdf9e27cac139c66717a Author: Mark Johnston AuthorDate: 2026-07-31 12:55:48 +0000 Commit: Mark Johnston CommitDate: 2026-08-24 15:17:54 +0000 uma: Insert KASAN redzones after slab-allocated items Without this, KASAN has the deficiency that inter-object overflows are not detected most of the time[*] when keg_layout() is able to perfectly pack a slab. Try to overcome this by adjusting the allocation size to include a redzone following the object. With this change, we automatically get a redzone following each item, so any overflow into the redzone will trigger a panic. Most of UMA doesn't need to know about this: at slab allocation time, the whole slab is poisoned, and then kasan_mark_item_valid() will unpoison only the buffer that is available to the consumer. Note that in most zones, most objects will follow another object's redzone, so there is some protection against underflow as well. It might be worthwhile to provide a stronger guarantee here. Add an assertion to item_ctor() that the returned item is properly aligned. I couldn't see any pre-existing checks which verify this. Reviewed by: rlibby MFC after: 2 weeks Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D58271 (cherry picked from commit f51a5e1d9c415d97b86f0f2c8da9cc9ad9dc683b) --- sys/vm/uma_core.c | 60 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c index b80b5cc781f7..a1930b1d2d8b 100644 --- a/sys/vm/uma_core.c +++ b/sys/vm/uma_core.c @@ -538,9 +538,6 @@ bucket_zone_drain(int domain) } #ifdef KASAN -_Static_assert(UMA_SMALLEST_UNIT % KASAN_SHADOW_SCALE == 0, - "Base UMA allocation size not a multiple of the KASAN scale factor"); - static void kasan_mark_item_valid(uma_zone_t zone, void *item) { @@ -605,7 +602,7 @@ kasan_mark_slab_invalid(uma_keg_t keg, void *mem) sz = keg->uk_ppera * PAGE_SIZE; else sz = keg->uk_pgoff; - kasan_mark(mem, 0, sz, KASAN_UMA_FREED); + kasan_mark(mem, 0, sz, KASAN_GENERIC_REDZONE); } } #else /* !KASAN */ @@ -2255,8 +2252,8 @@ struct keg_layout_result { }; static void -keg_layout_one(uma_keg_t keg, u_int rsize, u_int slabsize, u_int fmt, - struct keg_layout_result *kl) +keg_layout_one(uma_keg_t keg, u_int size, u_int rsize, u_int slabsize, + u_int fmt, struct keg_layout_result *kl) { u_int total; @@ -2269,7 +2266,7 @@ keg_layout_one(uma_keg_t keg, u_int rsize, u_int slabsize, u_int fmt, kl->slabsize += PAGE_SIZE; } - kl->ipers = slab_ipers_hdr(keg->uk_size, rsize, kl->slabsize, + kl->ipers = slab_ipers_hdr(size, rsize, kl->slabsize, (fmt & UMA_ZFLAG_OFFPAGE) == 0); /* Account for memory used by an offpage slab header. */ @@ -2298,7 +2295,7 @@ keg_layout(uma_keg_t keg) u_int alignsize; u_int nfmt; u_int pages; - u_int rsize; + u_int size, rsize; u_int slabsize; u_int i, j; @@ -2314,21 +2311,33 @@ keg_layout(uma_keg_t keg) PRINT_UMA_ZFLAGS)); alignsize = keg->uk_align + 1; -#ifdef KASAN + /* - * ASAN requires that each allocation be aligned to the shadow map - * scale factor. + * Calculate the size of each allocation. uk_size is the originally + * requested item size that the consumer expects to use. "size" is the + * requested size after adjusting for an optional redzone after each + * item (currently used only by KASAN). rsize is the final size between + * item start addresses after adjusting for alignment and minimum + * allocation size requirements. + * + * The padding given by the difference rsize - size may not be present + * for the last item in a slab. */ - if (alignsize < KASAN_SHADOW_SCALE) - alignsize = KASAN_SHADOW_SCALE; + size = keg->uk_size; + +#ifdef KASAN + if ((keg->uk_flags & UMA_ZONE_NOKASAN) == 0) { + /* + * kasan_mark() requires that each allocation be aligned to the + * shadow map scale factor. + */ + if (alignsize < KASAN_SHADOW_SCALE) + alignsize = KASAN_SHADOW_SCALE; + size += KASAN_SHADOW_SCALE; + } #endif - /* - * Calculate the size of each allocation (rsize) according to - * alignment. If the requested size is smaller than we have - * allocation bits for we round it up. - */ - rsize = MAX(keg->uk_size, UMA_SMALLEST_UNIT); + rsize = MAX(size, UMA_SMALLEST_UNIT); rsize = roundup2(rsize, alignsize); if ((keg->uk_flags & UMA_ZONE_CACHESPREAD) != 0) { @@ -2350,7 +2359,7 @@ keg_layout(uma_keg_t keg) * represent a single item. We will try to fit as many * additional items into the slab as possible. */ - slabsize = round_page(keg->uk_size); + slabsize = round_page(size); } /* Build a list of all of the available formats for this keg. */ @@ -2387,13 +2396,13 @@ keg_layout(uma_keg_t keg) * for small items (up to PAGE_SIZE), the iteration increment is one * page; and for large items, the increment is one item. */ - i = (slabsize + rsize - keg->uk_size) / MAX(PAGE_SIZE, rsize); + i = (slabsize + rsize - size) / MAX(PAGE_SIZE, rsize); KASSERT(i >= 1, ("keg %s(%p) flags=0x%b slabsize=%u, rsize=%u, i=%u", keg->uk_name, keg, keg->uk_flags, PRINT_UMA_ZFLAGS, slabsize, rsize, i)); for ( ; ; i++) { slabsize = (rsize <= PAGE_SIZE) ? ptoa(i) : - round_page(rsize * (i - 1) + keg->uk_size); + round_page(rsize * (i - 1) + size); for (j = 0; j < nfmt; j++) { /* Only if we have no viable format yet. */ @@ -2401,7 +2410,8 @@ keg_layout(uma_keg_t keg) kl.ipers > 0) continue; - keg_layout_one(keg, rsize, slabsize, fmts[j], &kl_tmp); + keg_layout_one(keg, size, rsize, slabsize, fmts[j], + &kl_tmp); if (kl_tmp.eff <= kl.eff) continue; @@ -3494,6 +3504,10 @@ item_ctor(uma_zone_t zone, int uz_flags, int size, void *udata, int flags, bool skipdbg; #endif + KASSERT(zone->uz_keg == NULL || + ((uintptr_t)item & zone->uz_keg->uk_align) == 0, + ("item_ctor: underaligned item %p from %s", item, zone->uz_name)); + kasan_mark_item_valid(zone, item); kmsan_mark_item_uninitialized(zone, item);