Re: RFA/RFC: Add stack recursion limit to libiberty's demangler [v5]

2018-12-07 Thread H.J. Lu
On Thu, Dec 6, 2018 at 10:04 AM Ian Lance Taylor via gcc-patches
 wrote:
>
> On Thu, Dec 6, 2018 at 3:12 AM Nick Clifton  wrote:
> >
> >   Is the patch OK with you ?
>

This caused:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88409


-- 
H.J.


Re: RFA/RFC: Add stack recursion limit to libiberty's demangler [v5]

2018-12-06 Thread Ian Lance Taylor via gcc-patches
On Thu, Dec 6, 2018 at 3:12 AM Nick Clifton  wrote:
>
>   Is the patch OK with you ?

Yes, thanks.

Ian


Re: RFA/RFC: Add stack recursion limit to libiberty's demangler [v5]

2018-12-06 Thread Jason Merrill

On 12/4/18 11:56 AM, Nick Clifton wrote:

OK, revised (v5) patch attached.  Is this version acceptable to all ?


Looks good to me.  Independently, do you see a reason not to disable the 
old demangler entirely?


Jason


Re: RFA/RFC: Add stack recursion limit to libiberty's demangler [v5]

2018-12-06 Thread Nick Clifton
Hi Ian,

  Is the patch OK with you ?

Cheers
  Nick


Re: RFA/RFC: Add stack recursion limit to libiberty's demangler [v5]

2018-12-04 Thread Pedro Alves
On 12/04/2018 04:56 PM, Nick Clifton wrote:
> Hi Pedro,
> 
>> The issue pointed out by
>>
>>  https://gcc.gnu.org/ml/gcc-patches/2018-11/msg02592.html
>>
>> is still present in this version.
> 
> Doh!  Yes I meant to fix that one too, but forgot.
> 
>> Also, noticed a typo here:
>>
>>> +/* If DMGL_NO_RECURE_LIMIT is not enabled, then this is the value used as
>>
>> Typo: "RECURE"
> 
> Oops - thanks.
> 
> OK, revised (v5) patch attached.  Is this version acceptable to all ?
> 
This is fine with me.

Thanks,
Pedro Alves


Re: RFA/RFC: Add stack recursion limit to libiberty's demangler [v5]

2018-12-04 Thread Nick Clifton
Hi Pedro,

> The issue pointed out by
> 
>  https://gcc.gnu.org/ml/gcc-patches/2018-11/msg02592.html
> 
> is still present in this version.

Doh!  Yes I meant to fix that one too, but forgot.

> Also, noticed a typo here:
> 
>> +/* If DMGL_NO_RECURE_LIMIT is not enabled, then this is the value used as
> 
> Typo: "RECURE"

Oops - thanks.

OK, revised (v5) patch attached.  Is this version acceptable to all ?

Cheers
  Nick

Index: include/demangle.h
===
--- include/demangle.h	(revision 266771)
+++ include/demangle.h	(working copy)
@@ -68,6 +68,17 @@
 /* If none of these are set, use 'current_demangling_style' as the default. */
 #define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM|DMGL_HP|DMGL_EDG|DMGL_GNU_V3|DMGL_JAVA|DMGL_GNAT|DMGL_DLANG|DMGL_RUST)
 
