diff mbox

Proposed Patch for Bug 69687

Message ID 42533159-9D5B-476F-A209-44C81C2B9AA0@gmail.com
State New
Headers show

Commit Message

Marcel Böhme March 31, 2016, 4:56 a.m. UTC
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.

Comments

Bernd Schmidt April 1, 2016, 2:06 p.m. UTC | #1
On 03/31/2016 06:56 AM, Marcel Böhme wrote:
> 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

Forgot about this issue, sorry. At least this needs guarding with #ifdef 
HAVE_LIMITS_H, as in the other files in libiberty. Several of them also 
go to trouble to define the macros if limits.h is missing; not sure how 
much of an issue that is nowadays, but you might want to adapt something 
like the code from strtol.c:

#ifndef ULONG_MAX
#define ULONG_MAX       ((unsigned long)(~0L))          /* 0xFFFFFFFF */
#endif

#ifndef LONG_MAX
#define LONG_MAX        ((long)(ULONG_MAX >> 1))        /* 0x7FFFFFFF */
#endif

Mind trying that and doing a full test run as described in my other mail?


Bernd
diff mbox

Patch

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);