This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Proposed Patch for Bug 69687
- From: Marcel Böhme <boehme dot marcel at gmail dot com>
- To: Bernd Schmidt <bschmidt at redhat dot com>
- Cc: Mike Stump <mikestump at comcast dot net>, gcc-patches at gcc dot gnu dot org
- Date: Thu, 31 Mar 2016 12:56:17 +0800
- Subject: Re: Proposed Patch for Bug 69687
- Authentication-results: sourceware.org; auth=none
- References: <EA6F36C4-86FE-4018-8CB0-D0F314C1528D at gmail dot com> <EBBC24E4-04F9-4A8F-9A5D-801BFF9009EF at comcast dot net> <66021953-4407-44D7-B252-0D2D685CF235 at gmail dot com> <56FA7396 dot 7060507 at redhat dot com>
Hi Bernd,
> Are all the places being patched really problematic ones where an input file could realistically cause an overflow, or just the string functions?
The loop in demangle_args allows to call the patched register*- and remember*-methods arbitrarily often. So, those should also overflow at some point.
Found a few other segmentation faults in libiberty that I’ll report and patch separately.
> I'm concerned about just returning without any kind of error indication. Not sure what we should be calling from libiberty, but I was thinking maybe xmalloc_failed.
Done. Now, clients of libiberty freeze for about 80 seconds and consume about 3GB of memory before exiting with "out of memory allocating 2147483647 bytes after a total of 3221147648 bytes”.
> Might also want to guard against overflow from the first addition.
Done.
Index: libiberty/cplus-dem.c
===================================================================
--- libiberty/cplus-dem.c (revision 234607)
+++ libiberty/cplus-dem.c (working copy)
@@ -55,6 +55,7 @@ Boston, MA 02110-1301, USA. */
void * malloc ();
void * realloc ();
#endif
+#include <limits.h>
#include <demangle.h>
#undef CURRENT_DEMANGLING_STYLE
@@ -4254,6 +4255,8 @@ remember_type (struct work_stuff *work,
}
else
{
+ if (work -> typevec_size > INT_MAX / 2)
+ xmalloc_failed (INT_MAX);
work -> typevec_size *= 2;
work -> typevec
= XRESIZEVEC (char *, work->typevec, work->typevec_size);
@@ -4281,6 +4284,8 @@ remember_Ktype (struct work_stuff *work,
}
else
{
+ if (work -> ksize > INT_MAX / 2)
+ xmalloc_failed (INT_MAX);
work -> ksize *= 2;
work -> ktypevec
= XRESIZEVEC (char *, work->ktypevec, work->ksize);
@@ -4310,6 +4315,8 @@ register_Btype (struct work_stuff *work)
}
else
{
+ if (work -> bsize > INT_MAX / 2)
+ xmalloc_failed (INT_MAX);
work -> bsize *= 2;
work -> btypevec
= XRESIZEVEC (char *, work->btypevec, work->bsize);
@@ -4764,6 +4771,8 @@ string_need (string *s, int n)
else if (s->e - s->p < n)
{
tem = s->p - s->b;
+ if (n > INT_MAX / 2 - tem)
+ xmalloc_failed (INT_MAX);
n += tem;
n *= 2;
s->b = XRESIZEVEC (char, s->b, n);