+/* Disable a limit on the depth of recursion in mangled strings.
+   Note if this limit is disabled then stack exhaustion is possible when
+   demangling pathologically complicated strings.  Bug reports about stack
+   exhaustion when the option is enabled will be rejected.  */  
+#define DMGL_NO_RECURSE_LIMIT (1 << 18)	
+
+/* If DMGL_NO_RECURSE_LIMIT is not enabled, then this is the value used as
+   the maximum depth of recursion allowed.  It should be enough for any
+   real-world mangled name.  */
+#define DEMANGLE_RECURSION_LIMIT 1024
+  
 /* Enumeration of possible demangling styles.
 
Lucid and ARM styles are still kept logically distinct, even though
Index: libiberty/cp-demangle.c
===
--- libiberty/cp-demangle.c	(revision 266771)
+++ libiberty/cp-demangle.c	(working copy)
@@ -2852,21 +2852,35 @@
 static struct demangle_component *
 d_function_type (struct d_info *di)
 {
-  struct demangle_component *ret;
+  struct demangle_component *ret = NULL;
 
-  if (! d_check_char (di, 'F'))
-return NULL;
-  if (d_peek_char (di) == 'Y')
+  if ((di->options & DMGL_NO_RECURSE_LIMIT) == 0)
 {
-  /* Function has C linkage.  We don't print this information.
-	 FIXME: We should print it in verbose mode.  */
-  d_advance (di, 1);
+  if (di->recursion_level > DEMANGLE_RECURSION_LIMIT)
+	/* FIXME: There ought to be a way to report
+	   that the recursion limit has been reached.  */
+	return NULL;
+
+  di->recursion_level ++;
 }
-  ret = d_bare_function_type (di, 1);
-  ret = d_ref_qualifier (di, ret);
 
-  if (! d_check_char (di, 'E'))
-return NULL;
+  if (d_check_char (di, 'F'))
+{
+  if (d_peek_char (di) == 'Y')
+	{
+	  /* Function has C linkage.  We don't print this information.
+	 FIXME: We should print it in verbose mode.  */
+	  d_advance (di, 1);
+	}
+  ret = d_bare_function_type (di, 1);
+  ret = d_ref_qualifier (di, ret);
+  
+  if (! d_check_char (di, 'E'))
+	ret = NULL;
+}
+
+  if ((di->options & DMGL_NO_RECURSE_LIMIT) == 0)
+di->recursion_level --;
   return ret;
 }
 
@@ -6203,6 +6217,7 @@
   di->expansion = 0;
   di->is_expression = 0;
   di->is_conversion = 0;
+  di->recursion_level = 0;
 }
 
 /* Internal implementation for the demangler.  If MANGLED is a g++ v3 ABI
@@ -6242,6 +6257,20 @@
 
   cplus_demangle_init_info (mangled, options, strlen (mangled), );
 
+  /* PR 87675 - Check for a mangled string that is so long
+ that we do not have enough stack space to demangle it.  */
+  if (((options & DMGL_NO_RECURSE_LIMIT) == 0)
+  /* This check is a bit arbitrary, since what we really want to do is to
+	 compare the sizes of the di.comps and di.subs arrays against the
+	 amount of stack space remaining.  But there is no portable way to do
+	 this, so instead we use the recursion limit as a guide to the maximum
+	 size of the arrays.  */
+  && (unsigned long) di.num_comps > DEMANGLE_RECURSION_LIMIT)
+{
+  /* FIXME: We need a way to indicate that a stack limit has been reached.  */
+  return 0;
+}
+
   {
 #ifdef CP_DYNAMIC_ARRAYS
 __extension__ struct demangle_component comps[di.num_comps];
Index: libiberty/cp-demangle.h
===
--- libiberty/cp-demangle.h	(revision 266771)
+++ libiberty/cp-demangle.h	(working copy)
@@ -122,6 +122,9 @@
   /* Non-zero if we are parsing the type operand of a conversion
  operator, but not when in an expression.  */
   int is_conversion;
+  /* If DMGL_NO_RECURSE_LIMIT is not active then this is set to
+ the current recursion level.  */
+  unsigned int recursion_level;
 };
 
 /* To avoid running past the ending '\0', don't:
Index: libiberty/cplus-dem.c
===
--- libiberty/cplus-dem.c	(revision 266771)
+++ libiberty/cplus-dem.c	(working copy)
@@ -146,6 +146,7 @@
   int *proctypevec; /* Indices of currently processed remembered typevecs.  */
   int proctypevec_size;
   int nproctypes;
+  unsigned int recursion_level;
 };
 
 #define PRINT_ANSI_QUALIFIERS (work ->