When attempting to strip the root path, we should first canonicalise the root pathname. Signed-off-by: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx> --- support/misc/nfsd_path.c | 17 ++++++++++++----- utils/mountd/cache.c | 6 ++++-- 2 files changed, 16 insertions(+), 7 deletions(-) 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; -- 2.21.0