NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/57005



The following reply was made to PR kern/57005; it has been noted by GNATS.

From: Rudra Pratap Singh <rudra.singh.offset%gmail.com@localhost>
To: gnats-bugs%netbsd.org@localhost
Cc: tech-kern%netbsd.org@localhost
Subject: Re: kern/57005
Date: Thu, 26 Mar 2026 10:41:18 +0530

 Hi,
 
 PR kern/57005 reports that ufs_rmdir calls cache_purge(dvp) which
 expands to cache_purge1(dvp, NULL, 0, PURGE_PARENTS|PURGE_CHILDREN),
 purging all namecache entries in the parent directory and its parent,
 when only the single removed entry needs to go.
 
 The fix is to replace cache_purge(dvp) with cache_purge1(dvp,
 cnp->cn_nameptr, cnp->cn_namelen, 0) which evicts only the specific
 entry being deleted. The same issue exists in ulfs_vnops.c,
 ext2fs_vnops.c, msdosfs_vnops.c and tmpfs_vnops.c and is fixed here
 too.
 
 dholland noted cn_nameptr might be trashed at that point. I traced the
 call chain: the path buffer is allocated in do_sys_unlinkat
 (vfs_syscalls.c) and freed at line 2977 only after VOP_RMDIR returns.
 None of the calls inside each rmdir function before cache_purge(dvp)
 receive cnp itself as a pointer. Per vnode_if.src, cnp is marked IN
 only for vop_rmdir with no ownership transfer.
 
 Note: dholland also mentioned rename has the same issue. This patch
 addresses rmdir only; rename can follow separately.
 
 
 
 
 
 
 Index: sys/ufs/ufs/ufs_vnops.c
 
 ===================================================================
 
 RCS file: /cvsroot/src/sys/ufs/ufs/ufs_vnops.c,v
 
 retrieving revision 1.264
 
 diff -u -r1.264 ufs_vnops.c
 
 --- sys/ufs/ufs/ufs_vnops.c     22 Jan 2026 03:24:19 -0000      1.264
 
 +++ sys/ufs/ufs/ufs_vnops.c     25 Mar 2026 23:41:43 -0000
 
 @@ -1451,7 +1451,7 @@
 
                 UFS_WAPBL_END(dvp->v_mount);
 
                 goto out;
 
         }
 
 -       cache_purge(dvp);
 
 +       cache_purge1(dvp, cnp->cn_nameptr, cnp->cn_namelen, 0);
 
         /*
 
          * Truncate inode.  The only stuff left in the directory is "." and
 
          * "..".  The "." reference is inconsequential since we're quashing
 
 Index: sys/ufs/lfs/ulfs_vnops.c
 
 ===================================================================
 
 RCS file: /cvsroot/src/sys/ufs/lfs/ulfs_vnops.c,v
 
 retrieving revision 1.56
 
 diff -u -r1.56 ulfs_vnops.c
 
 --- sys/ufs/lfs/ulfs_vnops.c    27 Mar 2022 16:24:59 -0000      1.56
 
 +++ sys/ufs/lfs/ulfs_vnops.c    25 Mar 2026 23:41:43 -0000
 
 @@ -735,7 +735,7 @@
 
         if (error) {
 
                 goto out;
 
         }
 
 -       cache_purge(dvp);
 
 +       cache_purge1(dvp, cnp->cn_nameptr, cnp->cn_namelen, 0);
 
         /*
 
          * Truncate inode.  The only stuff left in the directory is "." and
 
          * "..".  The "." reference is inconsequential since we're quashing
 
 Index: sys/ufs/ext2fs/ext2fs_vnops.c
 
 ===================================================================
 
 RCS file: /cvsroot/src/sys/ufs/ext2fs/ext2fs_vnops.c,v
 
 retrieving revision 1.139
 
 diff -u -r1.139 ext2fs_vnops.c
 
 --- sys/ufs/ext2fs/ext2fs_vnops.c       29 Jan 2024 18:27:09 -0000      1.139
 
 +++ sys/ufs/ext2fs/ext2fs_vnops.c       25 Mar 2026 23:41:44 -0000
 
 @@ -795,7 +795,7 @@
 
         if (dp->i_e2fs_nlink != EXT2FS_LINK_INF)
 
                 dp->i_e2fs_nlink--;
 
         dp->i_flag |= IN_CHANGE;
 
 -       cache_purge(dvp);
 
 +       cache_purge1(dvp, cnp->cn_nameptr, cnp->cn_namelen, 0);
 
         /*
 
          * Truncate inode.  The only stuff left
 
          * in the directory is "." and "..".  The
 
 Index: sys/fs/msdosfs/msdosfs_vnops.c
 
 ===================================================================
 
 RCS file: /cvsroot/src/sys/fs/msdosfs/msdosfs_vnops.c,v
 
 retrieving revision 1.113
 
 diff -u -r1.113 msdosfs_vnops.c
 
 --- sys/fs/msdosfs/msdosfs_vnops.c      11 Sep 2024 00:27:54 -0000      1.113
 
 +++ sys/fs/msdosfs/msdosfs_vnops.c      25 Mar 2026 23:41:44 -0000
 
 @@ -925,7 +925,7 @@
 
          * directory.  Since dos filesystems don't do this we just purge
 
          * the name cache and let go of the parent directory denode.
 
          */
 
 -       cache_purge(dvp);
 
 +       cache_purge1(dvp, cnp->cn_nameptr, cnp->cn_namelen, 0);
 
         /*
 
          * Truncate the directory that is being deleted.
 
          */
 
 Index: sys/fs/tmpfs/tmpfs_vnops.c
 
 ===================================================================
 
 RCS file: /cvsroot/src/sys/fs/tmpfs/tmpfs_vnops.c,v
 
 retrieving revision 1.150
 
 diff -u -r1.150 tmpfs_vnops.c
 
 --- sys/fs/tmpfs/tmpfs_vnops.c  1 Jun 2022 08:42:38 -0000       1.150
 
 +++ sys/fs/tmpfs/tmpfs_vnops.c  25 Mar 2026 23:41:44 -0000
 
 @@ -912,7 +912,7 @@
 
         tmpfs_dir_detach(dnode, de);
 
 
         /* Purge the cache for parent. */
 
 -       cache_purge(dvp);
 
 +       cache_purge1(dvp, ap->a_cnp->cn_nameptr, ap->a_cnp->cn_namelen, 0);
 
 
         /*
 
          * Destroy the directory entry or replace it with a whiteout.
 
 
 
 --
 Rudra Pratap Singh
 



Home | Main Index | Thread Index | Old Index