diff options
-rw-r--r-- | debian/patches/030_str-overflow.patch | 162 | ||||
-rw-r--r-- | debian/patches/series | 1 |
2 files changed, 163 insertions, 0 deletions
diff --git a/debian/patches/030_str-overflow.patch b/debian/patches/030_str-overflow.patch new file mode 100644 index 0000000..47aa4a7 --- /dev/null +++ b/debian/patches/030_str-overflow.patch @@ -0,0 +1,162 @@ +Subject: Fix overflow due to Str.c +Author: Tatsuya Kinoshita <tats@debian.org> +Bug-Chromium: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=31397 + + * Str.c: Fix potential overflow due to Str.c. + * Str.c: Fix integer overflow due to Strgrow. + +--- a/Str.c ++++ b/Str.c +@@ -21,10 +21,12 @@ + #ifdef __EMX__ /* or include "fm.h" for HAVE_BCOPY? */ + #include <strings.h> + #endif ++#include <limits.h> + #include "Str.h" + #include "myctype.h" + + #define INITIAL_STR_SIZE 32 ++#define STR_SIZE_MAX INT_MAX + + #ifdef STR_DEBUG + /* This is obsolete, because "Str" can handle a '\0' character now. */ +@@ -48,8 +50,8 @@ Str + Strnew_size(int n) + { + Str x = GC_MALLOC(sizeof(struct _Str)); +- if (n < 0) +- n = 0; ++ if (n < 0 || n >= STR_SIZE_MAX) ++ n = STR_SIZE_MAX - 1; + x->ptr = GC_MALLOC_ATOMIC(n + 1); + x->ptr[0] = '\0'; + x->area_size = n + 1; +@@ -67,10 +69,13 @@ Strnew_charp(const char *p) + return Strnew(); + x = GC_MALLOC(sizeof(struct _Str)); + n = strlen(p) + 1; ++ if (n < 0 || n > STR_SIZE_MAX) ++ n = STR_SIZE_MAX; + x->ptr = GC_MALLOC_ATOMIC(n); + x->area_size = n; + x->length = n - 1; +- bcopy((void *)p, (void *)x->ptr, n); ++ bcopy((void *)p, (void *)x->ptr, n - 1); ++ x->ptr[x->length] = '\0'; + return x; + } + +@@ -96,6 +101,8 @@ Strnew_charp_n(const char *p, int n) + if (p == NULL) + return Strnew_size(n); + x = GC_MALLOC(sizeof(struct _Str)); ++ if (n < 0 || n >= STR_SIZE_MAX) ++ n = STR_SIZE_MAX - 1; + x->ptr = GC_MALLOC_ATOMIC(n + 1); + x->area_size = n + 1; + x->length = n; +@@ -149,15 +156,19 @@ Strcopy_charp(Str x, const char *y) + STR_LENGTH_CHECK(x); + if (y == NULL) { + x->length = 0; ++ x->ptr[0] = '\0'; + return; + } + len = strlen(y); ++ if (len < 0 || len >= STR_SIZE_MAX) ++ len = STR_SIZE_MAX - 1; + if (x->area_size < len + 1) { + GC_free(x->ptr); + x->ptr = GC_MALLOC_ATOMIC(len + 1); + x->area_size = len + 1; + } +- bcopy((void *)y, (void *)x->ptr, len + 1); ++ bcopy((void *)y, (void *)x->ptr, len); ++ x->ptr[len] = '\0'; + x->length = len; + } + +@@ -169,16 +180,19 @@ Strcopy_charp_n(Str x, const char *y, int n) + STR_LENGTH_CHECK(x); + if (y == NULL) { + x->length = 0; ++ x->ptr[0] = '\0'; + return; + } ++ if (len < 0 || len >= STR_SIZE_MAX) ++ len = STR_SIZE_MAX - 1; + if (x->area_size < len + 1) { + GC_free(x->ptr); + x->ptr = GC_MALLOC_ATOMIC(len + 1); + x->area_size = len + 1; + } +- bcopy((void *)y, (void *)x->ptr, n); +- x->ptr[n] = '\0'; +- x->length = n; ++ bcopy((void *)y, (void *)x->ptr, len); ++ x->ptr[len] = '\0'; ++ x->length = len; + } + + void +@@ -189,10 +203,18 @@ Strcat_charp_n(Str x, const char *y, int n) + STR_LENGTH_CHECK(x); + if (y == NULL) + return; ++ if (n < 0) ++ n = STR_SIZE_MAX - 1; + newlen = x->length + n + 1; ++ if (newlen < 0 || newlen > STR_SIZE_MAX) { ++ newlen = STR_SIZE_MAX; ++ n = newlen - x->length - 1; ++ } + if (x->area_size < newlen) { + char *old = x->ptr; + newlen = newlen * 3 / 2; ++ if (newlen < 0 || newlen > STR_SIZE_MAX) ++ newlen = STR_SIZE_MAX; + x->ptr = GC_MALLOC_ATOMIC(newlen); + x->area_size = newlen; + bcopy((void *)old, (void *)x->ptr, x->length); +@@ -237,9 +259,12 @@ Strgrow(Str x) + newlen = x->area_size * 6 / 5; + if (newlen == x->area_size) + newlen += 2; ++ if (newlen < 0 || newlen > STR_SIZE_MAX) ++ newlen = STR_SIZE_MAX; + x->ptr = GC_MALLOC_ATOMIC(newlen); + x->area_size = newlen; + bcopy((void *)old, (void *)x->ptr, x->length); ++ x->ptr[x->length] = '\0'; + GC_free(old); + } + +@@ -315,6 +340,10 @@ Strdelete(Str s, int pos, int n) + { + int i; + STR_LENGTH_CHECK(s); ++ if (pos < 0 || s->length < pos) ++ return; ++ if (n < 0) ++ n = STR_SIZE_MAX - pos - 1; + if (s->length <= pos + n) { + s->ptr[pos] = '\0'; + s->length = pos; +@@ -330,6 +359,8 @@ void + Strtruncate(Str s, int pos) + { + STR_LENGTH_CHECK(s); ++ if (pos < 0 || s->length < pos) ++ return; + s->ptr[pos] = '\0'; + s->length = pos; + } +@@ -342,7 +373,7 @@ Strshrink(Str s, int n) + s->length = 0; + s->ptr[0] = '\0'; + } +- else { ++ else if (n > 0) { + s->length -= n; + s->ptr[s->length] = '\0'; + } diff --git a/debian/patches/series b/debian/patches/series index ceb9913..b829509 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1,2 +1,3 @@ 010_section.patch 020_ssl-ca.patch +030_str-overflow.patch |