Sun, 21 Jan 2018 10:57:32 +0100
adds integer overflow checks to sstrlen and sstrcat
src/string.c | file | annotate | diff | comparison | revisions | |
test/string_tests.c | file | annotate | diff | comparison | revisions |
--- a/src/string.c Sun Jan 21 10:14:47 2018 +0100 +++ b/src/string.c Sun Jan 21 10:57:32 2018 +0100 @@ -57,6 +57,10 @@ for (size_t i = 1 ; i < n ; i++) { sstr_t str = va_arg(ap, sstr_t); + if(((size_t)-1) - str.length < size) { + size = 0; + break; + } size += str.length; } va_end(ap); @@ -77,6 +81,10 @@ return str; } + if(((size_t)-1) - s1.length < s2.length) { + return str; + } + sstr_t *strings = (sstr_t*) calloc(count, sizeof(sstr_t)); if(!strings) { return str; @@ -85,16 +93,25 @@ // get all args and overall length strings[0] = s1; strings[1] = s2; - size_t strlen = s1.length + s2.length; + size_t slen = s1.length + s2.length; + int error = 0; for (size_t i=2;i<count;i++) { sstr_t s = va_arg (ap, sstr_t); strings[i] = s; - strlen += s.length; + if(((size_t)-1) - s.length < slen) { + error = 1; + break; + } + slen += s.length; + } + if(error) { + free(strings); + return str; } // create new string - str.ptr = (char*) almalloc(a, strlen + 1); - str.length = strlen; + str.ptr = (char*) almalloc(a, slen + 1); + str.length = slen; if(!str.ptr) { free(strings); str.length = 0;
--- a/test/string_tests.c Sun Jan 21 10:14:47 2018 +0100 +++ b/test/string_tests.c Sun Jan 21 10:57:32 2018 +0100 @@ -193,6 +193,21 @@ UCX_TEST_ASSERT(t4.length == 0, "t4 has wrong length"); free(t4.ptr); + // overflow test + sstr_t o0; + o0.ptr = ""; + o0.length = ((size_t)-1) - 50; + sstr_t o1; + o1.ptr = ""; + o1.length = 100; + sstr_t o2; + o2.ptr = ""; + o2.length = 10; + + sstr_t n = sstrcat(2, o0, o1); + UCX_TEST_ASSERT(n.ptr == NULL && n.length == 0, "overflow not detected"); + sstr_t n2 = sstrcat(3, o0, o2, o1); + UCX_TEST_ASSERT(n2.ptr == NULL && n2.length == 0, "n2: overflow not detected"); UCX_TEST_END