From a744eb5b6a018d6d264276694f34f6bad51c68fe Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Thu, 23 Apr 2026 18:20:15 +0200
Subject: [PATCH 19/38] CVE-2026-4480/CVE-2026-4408: lib/util: remove unused
 talloc_strdup(insert) from talloc_string_sub2()

The insert string is not modified, so we do not need to copy it.

This will simplify further changes.

Review with: git show --patience

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

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
---
 lib/util/substitute.c | 57 +++++++++++++++++++------------------------
 1 file changed, 25 insertions(+), 32 deletions(-)

diff --git a/lib/util/substitute.c b/lib/util/substitute.c
index 26362ca77b2..4a0c58ab3a7 100644
--- a/lib/util/substitute.c
+++ b/lib/util/substitute.c
@@ -157,7 +157,7 @@ char *talloc_string_sub2(TALLOC_CTX *mem_ctx, const char *src,
 			bool replace_once,
 			bool allow_trailing_dollar)
 {
-	char *p, *in;
+	char *p;
 	char *s;
 	char *string;
 	ssize_t ls,lp,li,ld, i;
@@ -175,22 +175,32 @@ char *talloc_string_sub2(TALLOC_CTX *mem_ctx, const char *src,
 
 	s = string;
 
-	in = talloc_strdup(mem_ctx, insert);
-	if (!in) {
-		DEBUG(0, ("talloc_string_sub2: ENOMEM\n"));
-		talloc_free(string);
-		return NULL;
-	}
 	ls = (ssize_t)strlen(s);
 	lp = (ssize_t)strlen(pattern);
 	li = (ssize_t)strlen(insert);
 	ld = li - lp;
 
-	for (i=0;i<li;i++) {
-		switch (in[i]) {
+	while ((p = strstr_m(s,pattern))) {
+		if (ld > 0) {
+			int offset = PTR_DIFF(s,string);
+			string = (char *)talloc_realloc_size(mem_ctx, string,
+							ls + ld + 1);
+			if (!string) {
+				DEBUG(0, ("talloc_string_sub: out of "
+					  "memory!\n"));
+				return NULL;
+			}
+			p = string + offset + (p - s);
+		}
+		if (li != lp) {
+			memmove(p+li,p+lp,strlen(p+lp)+1);
+		}
+		for (i=0; i<li; i++) {
+			switch (insert[i]) {
 			case '$':
-				/* allow a trailing $
-				 * (as in machine accounts) */
+				/*
+				 * allow a trailing $ (as in machine accounts)
+				 */
 				if (allow_trailing_dollar && (i == li - 1 )) {
 					break;
 				}
@@ -204,34 +214,18 @@ char *talloc_string_sub2(TALLOC_CTX *mem_ctx, const char *src,
 			case '\r':
 			case '\n':
 				if (remove_unsafe_characters) {
-					in[i] = '_';
-					break;
+					p[i] = '_';
+					continue;
 				}
 
 				FALL_THROUGH;
 			default:
 				/* ok */
 				break;
-		}
-	}
-
-	while ((p = strstr_m(s,pattern))) {
-		if (ld > 0) {
-			int offset = PTR_DIFF(s,string);
-			string = (char *)talloc_realloc_size(mem_ctx, string,
-							ls + ld + 1);
-			if (!string) {
-				DEBUG(0, ("talloc_string_sub: out of "
-					  "memory!\n"));
-				TALLOC_FREE(in);
-				return NULL;
 			}
-			p = string + offset + (p - s);
+
+			p[i] = insert[i];
 		}
-		if (li != lp) {
-			memmove(p+li,p+lp,strlen(p+lp)+1);
-		}
-		memcpy(p, in, li);
 		s = p + li;
 		ls += ld;
 
@@ -239,7 +233,6 @@ char *talloc_string_sub2(TALLOC_CTX *mem_ctx, const char *src,
 			break;
 		}
 	}
-	TALLOC_FREE(in);
 	return string;
 }
 
-- 
2.43.0


