git: 7deedba4e586 - stable/14 - uma: New check_align_mask(): Validate alignments (INVARIANTS)

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Thu, 16 Nov 2023 20:54:44 UTC
The branch stable/14 has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=7deedba4e58686ad870767bb29c45235c255937a

commit 7deedba4e58686ad870767bb29c45235c255937a
Author:     Olivier Certner <olce.freebsd@certner.fr>
AuthorDate: 2023-10-13 14:09:51 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2023-11-16 15:07:17 +0000

    uma: New check_align_mask(): Validate alignments (INVARIANTS)
    
    New function check_align_mask() asserts (under INVARIANTS) that the mask
    fits in a (signed) integer (see the comment) and that the corresponding
    alignment is a power of two.
    
    Use check_align_mask() in uma_set_align_mask() and also in uma_zcreate()
    to replace the KASSERT() there (that was checking only for a power of
    2).
    
    Reviewed by:            kib, markj
    MFC after:              2 weeks
    Sponsored by:           The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D42263
    
    (cherry picked from commit 87090f5e5a7b927a2ab30878435f6dcba0705a1d)
---
 sys/vm/uma_core.c | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c
index a27dba4b01f1..661c98b272da 100644
--- a/sys/vm/uma_core.c
+++ b/sys/vm/uma_core.c
@@ -3249,19 +3249,31 @@ uma_kcreate(uma_zone_t zone, size_t size, uma_init uminit, uma_fini fini,
 	return (zone_alloc_item(kegs, &args, UMA_ANYDOMAIN, M_WAITOK));
 }
 
-/* Public functions */
-/* See uma.h */
-void
-uma_set_cache_align_mask(unsigned int mask)
+
+static void
+check_align_mask(unsigned int mask)
 {
 
+	KASSERT(powerof2(mask + 1),
+	    ("UMA: %s: Not the mask of a power of 2 (%#x)", __func__, mask));
 	/*
 	 * Make sure the stored align mask doesn't have its highest bit set,
 	 * which would cause implementation-defined behavior when passing it as
 	 * the 'align' argument of uma_zcreate().  Such very large alignments do
 	 * not make sense anyway.
 	 */
-	uma_cache_align_mask = mask & ~(1U << 31);
+	KASSERT(mask <= INT_MAX,
+	    ("UMA: %s: Mask too big (%#x)", __func__, mask));
+}
+
+/* Public functions */
+/* See uma.h */
+void
+uma_set_cache_align_mask(unsigned int mask)
+{
+
+	check_align_mask(mask);
+	uma_cache_align_mask = mask;
 }
 
 /* Returns the alignment mask to use to request cache alignment. */
@@ -3280,8 +3292,7 @@ uma_zcreate(const char *name, size_t size, uma_ctor ctor, uma_dtor dtor,
 	struct uma_zctor_args args;
 	uma_zone_t res;
 
-	KASSERT(powerof2(align + 1), ("invalid zone alignment %d for \"%s\"",
-	    align, name));
+	check_align_mask(align);
 
 	/* This stuff is essential for the zone ctor */
 	memset(&args, 0, sizeof(args));