darray: check integer overflow 07/318207/3 accepted/tizen_unified accepted/tizen_unified_x tizen accepted/tizen/unified/20240927.171126 accepted/tizen/unified/x/20240929.082835
authorduna.oh <duna.oh@samsung.com>
Wed, 25 Sep 2024 11:27:11 +0000 (20:27 +0900)
committerduna.oh <duna.oh@samsung.com>
Fri, 27 Sep 2024 02:29:20 +0000 (11:29 +0900)
In commit b9b3593cbdeb7f5b02d50cecaba6a0b47d4979ad,
darray is changed to use unsigned int instead of size_t
to reduce memory usage.
However, an integer overflow may occur due to arithmetic operation
(addition) between values.

To address this issue, this commit adds checks if this sums don't
exceed their type's maximum value.

Change-Id: Iaa689bb3beff0f991c8b9b6d8fc541f971d8c735

src/darray.h

index b75d85f..1fcce2b 100644 (file)
@@ -97,8 +97,11 @@ typedef darray (unsigned long)  darray_ulong;
 
 #define darray_append_items(arr, items, count) do { \
     unsigned __count = (count), __oldSize = (arr).size; \
-    darray_resize(arr, __oldSize + __count); \
-    memcpy((arr).item + __oldSize, items, __count * sizeof(*(arr).item)); \
+    size_t __total_size = __oldSize + __count; \
+    if (__total_size <= UINT32_MAX) { \
+        darray_resize(arr, __oldSize + __count); \
+        memcpy((arr).item + __oldSize, items, __count * sizeof(*(arr).item)); \
+    } \
 } while (0)
 
 #define darray_from_items(arr, items, count) do { \
@@ -134,18 +137,24 @@ typedef darray (unsigned long)  darray_ulong;
 
 #define darray_appends_nullterminate(arr, items, count) do { \
     unsigned __count = (count), __oldSize = (arr).size; \
-    darray_resize(arr, __oldSize + __count + 1); \
-    memcpy((arr).item + __oldSize, items, __count * sizeof(*(arr).item)); \
-    (arr).item[--(arr).size] = 0; \
+    size_t __total_size = __oldSize + __count + 1; \
+    if (__total_size <= UINT32_MAX) { \
+        darray_resize(arr, __oldSize + __count + 1); \
+        memcpy((arr).item + __oldSize, items, __count * sizeof(*(arr).item)); \
+        (arr).item[--(arr).size] = 0; \
+    } \
 } while (0)
 
 #define darray_prepends_nullterminate(arr, items, count) do { \
     unsigned __count = (count), __oldSize = (arr).size; \
-    darray_resize(arr, __count + __oldSize + 1); \
-    memmove((arr).item + __count, (arr).item, \
-            __oldSize * sizeof(*(arr).item)); \
-    memcpy((arr).item, items, __count * sizeof(*(arr).item)); \
-    (arr).item[--(arr).size] = 0; \
+    size_t __total_size = __count + __oldSize + 1; \
+    if (__total_size <= UINT32_MAX) { \
+        darray_resize(arr, __count + __oldSize + 1); \
+        memmove((arr).item + __count, (arr).item, \
+                __oldSize * sizeof(*(arr).item)); \
+        memcpy((arr).item, items, __count * sizeof(*(arr).item)); \
+        (arr).item[--(arr).size] = 0; \
+    } \
 } while (0)
 
 /*** Size management ***/