From 0ea29d6077dacbf6a754b0e648275eec2a576e87 Mon Sep 17 00:00:00 2001
From: Trond Myklebust <trond.myklebust@hammerspace.com>
Date: Mon, 10 Nov 2025 11:26:03 -0500
Subject: [PATCH 1/4] mountd: Minor refactor of get_rootfh()

Perform the mountpoint checks before checking the user path.

CVE: CVE-2025-12801
Upstream-Status: Backport [https://git.linux-nfs.org/?p=steved/nfs-utils.git;a=commit;h=7e8b36522f58657359c6842119fc516c6dd1baa4]

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Steve Dickson <steved@redhat.com>
(cherry picked from commit 7e8b36522f58657359c6842119fc516c6dd1baa4)
Signed-off-by: Deepak Rathore <deeratho@cisco.com>
---
 utils/mountd/mountd.c | 34 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c
index dbd5546d..39afd4aa 100644
--- a/utils/mountd/mountd.c
+++ b/utils/mountd/mountd.c
@@ -412,6 +412,23 @@ get_rootfh(struct svc_req *rqstp, dirpath *path, nfs_export **expret,
 		*error = MNT3ERR_ACCES;
 		return NULL;
 	}
+	if (nfsd_path_stat(exp->m_export.e_path, &estb) < 0) {
+		xlog(L_WARNING, "can't stat export point %s: %s",
+		     p, strerror(errno));
+		*error = MNT3ERR_NOENT;
+		return NULL;
+	}
+	if (exp->m_export.e_mountpoint &&
+		   !check_is_mountpoint(exp->m_export.e_mountpoint[0]?
+				  exp->m_export.e_mountpoint:
+				  exp->m_export.e_path,
+				  nfsd_path_lstat)) {
+		xlog(L_WARNING, "request to export an unmounted filesystem: %s",
+		     p);
+		*error = MNT3ERR_NOENT;
+		return NULL;
+	}
+
 	if (nfsd_path_stat(p, &stb) < 0) {
 		xlog(L_WARNING, "can't stat exported dir %s: %s",
 				p, strerror(errno));
@@ -426,12 +443,6 @@ get_rootfh(struct svc_req *rqstp, dirpath *path, nfs_export **expret,
 		*error = MNT3ERR_NOTDIR;
 		return NULL;
 	}
-	if (nfsd_path_stat(exp->m_export.e_path, &estb) < 0) {
-		xlog(L_WARNING, "can't stat export point %s: %s",
-		     p, strerror(errno));
-		*error = MNT3ERR_NOENT;
-		return NULL;
-	}
 	if (estb.st_dev != stb.st_dev
 	    && !(exp->m_export.e_flags & NFSEXP_CROSSMOUNT)) {
 		xlog(L_WARNING, "request to export directory %s below nearest filesystem %s",
@@ -439,17 +450,6 @@ get_rootfh(struct svc_req *rqstp, dirpath *path, nfs_export **expret,
 		*error = MNT3ERR_ACCES;
 		return NULL;
 	}
-	if (exp->m_export.e_mountpoint &&
-		   !check_is_mountpoint(exp->m_export.e_mountpoint[0]?
-				  exp->m_export.e_mountpoint:
-				  exp->m_export.e_path,
-				  nfsd_path_lstat)) {
-		xlog(L_WARNING, "request to export an unmounted filesystem: %s",
-		     p);
-		*error = MNT3ERR_NOENT;
-		return NULL;
-	}
-
 	/* This will be a static private nfs_export with just one
 	 * address.  We feed it to kernel then extract the filehandle,
 	 */
-- 
2.35.6

