From 374a1895b62b2504d0b6ae1c404237802e73ddb6 Mon Sep 17 00:00:00 2001
From: Tobias Stoeckmann <tobias@stoeckmann.org>
Date: Tue, 18 Jan 2022 13:45:13 +0000
Subject: [PATCH] garray: Fix integer overflows in element capacity
 calculations

Integer overflows in size calculations of buffers (GArray and GPtrArray)
allow subsequent buffer overflows. This happens due to conversions
between gsize and guint.

Proof of concept demonstrations of the overflows can be found in issue
2578. They are not being added as unit tests as they require too much
memory to test.

This will affect `GArray`s which are 4GB in size, or `GPtrArray`s which
are 48GB in size.

Fixes: #2578

Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/374a1895b62b2504d0b6ae1c404237802e73ddb6

---
 glib/garray.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/glib/garray.c b/glib/garray.c
index 3803fee037..b441562154 100644
--- a/glib/garray.c
+++ b/glib/garray.c
@@ -1001,7 +1001,7 @@ g_array_maybe_expand (GRealArray *array,
         memset (g_array_elt_pos (array, array->elt_capacity), 0,
                 g_array_elt_len (array, want_len - array->elt_capacity));
 
-      array->elt_capacity = want_alloc / array->elt_size;
+      array->elt_capacity = MIN (want_alloc / array->elt_size, G_MAXUINT);
     }
 }
 
@@ -1518,9 +1518,10 @@ g_ptr_array_maybe_expand (GRealPtrArray *array,
   if ((array->len + len) > array->alloc)
     {
       guint old_alloc = array->alloc;
-      array->alloc = g_nearest_pow (array->len + len);
-      array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE);
-      array->pdata = g_realloc (array->pdata, sizeof (gpointer) * array->alloc);
+      gsize want_alloc = g_nearest_pow (sizeof (gpointer) * (array->len + len));
+      want_alloc = MAX (want_alloc, MIN_ARRAY_SIZE);
+      array->alloc = MIN (want_alloc / sizeof (gpointer), G_MAXUINT);
+      array->pdata = g_realloc (array->pdata, want_alloc);
       if (G_UNLIKELY (g_mem_gc_friendly))
         for ( ; old_alloc < array->alloc; old_alloc++)
           array->pdata [old_alloc] = NULL;
-- 
GitLab

