adds integer overflow checks to sstrlen and sstrcat

Sun, 21 Jan 2018 10:57:32 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 21 Jan 2018 10:57:32 +0100
changeset 272
2def28b65328
parent 271
47b8ea435902
child 273
9c1591b3c4a4

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
     1.1 --- a/src/string.c	Sun Jan 21 10:14:47 2018 +0100
     1.2 +++ b/src/string.c	Sun Jan 21 10:57:32 2018 +0100
     1.3 @@ -57,6 +57,10 @@
     1.4  
     1.5      for (size_t i = 1 ; i < n ; i++) {
     1.6          sstr_t str = va_arg(ap, sstr_t);
     1.7 +        if(((size_t)-1) - str.length < size) {
     1.8 +            size = 0;
     1.9 +            break;
    1.10 +        }
    1.11          size += str.length;
    1.12      }
    1.13      va_end(ap);
    1.14 @@ -77,6 +81,10 @@
    1.15          return str;
    1.16      }
    1.17      
    1.18 +    if(((size_t)-1) - s1.length < s2.length) {
    1.19 +        return str;
    1.20 +    }
    1.21 +    
    1.22      sstr_t *strings = (sstr_t*) calloc(count, sizeof(sstr_t));
    1.23      if(!strings) {
    1.24          return str;
    1.25 @@ -85,16 +93,25 @@
    1.26      // get all args and overall length
    1.27      strings[0] = s1;
    1.28      strings[1] = s2;
    1.29 -    size_t strlen = s1.length + s2.length;
    1.30 +    size_t slen = s1.length + s2.length;
    1.31 +    int error = 0;
    1.32      for (size_t i=2;i<count;i++) {
    1.33          sstr_t s = va_arg (ap, sstr_t);
    1.34          strings[i] = s;
    1.35 -        strlen += s.length;
    1.36 +        if(((size_t)-1) - s.length < slen) {
    1.37 +            error = 1;
    1.38 +            break;
    1.39 +        }
    1.40 +        slen += s.length;
    1.41 +    }
    1.42 +    if(error) {
    1.43 +        free(strings);
    1.44 +        return str;
    1.45      }
    1.46      
    1.47      // create new string
    1.48 -    str.ptr = (char*) almalloc(a, strlen + 1);
    1.49 -    str.length = strlen;
    1.50 +    str.ptr = (char*) almalloc(a, slen + 1);
    1.51 +    str.length = slen;
    1.52      if(!str.ptr) {
    1.53          free(strings);
    1.54          str.length = 0;
     2.1 --- a/test/string_tests.c	Sun Jan 21 10:14:47 2018 +0100
     2.2 +++ b/test/string_tests.c	Sun Jan 21 10:57:32 2018 +0100
     2.3 @@ -193,6 +193,21 @@
     2.4      UCX_TEST_ASSERT(t4.length == 0, "t4 has wrong length");
     2.5      free(t4.ptr);
     2.6      
     2.7 +    // overflow test
     2.8 +    sstr_t o0;
     2.9 +    o0.ptr = "";
    2.10 +    o0.length = ((size_t)-1) - 50;
    2.11 +    sstr_t o1;
    2.12 +    o1.ptr = "";
    2.13 +    o1.length = 100;
    2.14 +    sstr_t o2;
    2.15 +    o2.ptr = "";
    2.16 +    o2.length = 10;
    2.17 +    
    2.18 +    sstr_t n = sstrcat(2, o0, o1);
    2.19 +    UCX_TEST_ASSERT(n.ptr == NULL && n.length == 0, "overflow not detected");
    2.20 +    sstr_t n2 = sstrcat(3, o0, o2, o1);
    2.21 +    UCX_TEST_ASSERT(n2.ptr == NULL && n2.length == 0, "n2: overflow not detected");
    2.22              
    2.23      UCX_TEST_END
    2.24      

mercurial