From 98b2a013bc723cd660978d5a1db40b987816f90e Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow@samba.org>
Date: Tue, 6 Jun 2023 15:17:26 +0200
Subject: [PATCH] CVE-2023-34968: mdssvc: cache and reuse stat info in struct
 sl_inode_path_map

Prepare for the "path" being a fake path and not the real server-side
path where we won't be able to vfs_stat_fsp() this fake path. Luckily we already
got stat info for the object in mds_add_result() so we can just pass stat info
from there.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15388

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>

Upstream-Status: Backport [https://github.com/samba-team/samba/commit/98b2a013bc723cd660978d5a1db40b987816f90e]

CVE: CVE-2023-34968

Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com>
---
 source3/rpc_server/mdssvc/mdssvc.c | 32 +++++++-----------------------
 source3/rpc_server/mdssvc/mdssvc.h |  1 +
 2 files changed, 8 insertions(+), 25 deletions(-)

diff --git a/source3/rpc_server/mdssvc/mdssvc.c b/source3/rpc_server/mdssvc/mdssvc.c
index 26a3ec7..a6cc653 100644
--- a/source3/rpc_server/mdssvc/mdssvc.c
+++ b/source3/rpc_server/mdssvc/mdssvc.c
@@ -446,7 +446,10 @@ static int ino_path_map_destr_cb(struct sl_inode_path_map *entry)
  * entries by calling talloc_free() on the query slq handles.
  **/

-static bool inode_map_add(struct sl_query *slq, uint64_t ino, const char *path)
+static bool inode_map_add(struct sl_query *slq,
+			  uint64_t ino,
+			  const char *path,
+			  struct stat_ex *st)
 {
	NTSTATUS status;
	struct sl_inode_path_map *entry;
@@ -493,6 +496,7 @@ static bool inode_map_add(struct sl_query *slq, uint64_t ino, const char *path)

	entry->ino = ino;
	entry->mds_ctx = slq->mds_ctx;
+	entry->st = *st;
	entry->path = talloc_strdup(entry, path);
	if (entry->path == NULL) {
		DEBUG(1, ("talloc failed\n"));
@@ -629,7 +633,7 @@ bool mds_add_result(struct sl_query *slq, const char *path)
		return false;
	}

-	ok = inode_map_add(slq, ino64, path);
+	ok = inode_map_add(slq, ino64, path, &sb);
	if (!ok) {
		DEBUG(1, ("inode_map_add error\n"));
		slq->state = SLQ_STATE_ERROR;
@@ -1350,29 +1354,7 @@ static bool slrpc_fetch_attributes(struct mds_ctx *mds_ctx,
		elem = talloc_get_type_abort(p, struct sl_inode_path_map);
		path = elem->path;

-		status = synthetic_pathref(talloc_tos(),
-					   mds_ctx->conn->cwd_fsp,
-					   path,
-					   NULL,
-					   NULL,
-					   0,
-					   0,
-					   &smb_fname);
-		if (!NT_STATUS_IS_OK(status)) {
-			/* This is not an error, the user may lack permissions */
-			DBG_DEBUG("synthetic_pathref [%s]: %s\n",
-				  smb_fname_str_dbg(smb_fname),
-				  nt_errstr(status));
-			return true;
-		}
-
-		result = SMB_VFS_FSTAT(smb_fname->fsp, &smb_fname->st);
-		if (result != 0) {
-			TALLOC_FREE(smb_fname);
-			return true;
-		}
-
-		sp = &smb_fname->st;
+		sp = &elem->st;
	}

	ok = add_filemeta(mds_ctx, reqinfo, fm_array, path, sp);
diff --git a/source3/rpc_server/mdssvc/mdssvc.h b/source3/rpc_server/mdssvc/mdssvc.h
index 3924827..a097991 100644
--- a/source3/rpc_server/mdssvc/mdssvc.h
+++ b/source3/rpc_server/mdssvc/mdssvc.h
@@ -105,6 +105,7 @@ struct sl_inode_path_map {
	struct mds_ctx    *mds_ctx;
	uint64_t           ino;
	char              *path;
+	struct stat_ex     st;
 };

 /* Per process state */
--
2.40.0
