The branch main has been updated by rmacklem:

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

commit 3e04ab36ba5ce5cbbf6d22f17a01a391a04e465f
Author:     Rick Macklem <rmack...@freebsd.org>
AuthorDate: 2021-02-28 22:15:32 +0000
Commit:     Rick Macklem <rmack...@freebsd.org>
CommitDate: 2021-02-28 22:15:32 +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.
    
    Reviewd by:     kib
    MFC after:      2 weeks
    Differential Revision:  https://reviews.freebsd.org/D28987
---
 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 80317cfd7a50..fc5445ef1e76 100644
--- a/sys/fs/nfsclient/nfs_clvnops.c
+++ b/sys/fs/nfsclient/nfs_clvnops.c
@@ -1423,7 +1423,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,
@@ -1752,9 +1752,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,
@@ -2126,7 +2131,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,
@@ -2205,7 +2214,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);
 }
@@ -2278,9 +2292,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);
_______________________________________________
dev-commits-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"

Reply via email to