Module: kamailio
Branch: master
Commit: 6cfed87253c51aa98d9363ddca3c0278b29635ef
URL: 
https://github.com/kamailio/kamailio/commit/6cfed87253c51aa98d9363ddca3c0278b29635ef

Author: SABITH SAHEB <[email protected]>
Committer: Daniel-Constantin Mierla <[email protected]>
Date: 2026-07-01T09:48:10+02:00

core: strutils - fix out of bounds read in replace()

- replace() took the backreference index from a replacement token
  (\0..\9) but indexed pmatch[] with no upper bound; the array holds
  only SR_RE_MAX_MATCH (6) entries, so a \6..\9 token read past its end
- the out of bounds regmatch_t could yield a negative rm_eo - rm_so that
  passed the signed "j + size < result->len" check and reached memcpy()
  as a large size_t, overflowing result->s
- bound the index to the match array and reject a negative match size
- replacement strings can come from untrusted data (e.g. NAPTR records
  handled by the enum module), making this reachable

Signed-off-by: SABITH SAHEB <[email protected]>

---

Modified: src/core/strutils.c

---

Diff:  
https://github.com/kamailio/kamailio/commit/6cfed87253c51aa98d9363ddca3c0278b29635ef.diff
Patch: 
https://github.com/kamailio/kamailio/commit/6cfed87253c51aa98d9363ddca3c0278b29635ef.patch

---

diff --git a/src/core/strutils.c b/src/core/strutils.c
index ad5c814663b..5b48538885a 100644
--- a/src/core/strutils.c
+++ b/src/core/strutils.c
@@ -768,6 +768,8 @@ int cmp_aor_str(str *s1, str *s2)
        return cmp_aor(&uri1, &uri2);
 }
 
+#define SR_RE_MAX_MATCH 6
+
 /*! \brief Replace in replacement tokens \\d with substrings of string pointed 
by
  * pmatch.
  */
@@ -783,9 +785,9 @@ int replace(regmatch_t *pmatch, char *string, char 
*replacement, str *result)
                        if(i < len - 1) {
                                if(isdigit((unsigned char)replacement[i + 1])) {
                                        digit = replacement[i + 1] - '0';
-                                       if(pmatch[digit].rm_so != -1) {
+                                       if(digit < SR_RE_MAX_MATCH && 
pmatch[digit].rm_so != -1) {
                                                size = pmatch[digit].rm_eo - 
pmatch[digit].rm_so;
-                                               if(j + size < result->len) {
+                                               if(size >= 0 && j + size < 
result->len) {
                                                        memcpy(&(result->s[j]),
                                                                        string 
+ pmatch[digit].rm_so, size);
                                                        j = j + size;
@@ -816,8 +818,6 @@ int replace(regmatch_t *pmatch, char *string, char 
*replacement, str *result)
 }
 
 
-#define SR_RE_MAX_MATCH 6
-
 /*! \brief Match pattern against string and store result in pmatch */
 int reg_match(char *pattern, char *string, regmatch_t *pmatch)
 {

_______________________________________________
Kamailio - Development Mailing List -- [email protected]
To unsubscribe send an email to [email protected]
Important: keep the mailing list in the recipients, do not reply only to the 
sender!

Reply via email to