]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
CVE-2026-4480/CVE-2026-4408: lib/util: split out realloc_string_sub_raw()
authorStefan Metzmacher <metze@samba.org>
Thu, 30 Apr 2026 12:48:26 +0000 (14:48 +0200)
committerStefan Metzmacher <metze@samba.org>
Tue, 26 May 2026 12:51:32 +0000 (12:51 +0000)
This will allow realloc_string_sub2() to use it in order
to have the logic in one place only.

And it will also allow adjacted callers to be
more flexible.

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
lib/util/substitute.h

index b9fe32e993ec4e44af24a4cf8c59f4b36a2df09e..465aea8660553aff2f2a2ea754562cd14e130a46 100644 (file)
@@ -171,32 +171,24 @@ _PUBLIC_ void all_string_sub(char *s,const char *pattern,const char *insert, siz
  * talloc version of string_sub2.
  */
 
-char *talloc_string_sub2(TALLOC_CTX *mem_ctx, const char *src,
-                       const char *pattern,
-                       const char *insert,
-                       bool remove_unsafe_characters,
-                       bool replace_once,
-                       bool allow_trailing_dollar)
+bool realloc_string_sub_raw(char **_string,
+                           const char *pattern,
+                           const char *insert,
+                           bool replace_once,
+                           bool allow_trailing_dollar,
+                           const char *unsafe_characters,
+                           char safe_character)
 {
-       const char *unsafe_characters = STRING_SUB_UNSAFE_CHARACTERS;
-       const char safe_character = '_';
-       char *p = NULL,
+       char *p = NULL;
        char *s = NULL;
        char *string = NULL;
        ssize_t ls,lp,li,ld, i;
 
-       if (!insert || !pattern || !*pattern || !src) {
-               return NULL;
-       }
-
-       string = talloc_strdup(mem_ctx, src);
-       if (string == NULL) {
-               DEBUG(0, ("talloc_string_sub2: "
-                       "talloc_strdup failed\n"));
-               return NULL;
+       if (!insert || !pattern || !*pattern || !_string|| !*_string) {
+               return false;
        }
 
-       s = string;
+       s = string = *_string;
 
        ls = (ssize_t)strlen(s);
        lp = (ssize_t)strlen(pattern);
@@ -205,14 +197,13 @@ char *talloc_string_sub2(TALLOC_CTX *mem_ctx, const char *src,
 
        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);
+                       ptrdiff_t offset = PTR_DIFF(s,string);
+                       string = talloc_realloc(NULL, string, char, ls + ld + 1);
                        if (!string) {
-                               DEBUG(0, ("talloc_string_sub: out of "
-                                         "memory!\n"));
-                               return NULL;
+                               DBG_ERR("out of memory(realloc)!\n");
+                               return false;
                        }
+                       *_string = string;
                        p = string + offset + (p - s);
                }
                if (li != lp) {
@@ -234,6 +225,50 @@ char *talloc_string_sub2(TALLOC_CTX *mem_ctx, const char *src,
                        break;
                }
        }
+       return true;
+}
+
+char *talloc_string_sub2(TALLOC_CTX *mem_ctx,
+                        const char *src,
+                        const char *pattern,
+                        const char *insert,
+                        bool remove_unsafe_characters,
+                        bool replace_once,
+                        bool allow_trailing_dollar)
+{
+       const char *unsafe_characters = NULL;
+       char safe_character = '\0';
+       char *string = NULL;
+       bool ok;
+
+       if (!insert || !pattern || !*pattern || !src) {
+               return NULL;
+       }
+
+       if (remove_unsafe_characters) {
+               unsafe_characters = STRING_SUB_UNSAFE_CHARACTERS;
+               safe_character = '_';
+       }
+
+       string = talloc_strdup(mem_ctx, src);
+       if (string == NULL) {
+               DBG_ERR("out of memory, talloc_strdup(src)!\n");
+               return NULL;
+       }
+
+       ok = realloc_string_sub_raw(&string,
+                                   pattern,
+                                   insert,
+                                   replace_once,
+                                   allow_trailing_dollar,
+                                   unsafe_characters,
+                                   safe_character);
+       if (!ok) {
+               TALLOC_FREE(string);
+               DBG_ERR("out of memory, realloc_string_sub_raw()!\n");
+               return NULL;
+       }
+
        return string;
 }
 
index e1a82859daca7a3553cd712212381ed9e9fb413d..041a649fd1817dd5639af6a333aa4d40f8e61a6f 100644 (file)
@@ -51,6 +51,24 @@ void string_sub(char *s,const char *pattern, const char *insert, size_t len);
 **/
 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len);
 
+/*
+ * If unsafe_characters is NULL all characters are allowed,
+ * if unsafe_characters is not NULL all characters caught
+ * by iscntrl() are also replaced by safe_character.
+ *
+ * *_string might be reallocated!
+ *
+ * On error *_string may still be reallocated and
+ * may contain partial replacements.
+ */
+bool realloc_string_sub_raw(char **_string,
+                           const char *pattern,
+                           const char *insert,
+                           bool replace_once,
+                           bool allow_trailing_dollar,
+                           const char *unsafe_characters,
+                           char safe_character);
+
 char *talloc_string_sub2(TALLOC_CTX *mem_ctx, const char *src,
                        const char *pattern,
                        const char *insert,