diff mbox series

[1/5] nfsd_path.h - nfsd_path.c: - Configured export rootdir must now be an absolute path - Rootdir is into a global variable what will also be used to retrieve it later on - nfsd_path_nfsd_rootdir(void) is simplified with nfsd_path_rootdir which returns

Message ID 20241206221202.31507-2-christopherbii@hyub.org (mailing list archive)
State New
Headers show
Series nfs export symlink vulnerability fix (duplicate(ish)) | expand

Commit Message

Christopher Bii Dec. 6, 2024, 10:11 p.m. UTC
Signed-off-by: Christopher Bii <christopherbii@hyub.org>
---
 support/export/export.c     |  2 +-
 support/include/nfsd_path.h |  2 +-
 support/misc/nfsd_path.c    | 65 ++++++++++++++-----------------------
 3 files changed, 27 insertions(+), 42 deletions(-)
diff mbox series

Patch

diff --git a/support/export/export.c b/support/export/export.c
index 2c8c3335..3a4fb747 100644
--- a/support/export/export.c
+++ b/support/export/export.c
@@ -40,7 +40,7 @@  static int	export_check(const nfs_export *exp, const struct addrinfo *ai,
 static void
 exportent_mkrealpath(struct exportent *eep)
 {
-	const char *chroot = nfsd_path_nfsd_rootdir();
+	const char *chroot = nfsd_path_rootdir();
 	char *ret = NULL;
 
 	if (chroot) {
diff --git a/support/include/nfsd_path.h b/support/include/nfsd_path.h
index aa1e1dd0..2b9b68af 100644
--- a/support/include/nfsd_path.h
+++ b/support/include/nfsd_path.h
@@ -11,7 +11,7 @@  struct statfs;
 
 void 		nfsd_path_init(void);
 
-const char *	nfsd_path_nfsd_rootdir(void);
+const char *    nfsd_path_rootdir(void);
 char *		nfsd_path_strip_root(char *pathname);
 char *		nfsd_path_prepend_dir(const char *dir, const char *pathname);
 
diff --git a/support/misc/nfsd_path.c b/support/misc/nfsd_path.c
index c3dea4f0..5168903d 100644
--- a/support/misc/nfsd_path.c
+++ b/support/misc/nfsd_path.c
@@ -20,57 +20,43 @@ 
 #include "workqueue.h"
 
 static struct xthread_workqueue *nfsd_wq;
+const char      *rootdir;
+size_t          rootdir_pathlen = 0;
 
-static int
-nfsd_path_isslash(const char *path)
-{
-	return path[0] == '/' && path[1] == '/';
-}
 
-static int
-nfsd_path_isdot(const char *path)
+const char*
+nfsd_path_rootdir(void)
 {
-	return path[0] == '.' && path[1] == '/';
-}
+        return rootdir;
+};
 
-static const char *
-nfsd_path_strip(const char *path)
+/* Set rootdir global variable. Rootdir must be an absolute path
+ * and resolveable by realpath()
+ * */
+static void
+nfsd_rootdir_set(void)
 {
-	if (!path || *path == '\0')
-		goto out;
-	for (;;) {
-		if (nfsd_path_isslash(path)) {
-			path++;
-			continue;
-		}
-		if (nfsd_path_isdot(path)) {
-			path += 2;
-			continue;
-		}
-		break;
-	}
-out:
-	return path;
-}
+        const char             *path;
+        if (!(path = conf_get_str("exports", "rootdir")))
+                return;
 
-const char *
-nfsd_path_nfsd_rootdir(void)
-{
-	const char *rootdir;
+        if (path[0] != '/')
+                xlog(L_FATAL, "%s: NFS export rootdir must be an absolute path. "
+                                "Current value: \"%s\"", __func__, path);
 
-	rootdir = nfsd_path_strip(conf_get_str("exports", "rootdir"));
-	if (!rootdir || rootdir[0] ==  '\0')
-		return NULL;
-	if (rootdir[0] == '/' && rootdir[1] == '\0')
-		return NULL;
-	return rootdir;
+        if (!(rootdir = realpath(path, NULL))){
+                free((void*)rootdir);
+                xlog(L_FATAL, "realpath(): Unable to resolve root export path \"%s\"", path);
+        };
+
+        rootdir_pathlen = strlen(rootdir);
 }
 
 char *
 nfsd_path_strip_root(char *pathname)
 {
 	char buffer[PATH_MAX];
-	const char *dir = nfsd_path_nfsd_rootdir();
+	const char *dir = nfsd_path_rootdir();
 
 	if (!dir)
 		goto out;
@@ -106,8 +92,7 @@  nfsd_path_prepend_dir(const char *dir, const char *pathname)
 static void
 nfsd_setup_workqueue(void)
 {
-	const char *rootdir = nfsd_path_nfsd_rootdir();
-
+	nfsd_rootdir_set();
 	if (!rootdir)
 		return;