Module Name:    src
Committed By:   perseant
Date:           Mon Sep  9 05:01:57 UTC 2024

Modified Files:
        src/sys/fs/exfatfs [perseant-exfatfs]: exfatfs_inode.h exfatfs_vnops.c

Log Message:
Add a flag XI_DELETED to mark a directory deleted so that it is no longer
accessible as "..", to pass t_vnops case dir_rmdirdotdot.

Use genfs_can_chmod to test permissions for chmod, rather than
genfs_can_chflags.

Don't allow files to be removed from a read-only filesystem.

Fix some integer width issues in debug printfs.


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.4 -r1.1.2.5 src/sys/fs/exfatfs/exfatfs_inode.h
cvs rdiff -u -r1.1.2.10 -r1.1.2.11 src/sys/fs/exfatfs/exfatfs_vnops.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/fs/exfatfs/exfatfs_inode.h
diff -u src/sys/fs/exfatfs/exfatfs_inode.h:1.1.2.4 src/sys/fs/exfatfs/exfatfs_inode.h:1.1.2.5
--- src/sys/fs/exfatfs/exfatfs_inode.h:1.1.2.4	Fri Jul 19 16:19:15 2024
+++ src/sys/fs/exfatfs/exfatfs_inode.h	Mon Sep  9 05:01:57 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: exfatfs_inode.h,v 1.1.2.4 2024/07/19 16:19:15 perseant Exp $	*/
+/*	$NetBSD: exfatfs_inode.h,v 1.1.2.5 2024/09/09 05:01:57 perseant Exp $	*/
 
 /*-
  * Copyright (c) 2022, 2024 The NetBSD Foundation, Inc.
@@ -336,6 +336,7 @@ void exfatfs_check_fence(struct exfatfs 
 #define	XI_ACCESS	0x0004	/* Access time update */
 #define	XI_MODIFIED	0x0008	/* Xfinode has been modified. */
 #define	XI_RENAME	0x0010	/* Xfinode is being renamed */
+#define XI_DELETED	0x0020  /* Invalid, deleted */
 
 #define	EXFATFS_MAXNAMELEN	255
 

