From nobody Mon Jun 29 17:13:21 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 4gptCW5gZHz6jW7j for ; Mon, 29 Jun 2026 17:13:27 +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 "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4gptCW0KxXz3nGs for ; Mon, 29 Jun 2026 17:13:27 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1782753207; 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=G8kkaHRrfYPrJLAWLgoDclzjCod6TCW4bHs0kch/yaM=; b=AUnKJL6BGLLdqDk2XENm6bFMoqYNHyuM5pCWy8BwgaQLRVIVXao5kHPzvWAABj2ME+snQS 1BaW12usM3phDunQfdNSOF0R8Tq4Znu9GVF368t4GcfGyHN9IUbhZAEiJwMIxuZtj9kKQb 0jgfy/8+S2FI2IGeM0mgzvcipN2J46SUyimggbp/3FyhpOqdhV4vHKVnG8dx7LkSKPUe70 TYjmqU/clFQJB0ZXoflVk+G/DyMU8eh4UbeFrd4A210DyC8mk/4bNIdeiFlzoUeO4KyWjg B4rzuDd2sZAf9kEoyYNzru4o+CJlso9nhOwY9yvR/XJK0rJkolOABZItCoq1KQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1782753207; a=rsa-sha256; cv=none; b=E11898QndoKm5QFUSTZiX/ssTPQaZQnMzn3CCHmeq/i3p+sNDNj+NuVqTwQ83xOI33pQST KZjsouPo/BArOGjhk7qmXFJu/6ZtFlKIsDuE7Ec1u+nnIqHiD+cJZe2A3jq3UTfHdkJSDF KvfIGIcgRHTWIMOHpVN1v1aeZiHUPCHsCOm4auM23oN/DdRjyHPyZmED7iy0CgJb8Yp7so wVPu4LZWTlKP2dIdiyEZl6eg10IjuWCnacjWEHtaHwli6QDdEsJa4cmF7XpaQZLggEpgC9 lExxmtt4kEQg/VrFV62VmXq05VRDHwEgLyJYlz5YR5TrbTaFRYycbvo+yZxhSw== 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=1782753207; 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=G8kkaHRrfYPrJLAWLgoDclzjCod6TCW4bHs0kch/yaM=; b=p3/8XKFgkjApcPXVSFCUKeyqqkB1hxXRQKbA917qrQdT9eqiZuPjbq0GqqRxF62mMjob3G qpuYfhyYgBQAwLblhc42QKuRbCNFi3ddhyZyUCqg7PoYYZcEuVwxOTQ3fXqyJ1hBULco6A g9/YtXex1v40xeSLaMoYlqUu7y7/DMgxUorwwlvLwcuyX8c8TfAZkoCJQ9h8SfZB9qpYM7 HqI7BqTe7Zz+669RMnp4yMdNbjRPqdh097qrH/uNgydSHroDDDcHpbIwqCK1+eVFpWWCcd zUsWhGrPbQwsvyDEaR43nF4qzI1l5oHCNosQ4nsm8CnBcj48cPOJdx3fUyObTA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4gptCV6988z16Gl for ; Mon, 29 Jun 2026 17:13:26 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 433f9 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Mon, 29 Jun 2026 17:13:21 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Ryan Libby Subject: git: 2407abc9fb3b - main - witness: harden tunables for large settings 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: rlibby X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 2407abc9fb3b45d6d734d564706c76aa793b102a Auto-Submitted: auto-generated Date: Mon, 29 Jun 2026 17:13:21 +0000 Message-Id: <6a42a7b1.433f9.488a2de@gitrepo.freebsd.org> The branch main has been updated by rlibby: URL: https://cgit.FreeBSD.org/src/commit/?id=2407abc9fb3b45d6d734d564706c76aa793b102a commit 2407abc9fb3b45d6d734d564706c76aa793b102a Author: Ryan Libby AuthorDate: 2026-06-29 16:54:30 +0000 Commit: Ryan Libby CommitDate: 2026-06-29 16:54:30 +0000 witness: harden tunables for large settings Harden witness against reasonable tunable settings causing boot panics or scribblers. For now, don't bother to harden this completely. Panics are still achievable by setting the tunables to negative or very large values. The recent change to respect the setting of debug.witness.witness_count (08180f1b613b) exposed that there are no guard rails on that setting, setting it to large but plausible values can cause integer overflow or cause attempted use of memory beyond what is actually available. Add some guard rails, fall back to default configuration if the tuned values are too large, and fall back to a minimum memory allocation if even the defaults are too large. Also don't allow witness to use over half of the memory segment, as there are other early allocators after witness too. Reported by: asomers Reviewed by: kib, markj (previous version) Fixes: 08180f1b613b ("witness: actually set read-only tunables in time for witness_startup") Sponsored by: Dell Inc. Differential Revision: https://reviews.freebsd.org/D57793 --- sys/kern/subr_witness.c | 67 ++++++++++++++++++++++++++++++++++++++++++++----- sys/sys/lock.h | 2 +- sys/vm/vm_page.c | 11 ++++++-- 3 files changed, 71 insertions(+), 9 deletions(-) diff --git a/sys/kern/subr_witness.c b/sys/kern/subr_witness.c index 21d015c4f381..52f8fa51fd25 100644 --- a/sys/kern/subr_witness.c +++ b/sys/kern/subr_witness.c @@ -419,19 +419,16 @@ static u_long witness_count = WITNESS_COUNT; SYSCTL_ULONG(_debug_witness, OID_AUTO, witness_count, CTLFLAG_RDTUN | CTLFLAG_NOFETCH, &witness_count, 0, "Maximum count of lock type entries"); -TUNABLE_ULONG("debug.witness.witness_count", &witness_count); static u_long witness_lo_data_count = WITNESS_LO_DATA_COUNT; SYSCTL_ULONG(_debug_witness, OID_AUTO, lock_order_data_count, CTLFLAG_RDTUN | CTLFLAG_NOFETCH, &witness_lo_data_count, 0, "Maximum count of lock order data (stacks) to track"); -TUNABLE_ULONG("debug.witness.lock_order_data_count", &witness_lo_data_count); static u_long witness_lo_hash_size = WITNESS_LO_HASH_SIZE; SYSCTL_ULONG(_debug_witness, OID_AUTO, lock_order_hash_size, CTLFLAG_RDTUN | CTLFLAG_NOFETCH, &witness_lo_hash_size, 0, "Hash table size for lock order data"); -TUNABLE_ULONG("debug.witness.lock_order_hash_size", &witness_lo_hash_size); /* * Output channel for witness messages. By default we print to the console. @@ -489,6 +486,7 @@ static struct witness *w_data; static uint8_t **w_rmatrix; static struct lock_list_entry w_locklistdata[LOCK_CHILDCOUNT]; static struct witness_hash w_hash; /* The witness hash table. */ +static u_long w_sz; /* Witness startup memory allocation size */ /* The lock order data hash */ static struct witness_lock_order_data *w_lodata; @@ -791,10 +789,10 @@ fixup_filename(const char *file) /* * Calculate the size of early witness structures. */ -int -witness_startup_count(void) +static u_long +witness_startup_calc(void) { - int sz; + u_long sz; sz = sizeof(struct witness) * witness_count; sz += sizeof(*w_rmatrix) * (witness_count + 1); @@ -803,10 +801,65 @@ witness_startup_count(void) sz += sizeof(void *); sz += sizeof(w_lodata[0]) * witness_lo_data_count; sz += sizeof(w_lohash.wloh_array[0]) * witness_lo_hash_size; + sz = round_page(sz); return (sz); } +u_long +witness_startup_count(u_long avail) +{ + + /* + * Tune witness. We make an effort to protect against misconfiguration + * consuming more memory than available, but we do not robustly protect + * against integer overflow for all possible user-supplied values. + */ + TUNABLE_ULONG_FETCH("debug.witness.witness_count", &witness_count); + witness_count = ulmax(witness_count, 1); + TUNABLE_ULONG_FETCH("debug.witness.lock_order_data_count", + &witness_lo_data_count); + TUNABLE_ULONG_FETCH("debug.witness.lock_order_hash_size", + &witness_lo_hash_size); + w_sz = witness_startup_calc(); + if (bootverbose) + printf("WITNESS configuration requests %lu KiB " + "of startup allocations with witness_count=%lu, " + "lock_order_data_count=%lu, lock_order_hash_size=%lu\n", + w_sz / 1024, witness_count, witness_lo_data_count, + witness_lo_hash_size); + if (w_sz <= avail) + return (w_sz); + + /* Memory allocation would be too large, try fallbacks. */ + printf("WARNING: WITNESS configuration requests %lu KiB, " + "with %lu KiB available\n", w_sz / 1024, avail / 1024); + witness_count = ulmin(witness_count, WITNESS_COUNT); + witness_lo_data_count = ulmin(witness_lo_data_count, + WITNESS_LO_DATA_COUNT); + witness_lo_hash_size = ulmin(witness_lo_hash_size, + WITNESS_LO_HASH_SIZE); + w_sz = witness_startup_calc(); + if (w_sz <= avail) { + printf("WARNING: WITNESS configuration reduced to defaults\n"); + return (w_sz); + } + + /* Minimize startup allocations, functionally disabling witness. */ + witness_count = 1; + witness_lo_data_count = 0; + witness_lo_hash_size = 1; + w_sz = witness_startup_calc(); + if (w_sz <= avail) { + printf("WARNING: WITNESS configuration defaults too large, " + "lock order checks disabled\n"); + return (w_sz); + } + + panic("WITNESS unable to initialize with %lu KiB available", + avail / 1024); +} + /* * The WITNESS-enabled diagnostic code. Note that the witness code does * assume that the early boot is single-threaded at least until after this @@ -843,6 +896,8 @@ witness_startup(void *mem) w_lohash.wloh_array = (void *)p; p += sizeof(w_lohash.wloh_array[0]) * witness_lo_hash_size; + MPASS(p <= (uintptr_t)mem + w_sz); + badstack_sbuf_size = witness_count * 256; /* diff --git a/sys/sys/lock.h b/sys/sys/lock.h index 9d81a49ab52a..74e222176b4a 100644 --- a/sys/sys/lock.h +++ b/sys/sys/lock.h @@ -247,7 +247,7 @@ const char *witness_file(struct lock_object *); void witness_thread_exit(struct thread *); #ifdef WITNESS -int witness_startup_count(void); +u_long witness_startup_count(u_long); void witness_startup(void *); /* Flags for witness_warn(). */ diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index 233292bdd6cb..8c953149e6de 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -585,7 +585,7 @@ vm_page_startup(vm_offset_t vaddr) int biggestone, i, segind; #ifdef WITNESS void *mapped; - int witness_size; + u_long witness_size; #endif #if defined(__i386__) && defined(VM_PHYSSEG_DENSE) long ii; @@ -610,7 +610,14 @@ vm_page_startup(vm_offset_t vaddr) new_end = end; #ifdef WITNESS - witness_size = round_page(witness_startup_count()); + /* + * witness(4) support. Allocate and map memory and initialize. + * Advertised available memory is limited in order to avoid witness + * misconfiguration consuming memory needed for subsequent essential + * allocations. + */ + witness_size = round_page(witness_startup_count( + trunc_page((new_end - phys_avail[biggestone]) / 2))); new_end -= witness_size; mapped = pmap_map(&vaddr, new_end, new_end + witness_size, VM_PROT_READ | VM_PROT_WRITE);