From 049c13245649fab412b61a5b55e5a7dea72d7c72 Mon Sep 17 00:00:00 2001
From: Ralph Boehme <slow@samba.org>
Date: Fri, 26 May 2023 15:06:38 +0200
Subject: [PATCH 06/28] CVE-2023-34967: mdssvc: add type checking to
 dalloc_value_for_key()

Change the dalloc_value_for_key() function to require an additional final
argument which denotes the expected type of the value associated with a key. If
the types don't match, return NULL.

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

Signed-off-by: Ralph Boehme <slow@samba.org>

Conflict: NA
Reference: https://download.samba.org/pub/samba/patches/security/samba-4.17.10-security-2023-07-19.patch
---
 source3/rpc_server/mdssvc/dalloc.c | 14 ++++++++++----
 source3/rpc_server/mdssvc/mdssvc.c | 17 +++++++++++++----
 2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/source3/rpc_server/mdssvc/dalloc.c b/source3/rpc_server/mdssvc/dalloc.c
index 007702d4540..8b79b41fd97 100644
--- a/source3/rpc_server/mdssvc/dalloc.c
+++ b/source3/rpc_server/mdssvc/dalloc.c
@@ -159,7 +159,7 @@ void *dalloc_value_for_key(const DALLOC_CTX *d, ...)
 	int result = 0;
 	void *p = NULL;
 	va_list args;
-	const char *type;
+	const char *type = NULL;
 	int elem;
 	size_t array_len;
 
@@ -170,7 +170,6 @@ void *dalloc_value_for_key(const DALLOC_CTX *d, ...)
 		array_len = talloc_array_length(d->dd_talloc_array);
 		elem = va_arg(args, int);
 		if (elem >= array_len) {
-			va_end(args);
 			result = -1;
 			goto done;
 		}
@@ -178,8 +177,6 @@ void *dalloc_value_for_key(const DALLOC_CTX *d, ...)
 		type = va_arg(args, const char *);
 	}
 
-	va_end(args);
-
 	array_len = talloc_array_length(d->dd_talloc_array);
 
 	for (elem = 0; elem + 1 < array_len; elem += 2) {
@@ -192,8 +189,17 @@ void *dalloc_value_for_key(const DALLOC_CTX *d, ...)
 			break;
 		}
 	}
+	if (p == NULL) {
+		goto done;
+	}
+
+	type = va_arg(args, const char *);
+	if (strcmp(talloc_get_name(p), type) != 0) {
+		p = NULL;
+	}
 
 done:
+	va_end(args);
 	if (result != 0) {
 		p = NULL;
 	}
diff --git a/source3/rpc_server/mdssvc/mdssvc.c b/source3/rpc_server/mdssvc/mdssvc.c
index 9b32c99b8b3..7dd3c84713f 100644
--- a/source3/rpc_server/mdssvc/mdssvc.c
+++ b/source3/rpc_server/mdssvc/mdssvc.c
@@ -872,7 +872,8 @@ static bool slrpc_open_query(struct mds_ctx *mds_ctx,
 
 	querystring = dalloc_value_for_key(query, "DALLOC_CTX", 0,
 					   "DALLOC_CTX", 1,
-					   "kMDQueryString");
+					   "kMDQueryString",
+					   "char *");
 	if (querystring == NULL) {
 		DEBUG(1, ("missing kMDQueryString\n"));
 		goto error;
@@ -912,8 +913,11 @@ static bool slrpc_open_query(struct mds_ctx *mds_ctx,
 	slq->ctx2 = *uint64p;
 
 	path_scope = dalloc_value_for_key(query, "DALLOC_CTX", 0,
-					  "DALLOC_CTX", 1, "kMDScopeArray");
+					  "DALLOC_CTX", 1,
+					  "kMDScopeArray",
+					  "sl_array_t");
 	if (path_scope == NULL) {
+		DBG_ERR("missing kMDScopeArray\n");
 		goto error;
 	}
 
@@ -934,8 +938,11 @@ static bool slrpc_open_query(struct mds_ctx *mds_ctx,
 	}
 
 	reqinfo = dalloc_value_for_key(query, "DALLOC_CTX", 0,
-				       "DALLOC_CTX", 1, "kMDAttributeArray");
+				       "DALLOC_CTX", 1,
+				       "kMDAttributeArray",
+				       "sl_array_t");
 	if (reqinfo == NULL) {
+		DBG_ERR("missing kMDAttributeArray\n");
 		goto error;
 	}
 
@@ -943,7 +950,9 @@ static bool slrpc_open_query(struct mds_ctx *mds_ctx,
 	DEBUG(10, ("requested attributes: %s", dalloc_dump(reqinfo, 0)));
 
 	cnids = dalloc_value_for_key(query, "DALLOC_CTX", 0,
-				     "DALLOC_CTX", 1, "kMDQueryItemArray");
+				     "DALLOC_CTX", 1,
+				     "kMDQueryItemArray",
+				     "sl_array_t");
 	if (cnids) {
 		ok = sort_cnids(slq, cnids->ca_cnids);
 		if (!ok) {
-- 
2.34.1
