Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 15 Mar 2021 20:48:00 GMT
From:      Rick Macklem <rmacklem@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: b6b901f8f8a7 - stable/12 - nfsclient: add checks for a server returning the current directory
Message-ID:  <202103152048.12FKm0oM007351@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/12 has been updated by rmacklem:

URL: https://cgit.FreeBSD.org/src/commit/?id=b6b901f8f8a77ce37a7807ac152e971d43e2291e

commit b6b901f8f8a77ce37a7807ac152e971d43e2291e
Author:     Rick Macklem <rmacklem@FreeBSD.org>
AuthorDate: 2021-02-28 22:15:32 +0000
Commit:     Rick Macklem <rmacklem@FreeBSD.org>
CommitDate: 2021-03-15 19:46:23 +0000

    nfsclient: add checks for a server returning the current directory
    
    Commit 3fe2c68ba20f dealt with a panic in cache_enter_time() where
    the vnode referred to the directory argument.
    It would also be possible to get these panics if a broken
    NFS server were to return the directory as an new object being
    created within the directory or in a Lookup reply.
    
    This patch adds checks to avoid the panics and logs
    messages to indicate that the server is broken for the
    file object creation cases.
    
    (cherry picked from commit 3e04ab36ba5ce5cbbf6d22f17a01a391a04e465f)
---
 sys/fs/nfsclient/nfs_clvnops.c | 38 +++++++++++++++++++++++++++++---------
 1 file changed, 29 insertions(+), 9 deletions(-)

diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c
index 478ee059fe84..9fbf9173434f 100644
--- a/sys/fs/nfsclient/nfs_clvnops.c
+++ b/sys/fs/nfsclient/nfs_clvnops.c
@@ -1378,7 +1378,7 @@ nfs_lookup(struct vop_lookup_args *ap)
 	}
 	if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))
 		cnp->cn_flags |= SAVENAME;
-	if ((cnp->cn_flags & MAKEENTRY) &&
+	if ((cnp->cn_flags & MAKEENTRY) && dvp != newvp &&
 	    (cnp->cn_nameiop != DELETE || !(flags & ISLASTCN)) &&
 	    attrflag != 0 && (newvp->v_type != VDIR || dattrflag != 0))
 		cache_enter_time(dvp, newvp, cnp, &nfsva.na_ctime,
@@ -1707,9 +1707,14 @@ again:
 		}
 	}
 	if (!error) {
-		if ((cnp->cn_flags & MAKEENTRY) && attrflag)
-			cache_enter_time(dvp, newvp, cnp, &nfsva.na_ctime,
-			    NULL);
+		if ((cnp->cn_flags & MAKEENTRY) && attrflag) {
+			if (dvp != newvp)
+				cache_enter_time(dvp, newvp, cnp,
+				    &nfsva.na_ctime, NULL);
+			else
+				printf("nfs_create: bogus NFS server returned "
+				    "the directory as the new file object\n");
+		}
 		*ap->a_vpp = newvp;
 	} else if (NFS_ISV4(dvp)) {
 		error = nfscl_maperr(cnp->cn_thread, error, vap->va_uid,
@@ -2081,7 +2086,11 @@ nfs_link(struct vop_link_args *ap)
 	 */
 	if (VFSTONFS(vp->v_mount)->nm_negnametimeo != 0 &&
 	    (cnp->cn_flags & MAKEENTRY) && attrflag != 0 && error == 0) {
-		cache_enter_time(tdvp, vp, cnp, &nfsva.na_ctime, NULL);
+		if (tdvp != vp)
+			cache_enter_time(tdvp, vp, cnp, &nfsva.na_ctime, NULL);
+		else
+			printf("nfs_link: bogus NFS server returned "
+			    "the directory as the new link\n");
 	}
 	if (error && NFS_ISV4(vp))
 		error = nfscl_maperr(cnp->cn_thread, error, (uid_t)0,
@@ -2160,7 +2169,12 @@ nfs_symlink(struct vop_symlink_args *ap)
 	 */
 	if (VFSTONFS(dvp->v_mount)->nm_negnametimeo != 0 &&
 	    (cnp->cn_flags & MAKEENTRY) && attrflag != 0 && error == 0) {
-		cache_enter_time(dvp, newvp, cnp, &nfsva.na_ctime, NULL);
+		if (dvp != newvp)
+			cache_enter_time(dvp, newvp, cnp, &nfsva.na_ctime,
+			    NULL);
+		else
+			printf("nfs_symlink: bogus NFS server returned "
+			    "the directory as the new file object\n");
 	}
 	return (error);
 }
@@ -2233,9 +2247,15 @@ nfs_mkdir(struct vop_mkdir_args *ap)
 		 */
 		if (VFSTONFS(dvp->v_mount)->nm_negnametimeo != 0 &&
 		    (cnp->cn_flags & MAKEENTRY) &&
-		    attrflag != 0 && dattrflag != 0)
-			cache_enter_time(dvp, newvp, cnp, &nfsva.na_ctime,
-			    &dnfsva.na_ctime);
+		    attrflag != 0 && dattrflag != 0) {
+			if (dvp != newvp)
+				cache_enter_time(dvp, newvp, cnp,
+				    &nfsva.na_ctime, &dnfsva.na_ctime);
+			else
+				printf("nfs_mkdir: bogus NFS server returned "
+				    "the directory that the directory was "
+				    "created in as the new file object\n");
+		}
 		*ap->a_vpp = newvp;
 	}
 	return (error);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202103152048.12FKm0oM007351>