[glib] gfileutils: Fix a potential integer overflow
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] gfileutils: Fix a potential integer overflow
- Date: Wed, 27 Nov 2013 10:06:11 +0000 (UTC)
commit 33dd6d12d7478df22b7759f0ed26f81187ad2a54
Author: Philip Withnall <philip withnall collabora co uk>
Date: Mon Nov 25 14:06:01 2013 +0000
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
glib/gfileutils.c | 37 ++++++++++++++++++++++---------------
1 files changed, 22 insertions(+), 15 deletions(-)
---
diff --git a/glib/gfileutils.c b/glib/gfileutils.c
index fb47fc8..0db964a 100644
--- a/glib/gfileutils.c
+++ b/glib/gfileutils.c
@@ -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);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]