Index: src/sys/fs/exfatfs/exfatfs_vnops.c
diff -u src/sys/fs/exfatfs/exfatfs_vnops.c:1.1.2.10 src/sys/fs/exfatfs/exfatfs_vnops.c:1.1.2.11
--- src/sys/fs/exfatfs/exfatfs_vnops.c:1.1.2.10	Wed Aug 14 15:37:49 2024
+++ src/sys/fs/exfatfs/exfatfs_vnops.c	Mon Sep  9 05:01:57 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: exfatfs_vnops.c,v 1.1.2.10 2024/08/14 15:37:49 perseant Exp $	*/
+/*	$NetBSD: exfatfs_vnops.c,v 1.1.2.11 2024/09/09 05:01:57 perseant Exp $	*/
 
 /*-
  * Copyright (c) 2022 The NetBSD Foundation, Inc.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: exfatfs_vnops.c,v 1.1.2.10 2024/08/14 15:37:49 perseant Exp $");
+__KERNEL_RCSID(0, "$NetBSD: exfatfs_vnops.c,v 1.1.2.11 2024/09/09 05:01:57 perseant Exp $");
 
 #include <sys/buf.h>
 #include <sys/dirent.h>
@@ -257,10 +257,8 @@ exfatfs_setattr(void *v)
 	 * Note we silently ignore uid or gid changes.
 	 */
 	if ((vap->va_type != VNON) || (vap->va_nlink != (nlink_t)VNOVAL) ||
-#if 0
 	    (vap->va_uid != VNOVAL && vap->va_uid != fs->xf_uid) ||
 	    (vap->va_gid != VNOVAL && vap->va_gid != fs->xf_gid) ||
-#endif /* 0 */
 	    (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) ||
 	    (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) ||
 	    (vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) {
@@ -313,8 +311,9 @@ exfatfs_setattr(void *v)
 			error = EROFS;
 			goto bad;
 		}
-		error = kauth_authorize_vnode(cred, KAUTH_VNODE_WRITE_FLAGS, vp,
-			NULL, genfs_can_chflags(vp, cred, fs->xf_uid, false));
+		error = kauth_authorize_vnode(cred, KAUTH_VNODE_WRITE_SECURITY,
+			vp, NULL, genfs_can_chmod(vp, cred, fs->xf_uid,
+			fs->xf_gid, false));
 		if (error)
 			goto bad;
 		/* We ignore the read and execute bits. */
@@ -732,6 +731,8 @@ exfatfs_remove(void *v)
 		printf("remove 0x%x...\n", TRACE_INUM);
 #endif /* TRACE_INUM */
 
+	if (vp->v_mount->mnt_flag & MNT_RDONLY)
+		return EROFS;
 	if (vp->v_type == VDIR)
 		return EISDIR;
 
@@ -947,7 +948,7 @@ havespace:
 		return error;
 
 	DPRINTF(("new empty space at byte %lld (entry %u)\n",
-		 (long long)r, (unsigned)EXFATFS_B2DIRENT(r)));
+		 (long long)r, (unsigned)EXFATFS_B2DIRENT(fs, r)));
 
 	/*
 	 * Assign disk addresses
@@ -1180,7 +1181,7 @@ static unsigned first_valid_file(void *v
 	++*intp;
 
 	DPRINTF(("found valid file ino 0x%lx with ET 0x%hhx\n",
-		 INUM(xip), xip->xi_direntp[0]->xd_entryType));
+		 (unsigned long)INUM(xip), xip->xi_direntp[0]->xd_entryType));
 	return SCANDIR_STOP;
 }
 
@@ -1258,6 +1259,10 @@ exfatfs_rmdir(void *v)
 	new_key.dk_dirgen = xip;
 	exfatfs_rekey(vp, &new_key);
 	
+	/* Don't allow ".." to refer to this node anymore */
+	DPRINTF(("exfatfs_rmdir(), mark vp/xip %p/%p DELETED\n", vp, xip));
+	xip->xi_flag |= XI_DELETED;
+
 	/*
 	 * This is where we decrement the link count in the parent
 	 * directory.  Since dos filesystems don't do this we just purge
@@ -1423,6 +1428,12 @@ exfatfs_lookup(void *v)
 			}
 		}
 #endif /* TRACE_INUM */
+		if (*vpp != NULLVP && (VTOXI(*vpp)->xi_flag & XI_DELETED)) {
+			DPRINTF(("exfatfs_lookup refusing deleted cached node\n"));
+			VOP_UNLOCK(*vpp);
+			vrele(*vpp);
+			return ENOENT;
+		}
 		DPRINTF((" returning cached result\n"));
 		return *vpp == NULLVP ? ENOENT : 0;
 	}
@@ -1450,6 +1461,13 @@ exfatfs_lookup(void *v)
 
 		/* .., but not root's: we want parentvp. */
 		KASSERT(dxip->xi_parentvp != NULL);
+		DPRINTF(("exfatfs_lookup(), parent vp/xip %p/%p flags %x\n",
+			dxip->xi_parentvp, VTOXI(dxip->xi_parentvp),
+			(int)VTOXI(dxip->xi_parentvp)->xi_flag));
+		if (VTOXI(dxip->xi_parentvp)->xi_flag & XI_DELETED) {
+			DPRINTF(("exfatfs_lookup refusing deleted ..\n"));
+			return ENOENT;
+		}
 		*vpp = dxip->xi_parentvp;
 		vref(*vpp);
 		
@@ -2569,7 +2587,8 @@ deextend(struct xfinode *xip, off_t byte
 				if (pcn != opcn + 1 && IS_DSE_NOFATCHAIN(xip)) {
 					DPRINTF(("inum 0x%lx not consecutive"
 						 " with 0x%x != 0x%x+1\n",
-						 INUM(xip), pcn, opcn));
+						 (unsigned long)INUM(xip),
+						 pcn, opcn));
 					CLR_DSE_NOFATCHAIN(xip);
 					if ((error = rewrite_fat(xip, lcn, ioflags)) != 0)
 						return error;

Reply via email to