g_file_load_contents reads large (>4GiB) files past end of array due to gsize to guint truncation
I ran into a segmentation fault in glib on a program calling g_file_load_contents
on a file larger than 4 GiB.
This is due to g_file_load_contents
tracking the length in a gsize
, while GByteArray
uses guint
and only supports 32-bit lengths. If this function is called on a large file, pos
is advanced past 2^32, then passed to g_byte_array_set_size
, causing it to wrap, so no reallocation is performed. On the next call to g_input_stream_read
, it reads from the file into memory beyond the allocated region.
To fix this, there should be a check before g_byte_array_set_size
. Something like
pos += res;
if (pos >= G_MAXUINT - GET_CONTENT_BLOCK_SIZE - 1)
{
g_set_error(error, ...);
res = -1;
break;
}
g_byte_array_set_size (content, pos + GET_CONTENT_BLOCK_SIZE + 1);
I'm not sure of the security implications, but it seems likely that this function is used to load user input files, which could be used to overwrite application memory.