gio: Prevent hang writing to a large GMemoryBuffer
authorRoss Lagerwall <rosslagerwall@gmail.com>
Wed, 29 Oct 2014 22:12:39 +0000 (22:12 +0000)
committerRoss Lagerwall <rosslagerwall@gmail.com>
Thu, 30 Oct 2014 20:15:47 +0000 (20:15 +0000)
Fix a hang due to overflow by using unsigned numbers and explicitly
checking if the number overflows to zero.  This also fixes the previous
logic which assigned an int which may be negative to an unsigned number
resulting in sign extension and strange results.

Use gsize rather than int to allow for large buffers on 64 bit machines.

https://bugzilla.gnome.org/show_bug.cgi?id=727988

gio/gdbusmessage.c

index 5ad86940faceda89b90f51ed34092f6a644de736..766609ec8a384015bd6a92b8aec473f96aa13130 100644 (file)
@@ -204,12 +204,12 @@ g_memory_buffer_read_uint64 (GMemoryBuffer  *mbuf)
 
 #define MIN_ARRAY_SIZE  128
 
-static gint
-g_nearest_pow (gint num)
+static gsize
+g_nearest_pow (gsize num)
 {
-  gint n = 1;
+  gsize n = 1;
 
-  while (n < num)
+  while (n < num && n > 0)
     n <<= 1;
 
   return n;
@@ -261,12 +261,10 @@ g_memory_buffer_write (GMemoryBuffer  *mbuf,
          TODO: This wastes a lot of memory at large buffer sizes.
                Figure out a more rational allocation strategy. */
       new_size = g_nearest_pow (mbuf->pos + count);
-      /* Check for overflow again. We have only checked if
-         pos + count > G_MAXSIZE, but it only catches the case of writing
-         more than 4GiB total on a 32-bit system. There's still the problem
-         of g_nearest_pow overflowing above 0x7fffffff, so we're
-         effectively limited to 2GiB. */
-      if (new_size < mbuf->len)
+      /* Check for overflow again. We have checked if
+         pos + count > G_MAXSIZE, but now check if g_nearest_pow () has
+         overflowed */
+      if (new_size == 0)
         return FALSE;
 
       new_size = MAX (new_size, MIN_ARRAY_SIZE);