diff options
author | Rick Macklem <rmacklem@FreeBSD.org> | 2021-02-28 22:15:32 +0000 |
---|---|---|
committer | Rick Macklem <rmacklem@FreeBSD.org> | 2021-02-28 22:15:32 +0000 |
commit | 3e04ab36ba5ce5cbbf6d22f17a01a391a04e465f (patch) | |
tree | 43f8a79eba82925062d368c4939cdf51f63b7865 | |
parent | b12a960e4274926171dc7a4f9887a0d0a5195b44 (diff) | |
download | src-3e04ab36ba5ce5cbbf6d22f17a01a391a04e465f.tar.gz src-3e04ab36ba5ce5cbbf6d22f17a01a391a04e465f.zip |
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
-rw-r--r-- | sys/fs/nfsclient/nfs_clvnops.c | 38 |
1 files 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); |