Fix keyval decode functions 31/147131/4
authorHwankyu Jhun <h.jhun@samsung.com>
Fri, 1 Sep 2017 05:59:24 +0000 (14:59 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Sun, 3 Sep 2017 23:19:58 +0000 (08:19 +0900)
- Adds byte size check to prevent buffer overflow
- Fixes wrong pointer type

Change-Id: I30a1b4ab25555327bac2a25861b247824efe7e85
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
src/bundle.c
src/keyval.c
src/keyval.h
src/keyval_array.c

index c766ee9..ac0725f 100644 (file)
@@ -508,6 +508,7 @@ bundle *bundle_decode(const bundle_raw *r, const int data_size)
        size_t bytes_read;
        keyval_t *kv;
        int type;
+       size_t byte_size;
 
        if (r == NULL) {
                set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
@@ -572,15 +573,17 @@ bundle *bundle_decode(const bundle_raw *r, const int data_size)
        while (p_r < d_r + d_len - 1) {
                kv = NULL;      /* To get a new kv */
 
+               byte_size = d_r + d_len - 1 - p_r;
+               if (byte_size < sizeof(size_t))
+                       break;
+
                /* Find type, and use decode function according to type */
                type = keyval_get_type_from_encoded_byte(p_r);
                if (keyval_type_is_array(type)) {
                        bytes_read = keyval_array_decode(p_r,
-                                       (keyval_array_t **)&kv,
-                                       d_r + d_len - 1 - p_r);
+                                       (keyval_array_t **)&kv, byte_size);
                } else {
-                       bytes_read = keyval_decode(p_r, &kv,
-                                       d_r + d_len - 1 - p_r);
+                       bytes_read = keyval_decode(p_r, &kv, byte_size);
                }
 
                if (kv)
@@ -670,6 +673,7 @@ bundle *bundle_decode_raw(const bundle_raw *r, const int data_size)
        size_t bytes_read;
        keyval_t *kv;
        int type;
+       size_t byte_size;
 
        if (r == NULL) {
                set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
@@ -717,15 +721,17 @@ bundle *bundle_decode_raw(const bundle_raw *r, const int data_size)
        while (p_r < d_r + d_len - 1) {
                kv = NULL;      /* To get a new kv */
 
+               byte_size = d_r + d_len - 1 - p_r;
+               if (byte_size < sizeof(size_t))
+                       break;
+
                /* Find type, and use decode function according to type */
                type = keyval_get_type_from_encoded_byte(p_r);
                if (keyval_type_is_array(type)) {
                        bytes_read = keyval_array_decode(p_r,
-                                       (keyval_array_t **)&kv,
-                                       d_r + d_len - 1 - p_r);
+                                       (keyval_array_t **)&kv, byte_size);
                } else {
-                       bytes_read = keyval_decode(p_r, &kv,
-                                       d_r + d_len - 1 - p_r);
+                       bytes_read = keyval_decode(p_r, &kv, byte_size);
                }
 
                if (kv)
@@ -870,6 +876,13 @@ bundle *bundle_import_from_argv(int argc, char **argv)
                        return NULL;
                }
 
+               if (byte_size < sizeof(size_t)) {
+                       free(byte);
+                       byte = NULL;
+                       byte_size = 0;
+                       continue;
+               }
+
                type = keyval_get_type_from_encoded_byte(byte);
                if (keyval_type_is_array(type)) {
                        if (keyval_array_decode(byte, &kva, byte_size) == 0) /* TODO: error! */
@@ -883,6 +896,7 @@ bundle *bundle_import_from_argv(int argc, char **argv)
 
                free(byte);
                byte = NULL;
+               byte_size = 0;
        }
 
        set_last_result(BUNDLE_ERROR_NONE);
index ee069c2..8c7a42f 100755 (executable)
@@ -223,6 +223,7 @@ size_t keyval_decode(unsigned char *byte, keyval_t **kv, size_t byte_size)
        size_t size;
        void *val;
        unsigned char *p = byte;
+       size_t encoded_size;
 
        byte_len = *((size_t *)p);
 
@@ -246,6 +247,8 @@ size_t keyval_decode(unsigned char *byte, keyval_t **kv, size_t byte_size)
        byte_size -= sz_keysize;
        p += sz_keysize;
        key = (char *)p;
+       if ((strlen(key) + 1) != keysize)
+               return 0;
 
        if (byte_size < keysize)
                return 0;
@@ -260,6 +263,12 @@ size_t keyval_decode(unsigned char *byte, keyval_t **kv, size_t byte_size)
        byte_size -= sz_size;
        p += sz_size;
        val = (void *)p;
+
+       encoded_size = sz_byte_len + sz_type + sz_keysize + keysize +
+               sz_size + size;
+       if (encoded_size != byte_len)
+               return 0;
+
        p += size;
 
        if (kv)
@@ -274,7 +283,7 @@ int keyval_get_type_from_encoded_byte(unsigned char *byte)
        unsigned char *p = byte;
        int type;
 
-        p += sz_byte_len;
+       p += sz_byte_len;
        type = *((int *)p);
 
        return type;
index 4cf3b6b..1116b6b 100755 (executable)
@@ -38,7 +38,8 @@ typedef size_t (*keyval_method_encode_t)(
                keyval_t *,
                unsigned char **byte,
                size_t *byte_len);
-typedef size_t (*keyval_method_decode_t)(unsigned char *byte, keyval_t **kv);
+typedef size_t (*keyval_method_decode_t)(unsigned char *byte, keyval_t **kv,
+               size_t byte_size);
 
 struct keyval_method_collection_t {
        keyval_method_free_t free;
index db9d9c0..013531c 100755 (executable)
@@ -335,6 +335,8 @@ size_t keyval_array_decode(void *byte, keyval_array_t **kva, size_t byte_size)
        void *array_val;
        int i;
        size_t elem_size = 0;
+       size_t sum_array_element_size = 0;
+       size_t encoded_size;
 
        /* Get data */
        byte_len = *((size_t *)p);
@@ -359,6 +361,8 @@ size_t keyval_array_decode(void *byte, keyval_array_t **kva, size_t byte_size)
        byte_size -= sz_keysize;
        p += sz_keysize;
        key = (char *)p;
+       if ((strlen(key) + 1) != keysize)
+               return 0;
 
        if (byte_size < keysize)
                return 0;
@@ -380,6 +384,14 @@ 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)
+               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;
+       if (encoded_size != byte_len)
+               return 0;
+
        *kva = keyval_array_new(NULL, key, type, NULL, len);
        for (i = 0; i < len; i++) {
                elem_size += i ? array_element_size[i - 1] : 0;