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
--- 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
     

mercurial