From 68185910037d5b172cfe35ed4096bbd79e40ee1a Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Thu, 28 Aug 2025 13:57:11 -0400 Subject: [PATCH] kernel/fs: Add assertions to acquire_vnode and put_vnode. * panic under KDEBUG if the node does not exist. * panic always if the node reference count was 0. We don't handle 0 -> 1 transitions here, and it doesn't make sense to acquire "another" reference to a node you haven't referenced. Would have caught the ext2 use-after-free fixed in an earlier commit. --- src/system/kernel/fs/vfs.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/system/kernel/fs/vfs.cpp b/src/system/kernel/fs/vfs.cpp index 29e4dd2e68..430e292db4 100644 --- a/src/system/kernel/fs/vfs.cpp +++ b/src/system/kernel/fs/vfs.cpp @@ -3864,10 +3864,17 @@ acquire_vnode(fs_volume* volume, ino_t vnodeID) ReadLocker nodeLocker(sVnodeLock); struct vnode* vnode = lookup_vnode(volume->id, vnodeID); - if (vnode == NULL) + if (vnode == NULL) { + KDEBUG_ONLY(panic("acquire_vnode(%p, %" B_PRIdINO "): not found!", volume, vnodeID)); return B_BAD_VALUE; + } + + if (inc_vnode_ref_count(vnode) == 0) { + // It isn't valid to acquire another reference to a vnode that + // you don't already have a reference to, so this should never happen. + panic("acquire_vnode(%p, %" B_PRIdINO "): node wasn't used!", volume, vnodeID); + } - inc_vnode_ref_count(vnode); return B_OK; } @@ -3881,8 +3888,10 @@ put_vnode(fs_volume* volume, ino_t vnodeID) vnode = lookup_vnode(volume->id, vnodeID); rw_lock_read_unlock(&sVnodeLock); - if (vnode == NULL) + if (vnode == NULL) { + KDEBUG_ONLY(panic("put_vnode(%p, %" B_PRIdINO "): not found!", volume, vnodeID)); return B_BAD_VALUE; + } dec_vnode_ref_count(vnode, false, true); return B_OK;