--- /dev/null
+From 51b2ee7d006a736a9126e8111d1f24e4fd0afaa6 Mon Sep 17 00:00:00 2001
+From: "J. Bruce Fields" <bfields@redhat.com>
+Date: Mon, 11 Jan 2021 16:01:29 -0500
+Subject: nfsd4: readdirplus shouldn't return parent of export
+
+From: J. Bruce Fields <bfields@redhat.com>
+
+commit 51b2ee7d006a736a9126e8111d1f24e4fd0afaa6 upstream.
+
+If you export a subdirectory of a filesystem, a READDIRPLUS on the root
+of that export will return the filehandle of the parent with the ".."
+entry.
+
+The filehandle is optional, so let's just not return the filehandle for
+".." if we're at the root of an export.
+
+Note that once the client learns one filehandle outside of the export,
+they can trivially access the rest of the export using further lookups.
+
+However, it is also not very difficult to guess filehandles outside of
+the export. So exporting a subdirectory of a filesystem should
+considered equivalent to providing access to the entire filesystem. To
+avoid confusion, we recommend only exporting entire filesystems.
+
+Reported-by: Youjipeng <wangzhibei1999@gmail.com>
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfsd/nfs3xdr.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/fs/nfsd/nfs3xdr.c
++++ b/fs/nfsd/nfs3xdr.c
+@@ -822,9 +822,14 @@ compose_entry_fh(struct nfsd3_readdirres
+ if (isdotent(name, namlen)) {
+ if (namlen == 2) {
+ dchild = dget_parent(dparent);
+- /* filesystem root - cannot return filehandle for ".." */
++ /*
++ * Don't return filehandle for ".." if we're at
++ * the filesystem or export root:
++ */
+ if (dchild == dparent)
+ goto out;
++ if (dparent == exp->ex_path.dentry)
++ goto out;
+ } else
+ dchild = dget(dparent);
+ } else