gfileutils: Fix a potential integer overflow

When calculating the array sizes in get_contents_stdio(), there is a
possibility of overflow for very large files. Rearrange the overflow
checks to avoid this.

The code already handled some possibilities of files being too large, so
no new GError has been added to handle this; the existing
G_FILE_ERROR_FAILED is re-used.

Found by scan-build.

https://bugzilla.gnome.org/show_bug.cgi?id=715164
This commit is contained in:
Philip Withnall 2013-11-25 14:06:01 +00:00
parent c1d5db6186
commit 33dd6d12d7

View File

@ -614,7 +614,7 @@ get_contents_stdio (const gchar *display_filename,
GError **error)
{
gchar buf[4096];
gsize bytes;
gsize bytes; /* always <= sizeof(buf) */
gchar *str = NULL;
gsize total_bytes = 0;
gsize total_allocated = 0;
@ -629,12 +629,22 @@ get_contents_stdio (const gchar *display_filename,
bytes = fread (buf, 1, sizeof (buf), f);
save_errno = errno;
while ((total_bytes + bytes + 1) > total_allocated)
if (total_bytes > G_MAXSIZE - bytes)
goto file_too_large;
/* Possibility of overflow eliminated above. */
while (total_bytes + bytes >= total_allocated)
{
if (str)
total_allocated *= 2;
{
if (total_allocated > G_MAXSIZE / 2)
goto file_too_large;
total_allocated *= 2;
}
else
total_allocated = MIN (bytes + 1, sizeof (buf));
{
total_allocated = MIN (bytes + 1, sizeof (buf));
}
tmp = g_try_realloc (str, total_allocated);
@ -665,19 +675,9 @@ get_contents_stdio (const gchar *display_filename,
goto error;
}
g_assert (str != NULL);
memcpy (str + total_bytes, buf, bytes);
if (total_bytes + bytes < total_bytes)
{
g_set_error (error,
G_FILE_ERROR,
G_FILE_ERROR_FAILED,
_("File \"%s\" is too large"),
display_filename);
goto error;
}
total_bytes += bytes;
}
@ -698,6 +698,13 @@ get_contents_stdio (const gchar *display_filename,
return TRUE;
file_too_large:
g_set_error (error,
G_FILE_ERROR,
G_FILE_ERROR_FAILED,
_("File \"%s\" is too large"),
display_filename);
error:
g_free (str);