From 5af3ac1b40eef162e95d5861ec83831a9780429b Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 27 May 2018 15:11:03 +0200 Subject: [PATCH 1/2] reproduce buffer overflow in str_escape_ex --- src/util/strings.test.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/util/strings.test.c b/src/util/strings.test.c index b6b0f9696..2205e538b 100644 --- a/src/util/strings.test.c +++ b/src/util/strings.test.c @@ -22,6 +22,16 @@ static void test_str_unescape(CuTest * tc) CuAssertStrEquals(tc, "\"\\\n\t\ra", scratch); } +static void test_str_escape_ex(CuTest * tc) +{ + char scratch[16]; + + CuAssertPtrEquals(tc, NULL, (void *)str_escape_ex("1234", scratch, 0, "\\\"")); + memset(scratch, 0, sizeof(scratch)); + CuAssertStrEquals(tc, "1234", (void *)str_escape_ex("1234\000abcd", scratch, 16, "\\\"")); + CuAssertIntEquals(tc, 0, scratch[5]); +} + static void test_str_escape(CuTest * tc) { char scratch[16]; @@ -149,6 +159,7 @@ CuSuite *get_strings_suite(void) CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_str_hash); SUITE_ADD_TEST(suite, test_str_escape); + SUITE_ADD_TEST(suite, test_str_escape_ex); SUITE_ADD_TEST(suite, test_str_unescape); SUITE_ADD_TEST(suite, test_str_replace); SUITE_ADD_TEST(suite, test_str_slprintf); From 034872c44e96d3c6cc38633e27dcb36bf2ef28b4 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 27 May 2018 15:15:31 +0200 Subject: [PATCH 2/2] respect the input length when copying in str_escape_ex. --- src/util/strings.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/util/strings.c b/src/util/strings.c index 61a28b814..f4bbd54a5 100644 --- a/src/util/strings.c +++ b/src/util/strings.c @@ -312,10 +312,13 @@ char *str_unescape(char *str) { const char *str_escape_ex(const char *str, char *buffer, size_t size, const char *chars) { + size_t slen = strlen(str); const char *read = str; char *write = buffer; - if (size < 1) return NULL; - while (size > 1 && *read) { + if (size < 1) { + return NULL; + } + while (slen > 0 && size > 1 && *read) { const char *pos = strpbrk(read, chars); size_t len = size; if (pos) { @@ -324,7 +327,11 @@ const char *str_escape_ex(const char *str, char *buffer, size_t size, const char if (len < size) { unsigned char ch = *(const unsigned char *)pos; if (len > 0) { + if (len > slen) { + len = slen; + } memmove(write, read, len); + slen -= len; write += len; read += len; size -= len; @@ -376,13 +383,18 @@ const char *str_escape_ex(const char *str, char *buffer, size_t size, const char else size = 1; } ++read; + --slen; } else { /* end of buffer space */ len = size - 1; if (len > 0) { + if (len > slen) { + len = slen; + } memmove(write, read, len); write += len; size -= len; + slen -= len; break; } }