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 | 
