NetBSD Problem Report #59955
From www@netbsd.org Sun Feb 1 20:29:43 2026
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
client-signature RSA-PSS (2048 bits) client-digest SHA256)
(Client CN "mail.netbsd.org", Issuer "R13" (verified OK))
by mollari.NetBSD.org (Postfix) with ESMTPS id 35C411A923D
for <gnats-bugs@gnats.NetBSD.org>; Sun, 1 Feb 2026 20:29:43 +0000 (UTC)
Message-Id: <20260201202941.896A01A923E@mollari.NetBSD.org>
Date: Sun, 1 Feb 2026 20:29:41 +0000 (UTC)
From: campbell+netbsd@mumble.net
Reply-To: campbell+netbsd@mumble.net
To: gnats-bugs@NetBSD.org
Subject: kernel diagnostic assertion "rw_lock_held(&map->lock)" failed: file "/home/riastradh/netbsd/11/src/sys/uvm/uvm_map.c", line 1704
X-Send-Pr-Version: www-1.0
X-From4GNATS: "campbell+netbsd@mumble.net via gnats" <gnats-admin@NetBSD.org>
>Number: 59955
>Category: kern
>Synopsis: kernel diagnostic assertion "rw_lock_held(&map->lock)" failed: file "/home/riastradh/netbsd/11/src/sys/uvm/uvm_map.c", line 1704
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: needs-pullups
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sun Feb 01 20:30:00 +0000 2026
>Closed-Date:
>Last-Modified: Fri May 22 14:35:13 +0000 2026
>Originator: Taylor R Campbell
>Release: 11
>Organization:
The NetUVM Concrashulations, Inc.
>Environment:
>Description:
I started crash(8) and typed `ps', and the system panicked:
[ 598835.709592] panic: kernel diagnostic assertion "rw_lock_held(&map->lock)" failed: file "/home/riastradh/netbsd/11/src/sys/uvm/uvm_map.c", line 1704
[ 598835.709592] cpu1: Begin traceback...
[ 598835.710592] vpanic() at netbsd:vpanic+0x171
[ 598835.712592] kern_assert() at netbsd:kern_assert+0x4b
[ 598835.713592] uvm_map_lookup_entry() at netbsd:uvm_map_lookup_entry+0x99
[ 598835.715592] uvm_map_checkprot() at netbsd:uvm_map_checkprot+0x24
[ 598835.716591] mm_md_kernacc() at netbsd:mm_md_kernacc+0xc5
[ 598835.717591] mm_readwrite() at netbsd:mm_readwrite+0x295
[ 598835.719591] cdev_read() at netbsd:cdev_read+0x87
[ 598835.720592] spec_read() at netbsd:spec_read+0x328
[ 598835.722592] VOP_READ() at netbsd:VOP_READ+0x42
[ 598835.724592] vn_read() at netbsd:vn_read+0x98
[ 598835.726592] dofileread() at netbsd:dofileread+0x79
[ 598835.727592] sys_pread() at netbsd:sys_pread+0x95
[ 598835.729593] syscall() at netbsd:syscall+0x9d
[ 598835.729593] --- syscall (number 173) ---
[ 598835.730593] netbsd:syscall+0x9d:
[ 598835.730593] cpu1: End traceback...
[ 598835.733592] dumping to dev 168,12 (offset=527151, size=16710810):
>From the crash dump in gdb:
(gdb) bt
#0 0xffffffff80239b85 in cpu_reboot (howto=howto@entry=260,
bootstr=bootstr@entry=0x0)
at /home/riastradh/netbsd/11/src/sys/arch/amd64/amd64/machdep.c:709
#1 0xffffffff80ded195 in kern_reboot (howto=howto@entry=260,
bootstr=bootstr@entry=0x0)
at /home/riastradh/netbsd/11/src/sys/kern/kern_reboot.c:91
#2 0xffffffff80e32dc3 in vpanic (
fmt=0xffffffff8162e748 "kernel %sassertion \"%s\" failed: file \"%s\", line %d ", ap=ap@entry=0xffffa41265273ba8)
at /home/riastradh/netbsd/11/src/sys/kern/subr_prf.c:288
#3 0xffffffff81002c9e in kern_assert (
fmt=fmt@entry=0xffffffff8162e748 "kernel %sassertion \"%s\" failed: file \"%s\", line %d ")
at /home/riastradh/netbsd/11/src/sys/lib/libkern/kern_assert.c:51
#4 0xffffffff80d8c1e1 in uvm_map_lookup_entry (
map=map@entry=0xffffffff81ac4800 <module_map_store>,
address=address@entry=18446744071629767768,
entry=entry@entry=0xffffa41265273c38)
at /home/riastradh/netbsd/11/src/sys/uvm/uvm_map.c:1723
#5 0xffffffff80d901d7 in uvm_map_checkprot (
map=0xffffffff81ac4800 <module_map_store>,
start=start@entry=18446744071629767768,
end=end@entry=18446744071629767769, protection=protection@entry=1)
at /home/riastradh/netbsd/11/src/sys/uvm/uvm_map.c:4137
#6 0xffffffff8023a448 in mm_md_kernacc (ptr=ptr@entry=0xffffffff84090458,
prot=prot@entry=1, handled=handled@entry=0xffffa41265273c97)
at /home/riastradh/netbsd/11/src/sys/arch/amd64/amd64/machdep.c:2278
#7 0xffffffff80ed7a7d in dev_kmem_readwrite (iov=<optimized out>,
uio=0xffffa41265273ee0) at /home/riastradh/netbsd/11/src/sys/dev/mm.c:274
#8 mm_readwrite (dev=<optimized out>, uio=0xffffa41265273ee0,
flags=<optimized out>) at /home/riastradh/netbsd/11/src/sys/dev/mm.c:349
#9 0xffffffff80e1d2bc in cdev_read (dev=513,
uio=uio@entry=0xffffa41265273ee0, flag=0)
at /home/riastradh/netbsd/11/src/sys/kern/subr_devsw.c:1499
#10 0xffffffff80ec5132 in spec_read (v=0xffffa41265273e38)
at /home/riastradh/netbsd/11/src/sys/miscfs/specfs/spec_vnops.c:1127
#11 0xffffffff80eb6582 in VOP_READ (vp=vp@entry=0xffff9f662269e080,
uio=uio@entry=0xffffa41265273ee0, ioflag=ioflag@entry=0,
cred=cred@entry=0xffff9f6aee98bc40)
at /home/riastradh/netbsd/11/src/sys/kern/vnode_if.c:785
#12 0xffffffff80ead067 in vn_read (fp=<optimized out>,
offset=0xffffa41265273f68, uio=0xffffa41265273ee0,
cred=0xffff9f6aee98bc40, flags=<optimized out>)
at /home/riastradh/netbsd/11/src/sys/kern/vfs_vnops.c:675
#13 0xffffffff80e46f7d in dofileread (fd=fd@entry=5,
fp=fp@entry=0xffff9f61121327c0, buf=0x7f7fff4c1cf0, nbyte=1,
offset=offset@entry=0xffffa41265273f68, flags=flags@entry=0,
retval=retval@entry=0xffffa41265273fb0)
at /home/riastradh/netbsd/11/src/sys/kern/sys_generic.c:156
#14 0xffffffff80ea1879 in sys_pread (l=<optimized out>,
uap=0xffffa41265274000, retval=0xffffa41265273fb0)
at /home/riastradh/netbsd/11/src/sys/kern/vfs_syscalls.c:3056
#15 0xffffffff805c0ca1 in sy_call (rval=0xffffa41265273fb0,
uap=0xffffa41265274000, l=0xffff9f634ed85400,
sy=0xffffffff81a88af8 <sysent+4152>)
at /home/riastradh/netbsd/11/src/sys/sys/syscallvar.h:65
#16 sy_invoke (code=173, rval=0xffffa41265273fb0, uap=0xffffa41265274000,
l=0xffff9f634ed85400, sy=0xffffffff81a88af8 <sysent+4152>)
at /home/riastradh/netbsd/11/src/sys/sys/syscallvar.h:94
#17 syscall (frame=0xffffa41265274000)
at /home/riastradh/netbsd/11/src/sys/arch/x86/x86/syscall.c:137
#18 0xffffffff8021025d in handle_syscall ()
Relevant excerpt of code:
1679 /*
1680 * uvm_map_lookup_entry: find map entry at or before an address
1681 *
1682 * => map must at least be read-locked by caller.
1683 *
1684 * => If address lies in an entry, set *entry to it and return true;
1685 * then (*entry)->start <= address < (*entry)->end.
1686
1687 * => If address is below all entries in map, return false and set
1688 * *entry to &map->header.
1689 *
1690 * => Otherwise, return false and set *entry to the highest entry below
1691 * address, so (*entry)->end <= address, and if (*entry)->next is
1692 * not &map->header, address < (*entry)->next->start.
1693 */
1694
1695 bool
1696 uvm_map_lookup_entry(struct vm_map *map, vaddr_t address,
1697 struct vm_map_entry **entry /* OUT */)
1698 {
1699 struct vm_map_entry *cur;
1700 UVMHIST_FUNC(__func__);
1701 UVMHIST_CALLARGS(maphist,"(map=%#jx,addr=%#jx,ent=%#jx)",
1702 (uintptr_t)map, address, (uintptr_t)entry, 0);
1703
1704 KASSERT(rw_lock_held(&map->lock));
https://nxr.netbsd.org/xref/src/sys/uvm/uvm_map.c?r=1.427#1704
This is called from:
2240 int
2241 mm_md_kernacc(void *ptr, vm_prot_t prot, bool *handled)
...
2276 if (v >= bootspace.smodule && v < bootspace.emodule) {
2277 *handled = true;
2278 if (!uvm_map_checkprot(module_map, v, v + 1, prot)) {
2279 return EFAULT;
2280 }
2281 } else {
2282 *handled = false;
2283 }
https://nxr.netbsd.org/xref/src/sys/arch/amd64/amd64/machdep.c?r=1.376#2278
But module_map is not locked at this point.
Apparently I added this assertion relatively recently, for:
PR kern/51254: uvm assertion "!topdown || hint <= orig_hint" failed
https://mail-index.netbsd.org/source-changes/2024/08/13/msg152763.html
It's probably not safe to do this without the map lock.
>How-To-Repeat:
Make sure modules are loaded and (insert additional criteria here) and:
# crash
crash> ps
>Fix:
1. Verify this path isn't used by ddb, or allow unlocked access by ddb in the assertion.
2. Take the map lock in mm_md_kernacc.
3. Audit other callers of uvm_map_checkprot.
>Release-Note:
>Audit-Trail:
From: Taylor R Campbell <riastradh@NetBSD.org>
To: gnats-bugs@NetBSD.org, netbsd-bugs@NetBSD.org
Cc: chs@NetBSD.org
Subject: Re: kern/59955: kernel diagnostic assertion "rw_lock_held(&map->lock)" failed: file "/home/riastradh/netbsd/11/src/sys/uvm/uvm_map.c", line 1704
Date: Sun, 1 Feb 2026 20:37:45 +0000
Actually, just taking the read lock in mm_md_kernacc probably isn't
enough, because we really need the access to _remain_ allowed while we
do the uiomove in dev/mm.c. Can we hold the map lock across uiomove?
Sounds unlikely. Can we wire the pages with uvm_vslock or something
across the uvm_map_checkprot and uiomove?
From: Chuck Silvers <chuq@chuq.com>
To: Taylor R Campbell <riastradh@NetBSD.org>
Cc: gnats-bugs@NetBSD.org, netbsd-bugs@NetBSD.org
Subject: Re: kern/59955: kernel diagnostic assertion
"rw_lock_held(&map->lock)" failed: file
"/home/riastradh/netbsd/11/src/sys/uvm/uvm_map.c", line 1704
Date: Sun, 1 Feb 2026 17:55:43 -0800
On Sun, Feb 01, 2026 at 08:37:45PM +0000, Taylor R Campbell wrote:
> Actually, just taking the read lock in mm_md_kernacc probably isn't
> enough, because we really need the access to _remain_ allowed while we
> do the uiomove in dev/mm.c. Can we hold the map lock across uiomove?
> Sounds unlikely. Can we wire the pages with uvm_vslock or something
> across the uvm_map_checkprot and uiomove?
there is no need to call uvm_map_checkprot() here. if uiomove() faults
while trying to access an unmapped address within module_map, it will just
fail with an error, which is what you'd want anyway.
-Chuck
From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/59955 CVS commit: src/sys/arch/amd64/amd64
Date: Sun, 22 Feb 2026 12:14:56 +0000
Module Name: src
Committed By: riastradh
Date: Sun Feb 22 12:14:56 UTC 2026
Modified Files:
src/sys/arch/amd64/amd64: machdep.c
Log Message:
amd64: Fix locking around uvm_map_checkprot in mm_md_kernacc.
This call was originally introduced in sys/arch/amd64/amd64/mem.c
rev. 1.11 back in 2003 by fvdl@ with the commit message:
> Proper checks for kmem reads beyond _end
https://mail-index.netbsd.org/source-changes/2003/10/14/msg135803.html
At some point, SOMEBODY added an assertion in uvm that made it stop
working:
> uvm_map(9): Sprinkle assertions and interface contract comments.
>
> No functional change intended.
https://mail-index.netbsd.org/source-changes/2024/08/13/msg152763.html
(Really, this assertion revealed that this path was broken all along.)
This patch makes the amd64 mm_md_kernacc match the corresponding logic
in uvm_kernacc around uvm_map_checkprot:
104 vm_map_lock_read(kernel_map);
105 rv = uvm_map_checkprot(kernel_map, saddr, eaddr, prot);
106 vm_map_unlock_read(kernel_map);
https://nxr.netbsd.org/xref/src/sys/uvm/uvm_glue.c#92
Now, all of these checks in /dev/mem and company look like TOCTOU
bogosity, because the answers are stale by the time we reach uiomove,
which has to re-check any access anyway:
269 if (!md_kva) {
270 bool checked = false;
271
272 #ifdef __HAVE_MM_MD_KERNACC
273 /* MD check for the address. */
274 error = mm_md_kernacc(addr, prot, &checked);
275 if (error) {
276 return error;
277 }
278 #endif
279 /* UVM check for the address (unless MD indicated to not). */
280 if (!checked && !uvm_kernacc(addr, len, prot)) {
281 return EFAULT;
282 }
283 }
284 error = uiomove(addr, len, uio);
https://nxr.netbsd.org/xref/src/sys/dev/mm.c?r=1.25#269
But we can address that in a separate change.
PR kern/59955: kernel diagnostic assertion "rw_lock_held(&map->lock)"
failed: file "/home/riastradh/netbsd/11/src/sys/uvm/uvm_map.c", line
1704
To generate a diff of this commit:
cvs rdiff -u -r1.378 -r1.379 src/sys/arch/amd64/amd64/machdep.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: "Martin Husemann" <martin@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/59955 CVS commit: [netbsd-11] src/sys/arch/amd64/amd64
Date: Wed, 4 Mar 2026 20:05:59 +0000
Module Name: src
Committed By: martin
Date: Wed Mar 4 20:05:58 UTC 2026
Modified Files:
src/sys/arch/amd64/amd64 [netbsd-11]: machdep.c
Log Message:
Pull up following revision(s) (requested by riastradh in ticket #199):
sys/arch/amd64/amd64/machdep.c: revision 1.379
amd64: Fix locking around uvm_map_checkprot in mm_md_kernacc.
This call was originally introduced in sys/arch/amd64/amd64/mem.c
rev. 1.11 back in 2003 by fvdl@ with the commit message:
Proper checks for kmem reads beyond _end
https://mail-index.netbsd.org/source-changes/2003/10/14/msg135803.html
At some point, SOMEBODY added an assertion in uvm that made it stop
working:
uvm_map(9): Sprinkle assertions and interface contract comments.
No functional change intended.
https://mail-index.netbsd.org/source-changes/2024/08/13/msg152763.html
(Really, this assertion revealed that this path was broken all along.)
This patch makes the amd64 mm_md_kernacc match the corresponding logic
in uvm_kernacc around uvm_map_checkprot:
104 vm_map_lock_read(kernel_map);
105 rv = uvm_map_checkprot(kernel_map, saddr, eaddr, prot);
106 vm_map_unlock_read(kernel_map);
https://nxr.netbsd.org/xref/src/sys/uvm/uvm_glue.c#92
Now, all of these checks in /dev/mem and company look like TOCTOU
bogosity, because the answers are stale by the time we reach uiomove,
which has to re-check any access anyway:
269 if (!md_kva) {
270 bool checked = false;
271
272 #ifdef __HAVE_MM_MD_KERNACC
273 /* MD check for the address. */
274 error = mm_md_kernacc(addr, prot, &checked);
275 if (error) {
276 return error;
277 }
278 #endif
279 /* UVM check for the address (unless MD indicated to not). */
280 if (!checked && !uvm_kernacc(addr, len, prot)) {
281 return EFAULT;
282 }
283 }
284 error = uiomove(addr, len, uio);
https://nxr.netbsd.org/xref/src/sys/dev/mm.c?r=1.25#269
But we can address that in a separate change.
PR kern/59955: kernel diagnostic assertion "rw_lock_held(&map->lock)"
failed: file "/home/riastradh/netbsd/11/src/sys/uvm/uvm_map.c", line
1704
To generate a diff of this commit:
cvs rdiff -u -r1.376 -r1.376.2.1 src/sys/arch/amd64/amd64/machdep.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
State-Changed-From-To: open->needs-pullups
State-Changed-By: riastradh@NetBSD.org
State-Changed-When: Fri, 22 May 2026 14:35:13 +0000
State-Changed-Why:
fixed in HEAD, needs pullup-11, pullup-10, pullup-9
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.51 2026/08/10 02:28:17 riastradh Exp $
$NetBSD: gnats_config.sh,v 1.10 2026/05/13 22:00:09 riastradh Exp $
Copyright © 1994-2026
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.