On Thu, Sep 05, 2024 at 09:00:09AM +0200, Anton Lindqvist wrote:
> On Wed, Sep 04, 2024 at 11:00:08AM -0600, Bob Beck wrote:
> > CVSROOT:    /cvs
> > Module name:        src
> > Changes by: [email protected]    2024/09/04 11:00:08
> > 
> > Modified files:
> >     sys/ufs/ufs    : ufs_ihash.c 
> > 
> > Log message:
> > Work around vnode reuse bug resulting in a panic: vop_generic_badop
> > 
> > Joel hit this frequently on the go builder, and this was
> > also found by szykiller
> > 
> > https://syzkaller.appspot.com/bug?extid=58bdde9f7a1a407514a7
> > https://syzkaller.appspot.com/bug?extid=5779bc64fc4fdd0a5140
> > 
> > This is based on a workaround originally done by visa@ and mbuhl@
> > but not committed or widely distributed.
> > 
> > Realistically this should be fixed more like the previous attempt
> > with vdoom, but my attempts to do this at the moment are colliding
> > with finding all sources of similar races, now that kernel unlocking
> > is exposing these previously existing bugs
> > 
> > for now, let's put in this ugly workaround
> > 
> > ok deraadt@
> 
> This causes regress/sys/fileops/ext2 to hang, I haven't made further
> progress to see if other filesystems are also affected. Looks like the
> thread is stuck in the kernel inside this new loop.

Not proud but this is a possible fix. 

-- 
:wq Claudio

diff --git sys/ufs/ufs/ufs_ihash.c sys/ufs/ufs/ufs_ihash.c
index b0d6ca3a5dd..744a9320fa3 100644
--- sys/ufs/ufs/ufs_ihash.c
+++ sys/ufs/ufs/ufs_ihash.c
@@ -42,6 +42,7 @@
 #include <ufs/ufs/inode.h>
 #include <ufs/ufs/ufs_extern.h>
 #include <ufs/ufs/ufsmount.h>
+#include <ufs/ext2fs/ext2fs_extern.h>
 
 #include <crypto/siphash.h>
 
@@ -109,7 +110,11 @@ loop:
                        * dealt with so this can't happen.
                        */
                        if (VTOI(vp) != ip ||
-                           (DIP(ip, nlink) <= 0 &&
+                           ((
+#ifdef EXT2FS
+                           IS_EXT2_VNODE(ip->i_vnode) ? ip->i_e2fs_nlink <= 0 :
+#endif
+                           DIP(ip, nlink) <= 0) &&
                             (vp->v_mount->mnt_flag & MNT_RDONLY) == 0)) {
                                /*
                                 * This should recycle the inode immediately,

Reply via email to