summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2021-01-11 16:01:29 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-01-23 15:38:18 +0100
commit2174b2cf3960b9091c2516feeb9e345fe24f8906 (patch)
treec7b24ea5b9b5514679cf22f254fa7d4a4d9cd11a
parente739d7501b2ee2a23a0b10e11a09b8fc45804c28 (diff)
downloadlinux-2174b2cf3960b9091c2516feeb9e345fe24f8906.tar.gz
linux-2174b2cf3960b9091c2516feeb9e345fe24f8906.tar.bz2
linux-2174b2cf3960b9091c2516feeb9e345fe24f8906.zip
nfsd4: readdirplus shouldn't return parent of export
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>
-rw-r--r--fs/nfsd/nfs3xdr.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 7e50248ca432..93c6fb53cc0e 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -822,9 +822,14 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp,
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