mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-03-03 06:32:10 +01:00
gio: Prevent hang writing to a large GMemoryBuffer
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
This commit is contained in:
parent
5a6f13d16f
commit
226c292b6a
@ -204,12 +204,12 @@ g_memory_buffer_read_uint64 (GMemoryBuffer *mbuf)
|
|||||||
|
|
||||||
#define MIN_ARRAY_SIZE 128
|
#define MIN_ARRAY_SIZE 128
|
||||||
|
|
||||||
static gint
|
static gsize
|
||||||
g_nearest_pow (gint num)
|
g_nearest_pow (gsize num)
|
||||||
{
|
{
|
||||||
gint n = 1;
|
gsize n = 1;
|
||||||
|
|
||||||
while (n < num)
|
while (n < num && n > 0)
|
||||||
n <<= 1;
|
n <<= 1;
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
@ -261,12 +261,10 @@ g_memory_buffer_write (GMemoryBuffer *mbuf,
|
|||||||
TODO: This wastes a lot of memory at large buffer sizes.
|
TODO: This wastes a lot of memory at large buffer sizes.
|
||||||
Figure out a more rational allocation strategy. */
|
Figure out a more rational allocation strategy. */
|
||||||
new_size = g_nearest_pow (mbuf->pos + count);
|
new_size = g_nearest_pow (mbuf->pos + count);
|
||||||
/* Check for overflow again. We have only checked if
|
/* Check for overflow again. We have checked if
|
||||||
pos + count > G_MAXSIZE, but it only catches the case of writing
|
pos + count > G_MAXSIZE, but now check if g_nearest_pow () has
|
||||||
more than 4GiB total on a 32-bit system. There's still the problem
|
overflowed */
|
||||||
of g_nearest_pow overflowing above 0x7fffffff, so we're
|
if (new_size == 0)
|
||||||
effectively limited to 2GiB. */
|
|
||||||
if (new_size < mbuf->len)
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
new_size = MAX (new_size, MIN_ARRAY_SIZE);
|
new_size = MAX (new_size, MIN_ARRAY_SIZE);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user