diff mbox series

[v2,2/3] mountd: Ensure nfsd_path_strip_root() uses the canonicalised path

Message ID 20190604175734.98657-3-trond.myklebust@hammerspace.com (mailing list archive)
State New, archived
Headers show
Series Incremental against [exports] rootdir patchset | expand

Commit Message

Trond Myklebust June 4, 2019, 5:57 p.m. UTC
When attempting to strip the root path, we should first canonicalise
the root pathname.

Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
---
 support/misc/nfsd_path.c | 17 ++++++++++++-----
 utils/mountd/cache.c     |  6 ++++--
 2 files changed, 16 insertions(+), 7 deletions(-)
diff mbox series

Patch

diff --git a/support/misc/nfsd_path.c b/support/misc/nfsd_path.c
index 2f41a793c534..84e48028071c 100644
--- a/support/misc/nfsd_path.c
+++ b/support/misc/nfsd_path.c
@@ -1,6 +1,7 @@ 
 #include <errno.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <limits.h>
 #include <stdlib.h>
 #include <unistd.h>
 
@@ -62,13 +63,19 @@  nfsd_path_nfsd_rootdir(void)
 char *
 nfsd_path_strip_root(char *pathname)
 {
+	char buffer[PATH_MAX];
 	const char *dir = nfsd_path_nfsd_rootdir();
-	char *ret;
 
-	ret = strstr(pathname, dir);
-	if (!ret || ret != pathname)
-		return pathname;
-	return pathname + strlen(dir);
+	if (!dir)
+		goto out;
+
+	if (realpath(dir, buffer))
+		return strstr(pathname, buffer) == pathname ?
+			pathname + strlen(buffer) : NULL;
+
+	xlog(D_GENERAL, "%s: failed to resolve path %s: %m", __func__, dir);
+out:
+	return pathname;
 }
 
 char *
diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c
index d616d526667e..ecda18c75a0f 100644
--- a/utils/mountd/cache.c
+++ b/utils/mountd/cache.c
@@ -390,7 +390,6 @@  static char *next_mnt(void **v, char *p)
 	FILE *f;
 	struct mntent *me;
 	size_t l = strlen(p);
-	char *mnt_dir = NULL;
 
 	if (*v == NULL) {
 		f = setmntent("/etc/mtab", "r");
@@ -398,7 +397,10 @@  static char *next_mnt(void **v, char *p)
 	} else
 		f = *v;
 	while ((me = getmntent(f)) != NULL && l > 1) {
-		mnt_dir = nfsd_path_strip_root(me->mnt_dir);
+		char *mnt_dir = nfsd_path_strip_root(me->mnt_dir);
+
+		if (!mnt_dir)
+			continue;
 
 		if (strncmp(mnt_dir, p, l) == 0 && mnt_dir[l] == '/')
 			return mnt_dir;