Prevent size overflow 75/188575/3
authorHwankyu Jhun <h.jhun@samsung.com>
Thu, 6 Sep 2018 07:06:53 +0000 (16:06 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Fri, 7 Sep 2018 04:51:37 +0000 (13:51 +0900)
Change-Id: I3b1fcf07f9fd6a0a97e5610ceb4fb8474889381a
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
src/keyval.c
src/keyval_array.c

index d49be0e..279d469 100755 (executable)
@@ -151,17 +151,29 @@ int keyval_compare(keyval_t *kv1, keyval_t *kv2)
 
 size_t keyval_get_encoded_size(keyval_t *kv)
 {
-       size_t encoded_size;
+       size_t encoded_size = 0;
 
        if (!kv)
                return 0;
 
-       encoded_size = sizeof(size_t)   /* total size */
-               + sizeof(int)           /* type */
-               + sizeof(size_t)        /* key size */
-               + strlen(kv->key) + 1   /* key (+ null byte) */
-               + sizeof(size_t)        /* size */
-               + kv->size;             /* val */
+       encoded_size += sizeof(size_t); /* total size */
+       encoded_size += sizeof(int); /* type */
+       encoded_size += sizeof(size_t); /* key size */
+
+       if ((encoded_size + strlen(kv->key) + 1) < encoded_size)
+               return 0;
+
+       encoded_size += strlen(kv->key) + 1; /* key */
+
+       if ((encoded_size + sizeof(size_t)) < encoded_size)
+               return 0;
+
+       encoded_size += sizeof(size_t); /* size */
+
+       if ((encoded_size + kv->size) < encoded_size)
+               return 0;
+
+       encoded_size += kv->size; /* val */
 
        return encoded_size;
 }
@@ -186,6 +198,8 @@ size_t keyval_encode(keyval_t *kv, unsigned char **byte, size_t *byte_len)
        unsigned char *p;
 
        *byte_len = keyval_get_encoded_size(kv);
+       if (*byte_len == 0)
+               return 0;
 
        *byte = calloc(1, *byte_len);
        if (!*byte)
index 7c4fe56..b30ed09 100755 (executable)
@@ -267,18 +267,38 @@ size_t keyval_array_get_encoded_size(keyval_array_t *kva)
 {
        size_t sum_array_element_size = 0;
        int i;
-       size_t encoded_size;
+       size_t encoded_size = 0;
+
+       encoded_size += sizeof(size_t); /* total size */
+       encoded_size += sizeof(int); /* type */
+       encoded_size += sizeof(size_t); /* key size */
+
+       if ((encoded_size + strlen(((keyval_t *)kva)->key) + 1) < encoded_size)
+               return 0;
+
+       encoded_size += strlen(((keyval_t *)kva)->key) + 1; /* key */
+
+       if ((encoded_size + sizeof(int)) < encoded_size)
+               return 0;
+
+       encoded_size += sizeof(int); /* len */
+
+       if ((encoded_size + (kva->len * sizeof(size_t))) < encoded_size)
+               return 0;
+
+       encoded_size += kva->len * sizeof(size_t); /* array_element_size */
+
+       for (i = 0; i < kva->len; i++) {
+               if ((sum_array_element_size + kva->array_element_size[i]) < sum_array_element_size)
+                       return 0;
 
-       for (i = 0; i < kva->len; i++)
                sum_array_element_size += kva->array_element_size[i];
+       }
 
-       encoded_size = sizeof(size_t) /* total size */
-               + sizeof(int)    /* type */
-               + sizeof(size_t) /* keysize */
-               + strlen(((keyval_t *)kva)->key) + 1 /* key (+ null byte) */
-               + sizeof(int)    /* len */
-               + kva->len * sizeof(size_t)     /* array_element_size */
-               + sum_array_element_size;
+       if ((encoded_size + sum_array_element_size) < encoded_size)
+               return 0;
+
+       encoded_size += sum_array_element_size;
 
        return encoded_size;
 }
@@ -293,14 +313,13 @@ size_t keyval_array_encode(keyval_array_t *kva, void **byte, size_t *byte_len)
        size_t sz_key = strlen(kv->key) + 1;
        static const unsigned int sz_len = sizeof(int);
        size_t sz_array_element_size = kva->len * sizeof(size_t);
-       size_t sz_array_val = 0;
        unsigned char *p;
 
-       for (i = 0; i < kva->len; i++)
-               sz_array_val += kva->array_element_size[i];
-
        /* Allocate memory */
        *byte_len = keyval_array_get_encoded_size(kva);
+       if (*byte_len == 0)
+               return 0;
+
        *byte = calloc(1, *byte_len);
        if (!*byte)
                return 0;
@@ -395,8 +414,12 @@ size_t keyval_array_decode(void *byte, keyval_array_t **kva, size_t byte_size)
        p += sizeof(size_t) * len;
        array_val = (void *)p;
 
-       for (i = 0; i < len; ++i)
+       for (i = 0; i < len; ++i) {
+               if ((sum_array_element_size + array_element_size[i]) < sum_array_element_size)
+                       return 0;
+
                sum_array_element_size += array_element_size[i];
+       }
 
        encoded_size = sz_byte_len + sz_type + sz_keysize + keysize +
                sz_len + (sizeof(size_t) * len) + sum_array_element_size;