Hi Jason,

These test cases are generated by fuzzing which produces a lot of nonsensical 
input data. 
I think, "Garbage In, Garbage Out" is quite applicable here.
With the patch at least it doesn’t crash and fixes the vulnerability.

Best regards,
- Marcel

> On 26 May 2016, at 10:05 PM, Jason Merrill <ja...@redhat.com> wrote:
> 
> It seems like in cases of malformed input we should return the input
> again rather than produce garbage like "K<std::operator std::operator
>> ".  Maybe catch this sort of situation in
> d_lookup_template_parameter?
> 
> Jason
> 
> 
> On Mon, May 2, 2016 at 11:21 AM, Marcel Böhme <boehme.mar...@gmail.com> wrote:
>> Hi,
>> 
>> This fixes several stack overflows due to infinite recursion in d_print_comp 
>> (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70909).
>> 
>> The method d_print_comp in cp-demangle.c recursively constructs the 
>> d_print_info dpi from the demangle_component dc. The method 
>> d_print_comp_inner traverses dc as a graph. Now, dc can be a graph with 
>> cycles leading to infinite recursion in several distinct cases. The patch 
>> uses the component stack to find whether the current node dc has itself as 
>> ancestor more than once.
>> 
>> Bootstrapped and regression tested on x86_64-pc-linux-gnu. Test cases added 
>> to libiberty/testsuite/demangler-expected and checked PR70909 and related 
>> stack overflows are resolved.
>> 
>> Best regards,
>> - Marcel
>> 
>> 
>> 
>> Index: ChangeLog
>> ===================================================================
>> --- ChangeLog   (revision 235760)
>> +++ ChangeLog   (working copy)
>> @@ -1,3 +1,19 @@
>> +2016-05-02  Marcel Böhme  <boehme.mar...@gmail.com>
>> +
>> +       PR c++/70909
>> +       PR c++/61460
>> +       PR c++/68700
>> +       PR c++/67738
>> +       PR c++/68383
>> +       PR c++/70517
>> +       PR c++/61805
>> +       PR c++/62279
>> +       PR c++/67264
>> +       * cp-demangle.c: Prevent infinite recursion when traversing cyclic
>> +       demangle component.
>> +       (d_print_comp): Return when demangle component has itself as ancistor
>> +       more than once.
>> +
>> 2016-04-30  Oleg Endo  <olege...@gcc.gnu.org>
>> 
>>        * configure: Remove SH5 support.
>> Index: cp-demangle.c
>> ===================================================================
>> --- cp-demangle.c       (revision 235760)
>> +++ cp-demangle.c       (working copy)
>> @@ -5436,6 +5436,24 @@ d_print_comp (struct d_print_info *dpi, int option
>> {
>>   struct d_component_stack self;
>> 
>> +  self.parent = dpi->component_stack;
>> +
>> +  while (self.parent)
>> +    {
>> +      self.dc = self.parent->dc;
>> +      self.parent = self.parent->parent;
>> +      if (dc != NULL && self.dc == dc)
>> +       {
>> +         while (self.parent)
>> +           {
>> +             self.dc = self.parent->dc;
>> +             self.parent = self.parent->parent;
>> +             if (self.dc == dc)
>> +               return;
>> +           }
>> +       }
>> +    }
>> +
>>   self.dc = dc;
>>   self.parent = dpi->component_stack;
>>   dpi->component_stack = &self;
>> Index: testsuite/demangle-expected
>> ===================================================================
>> --- testsuite/demangle-expected (revision 235760)
>> +++ testsuite/demangle-expected (working copy)
>> @@ -4431,3 +4431,69 @@ _Q.__0
>> 
>> _Q10-__9cafebabe.
>> cafebabe.::-(void)
>> +#
>> +# Test demangler crash PR62279
>> +
>> +_ZN5Utils9transformIPN15ProjectExplorer13BuildStepListEZNKS1_18BuildConfiguration14knownStepListsEvEUlS3_E_EE5QListIDTclfp0_cvT__EEEERKS6_IS7_ET0_
>> +QList<decltype ({parm#2}((ProjectExplorer::BuildStepList*)()))> 
>> Utils::transform<ProjectExplorer::BuildStepList*, 
>> ProjectExplorer::BuildConfiguration::knownStepLists() 
>> const::{lambda(ProjectExplorer::BuildStepList*)#1}>(ProjectExplorer::BuildConfiguration::knownStepLists()
>>  const::{lambda(ProjectExplorer::BuildStepList*)#1}<QList> const&, 
>> ProjectExplorer::BuildConfiguration::knownStepLists() 
>> const::{lambda(ProjectExplorer::BuildStepList*)#1})
>> +#
>> +
>> +_ZSt7forwardIKSaINSt6thread5_ImplISt12_Bind_simpleIFZN6WIM_DL5Utils9AsyncTaskC4IMNS3_8Hardware12FpgaWatchdogEKFvvEIPS8_EEEibOT_DpOT0_EUlvE_vEEEEEESD_RNSt16remove_referenceISC_E4typeE
>> +std::allocator<std::thread::_Impl<std::_Bind_simple<WIM_DL::Utils::AsyncTask::AsyncTask<void
>>  (WIM_DL::Hardware::FpgaWatchdog::*)() const, 
>> WIM_DL::Hardware::FpgaWatchdog*>(int, bool, void 
>> (WIM_DL::Hardware::FpgaWatchdog::*&&)() const, 
>> WIM_DL::Hardware::FpgaWatchdog*&&)::{lambda()#1} ()> > > const&& 
>> std::forward<std::allocator<std::thread::_Impl<std::_Bind_simple<WIM_DL::Utils::AsyncTask::AsyncTask<void
>>  (WIM_DL::Hardware::FpgaWatchdog::*)() const, 
>> WIM_DL::Hardware::FpgaWatchdog*>(int, bool, 
>> std::allocator<std::thread::_Impl<std::_Bind_simple<WIM_DL::Utils::AsyncTask::AsyncTask<void
>>  (WIM_DL::Hardware::FpgaWatchdog::*)() const, 
>> WIM_DL::Hardware::FpgaWatchdog*>(int, bool, void 
>> (WIM_DL::Hardware::FpgaWatchdog::*&&)() const, 
>> WIM_DL::Hardware::FpgaWatchdog*&&)::{lambda()#1} ()> > > const&&, 
>> WIM_DL::Hardware::FpgaWatchdog*&&)::{lambda()#1} ()> > > 
>> const>(std::remove_reference<std::allocator<std::thread::_Impl<std::_Bind_simple<WIM_DL::Utils::AsyncTask::AsyncTask<void
>>  (WIM_DL::Hardware::FpgaWatchdog::*)() const, 
>> WIM_DL::Hardware::FpgaWatchdog*>(int, bool, void 
>> (WIM_DL::Hardware::FpgaWatchdog::*&&)() const, 
>> WIM_DL::Hardware::FpgaWatchdog*&&)::{lambda()#1} ()> > > const>::type&)
>> +#
>> +# Test demangler crash PR61805
>> +
>> +_ZNK5niven5ColorIfLi4EEdvIfEENSt9enable_ifIXsrSt13is_arithmeticIT_E5valueEKNS0_IDTmlcvS5__Ecvf_EELi4EEEE4typeES5_
>> +std::enable_if<std::is_arithmetic<float>::value, niven::Color<decltype 
>> (((float)())*((float)())), 4> const>::type niven::Color<float, 
>> 4>::operator/<float>(float) const
>> +#
>> +# Test recursion PR70517
>> +
>> +_ZSt4moveIRZN11tconcurrent6futureIvE4thenIZ5awaitIS2_EDaOT_EUlRKS6_E_EENS1_INSt5decayIDTclfp_defpTEEE4typeEEES7_EUlvE_EONSt16remove_referenceIS6_E4typeES7_
>> +std::remove_reference<tconcurrent::future<std::decay<decltype 
>> ({parm#1}(*this))>::type> tconcurrent::future<void>::then<auto 
>> await<tconcurrent::future<void> 
>> >(tconcurrent::future<void>&&)::{lambda(tconcurrent::future<std::decay<decltype
>>  ({parm#1}(*this))>::type> tconcurrent::future<void>::then<auto 
>> await<tconcurrent::future<void> >()::{lambda( const&)#1}>( 
>> const)::{lambda()#1}& const&)#1}>(auto await<tconcurrent::future<void> 
>> >()::{lambda( const&)#1}&& const)::{lambda()#1}&>::type&& 
>> std::move<tconcurrent::future<std::decay<decltype ({parm#1}(*this))>::type> 
>> tconcurrent::future<void>::then<auto await<tconcurrent::future<void> 
>> >(tconcurrent::future<std::decay<decltype ({parm#1}(*this))>::type> 
>> tconcurrent::future<void>::then<auto await<tconcurrent::future<void> 
>> >(tconcurrent::future<void>&&)::{lambda(& const&)#1}>(auto 
>> await<tconcurrent::future<void> >()::{lambda( const&)#1}&& 
>> const)::{lambda()#1}&)::{lambda(tconcurrent::future<std::decay<decltype 
>> ({parm#1}(*this))>::type> tconcurrent::future<void>::then<auto 
>> await<tconcurrent::future<void> >(tconcurrent::future<void>&&)::{lambda(& 
>> const&)#1}>(auto await<tconcurrent::future<void> >()::{lambda(&)#1}&& 
>> const)::{lambda()#1}& const&)#1}>(tconcurrent::future<std::decay<decltype 
>> ({parm#1}(*this))>::type> tconcurrent::future<void>::then<auto 
>> await<tconcurrent::future<void> >(tconcurrent::future<void>&&)::{lambda(& 
>> const&)#1}>(auto await<tconcurrent::future<void> >()::{lambda(&)#1}&& 
>> const)::{lambda()#1}& 
>> const)::{lambda()#1}&>(tconcurrent::future<std::decay<decltype 
>> ({parm#1}(*this))>::type> tconcurrent::future<void>::then<auto 
>> await<tconcurrent::future<void> 
>> >(tconcurrent::future<void>&&)::{lambda(tconcurrent::future<std::decay<decltype
>>  ({parm#1}(*this))>::type> tconcurrent::future<void>::then<auto 
>> await<tconcurrent::future<void> >()::{lambda(&)#1}>()::{lambda()#1}& 
>> const&)#1}>(auto await<tconcurrent::future<void> >()::{lambda(&)#1}&& 
>> const)::{lambda()#1}& const)
>> +#
>> +# Test recursion PR68383
>> +
>> +_ZSt7forwardIRKZN5Write14DataMapGrammarISt20back_insert_iteratorISsEEC4EvEUlRT_E_EOS5_RNSt16remove_referenceIS5_E4typeE
>> +_ZSt7forwardIRKZN5Write14DataMapGrammarISt20back_insert_iteratorISsEEC4EvEUlRT_E_EOS5_RNSt16remove_referenceIS5_E4typeE
>> +#
>> +# Test recursion PR67264
>> +
>> +_Z1KIStcvT_E
>> +K<std::operator std::operator >
>> +
>> +_ZcvT_IIS0_EE
>> +operator operator <operator operator >
>> +
>> +_ZcvT_IZcvT_E1fE
>> +operator operator operator ::f::f<operator operator ::f::f>
>> +
>> +_Z1gINcvT_EE
>> +g<operator operator >
>> +
>> +_ZcvT_ILZcvDTT_EEE
>> +operator operator decltype (operator decltype ())<operator decltype 
>> (operator decltype ())>
>> +
>> +_Z1gIJOOT_EEOT_c
>> +_Z1gIJOOT_EEOT_c
>> +
>> +_Z1KMMMMMMMMMMMMMMMA_xooooooooooooooo
>> +K(unsigned __int128 unsigned __int128 unsigned __int128 unsigned __int128 
>> unsigned __int128 unsigned __int128 unsigned __int128 unsigned __int128 
>> unsigned __int128 unsigned __int128 unsigned __int128 unsigned __int128 
>> unsigned __int128 unsigned __int128 unsigned __int128 long long (long long 
>> (unsigned __int128 ::*::* unsigned __int128 unsigned __int128 ::*::*::* 
>> unsigned __int128 unsigned __int128 unsigned __int128 ::*::*::*::* unsigned 
>> __int128 unsigned __int128 unsigned __int128 unsigned __int128 
>> ::*::*::*::*::* unsigned __int128 unsigned __int128 unsigned __int128 
>> unsigned __int128 unsigned __int128 ::*::*::*::*::*::* unsigned __int128 
>> unsigned __int128 unsigned __int128 unsigned __int128 unsigned __int128 
>> unsigned __int128 ::*::*::*::*::*::*::* unsigned __int128 unsigned __int128 
>> unsigned __int128 unsigned __int128 unsigned __int128 unsigned __int128 
>> unsigned __int128 ::*::*::*::*::*::*::*::* unsigned __int128 unsigned 
>> __int128 unsigned __int128 unsigned __int128 unsigned __int128 unsigned 
>> __int128 unsigned __int128 unsigned __int128 ::*::*::*::*::*::*::*::*::* 
>> unsigned __int128 unsigned __int128 unsigned __int128 unsigned __int128 
>> unsigned __int128 unsigned __int128 unsigned __int128 unsigned __int128 
>> unsigned __int128 ::*::*::*::*::*::*::*::*::*::* unsigned __int128 unsigned 
>> __int128 unsigned __int128 unsigned __int128 unsigned __int128 unsigned 
>> __int128 unsigned __int128 unsigned __int128 unsigned __int128 unsigned 
>> __int128 ::*::*::*::*::*::*::*::*::*::*::* unsigned __int128 unsigned 
>> __int128 unsigned __int128 unsigned __int128 unsigned __int128 unsigned 
>> __int128 unsigned __int128 unsigned __int128 unsigned __int128 unsigned 
>> __int128 unsigned __int128 ::*::*::*::*::*::*::*::*::*::*::*::* unsigned 
>> __int128 unsigned __int128 unsigned __int128 unsigned __int128 unsigned 
>> __int128 unsigned __int128 unsigned __int128 unsigned __int128 unsigned 
>> __int128 unsigned __int128 unsigned __int128 unsigned __int128 
>> ::*::*::*::*::*::*::*::*::*::*::*::*::* unsigned __int128 unsigned __int128 
>> unsigned __int128 unsigned __int128 unsigned __int128 unsigned __int128 
>> unsigned __int128 unsigned __int128 unsigned __int128 unsigned __int128 
>> unsigned __int128 unsigned __int128 unsigned __int128 
>> ::*::*::*::*::*::*::*::*::*::*::*::*::*::* unsigned __int128 unsigned 
>> __int128 unsigned __int128 unsigned __int128 unsigned __int128 unsigned 
>> __int128 unsigned __int128 unsigned __int128 unsigned __int128 unsigned 
>> __int128 unsigned __int128 unsigned __int128 unsigned __int128 unsigned 
>> __int128 ::*::*::*::*::*::*::*::*::*::*::*::*::*::*::*) []::*) 
>> []::*::*::*::*::*::*::*::*::*::*::*::*::*::*::*)
>> +
>> +_ZdvMMMMMMMMMMMMMrrrrA_DTdvfp_fp_Eededilfdfdfdfd
>> +operator/(float double float double float double float long int double long 
>> double double long double decltype ({parm#1}/{parm#1}) restrict (decltype 
>> ({parm#1}/{parm#1}) restrict (long double ::*::* double long double 
>> ::*::*::* long double double long double ::*::*::*::* double long double 
>> double long double ::*::*::*::*::* int double long double double long double 
>> ::*::*::*::*::*::* long int double long double double long double 
>> ::*::*::*::*::*::*::* float long int double long double double long double 
>> ::*::*::*::*::*::*::*::* double float long int double long double double 
>> long double ::*::*::*::*::*::*::*::*::* float double float long int double 
>> long double double long double ::*::*::*::*::*::*::*::*::*::* double float 
>> double float long int double long double double long double 
>> ::*::*::*::*::*::*::*::*::*::*::* float double float double float long int 
>> double long double double long double ::*::*::*::*::*::*::*::*::*::*::*::* 
>> double float double float double float long int double long double double 
>> long double ::*::*::*::*::*::*::*::*::*::*::*::*::*) []::*) 
>> []::*::*::*::*::*::*::*::*::*::*::*::*::*, double)
>> +#
>> +# Test for Infinite Recursion PR67738
>> +
>> +_ZNK6Common15ConvertingRangeIN5boost12range_detail17transformed_rangeIZN1a1b1cEbEUljE_KSt6vectorIjSaIjEEEEEcvT_IS7_INS4_1dESaISF_EEEEv
>> +Common::ConvertingRange<boost::range_detail::transformed_range<a::b::c(bool)::{lambda(unsigned
>>  int)#1}, std::vector<unsigned int, std::allocator<unsigned int> > const> 
>> >::operator a::b::c(bool)::{lambda(unsigned int)#1}<a::d, 
>> std::allocator<Common::ConvertingRange<boost::range_detail::transformed_range<a::b::c(bool)::{lambda(unsigned
>>  int)#1}, std::vector<unsigned int, std::allocator<unsigned int> > const> 
>> >::operator > ><a::b::c(bool)::{lambda(unsigned int)#1}<a::d, 
>> std::allocator<Common::ConvertingRange<boost::range_detail::transformed_range<a::b::c(bool)::{lambda(unsigned
>>  int)#1}, std::vector<unsigned int, std::allocator<unsigned int> > const> 
>> >::operator 
>> Common::ConvertingRange<boost::range_detail::transformed_range<a::b::c(bool)::{lambda(unsigned
>>  int)#1}, std::vector<unsigned int, std::allocator<unsigned int> > const> 
>> >::operator > > >() const
>> +#
>> +# Test for Infinite Recursion PR68700
>> +
>> +_ZN8futurizeI13frozen_schemaE5applyIRZN7seastar7shardedIN7service13storage_proxyEE9invoke_onIZZNS6_22init_messaging_serviceEvENKUljN5utils4UUIDEE8_clEjSA_EUlOT_E_6futureIJS0_EEEET0_jSD_EUlvE_JEEESG_SD_DpOT0_
>> +_ZN8futurizeI13frozen_schemaE5applyIRZN7seastar7shardedIN7service13storage_proxyEE9invoke_onIZZNS6_22init_messaging_serviceEvENKUljN5utils4UUIDEE8_clEjSA_EUlOT_E_6futureIJS0_EEEET0_jSD_EUlvE_JEEESG_SD_DpOT0_
>> +#
>> +# Test for Infinite Recursion PR61460
>> +
>> +_ZNK6clover6detail11basic_rangeINS_13adaptor_rangeINS_9addressesEINS2_IRFRNS_5eventEP9_cl_eventEINS_14iterator_rangeIPKS7_EEEEEEEENS0_16iterator_adaptorIS3_INSG_IS9_ISC_EEEEEESI_EcvT_ISt6vectorIPS4_SaISN_EEvEEv
>> +clover::detail::basic_range<clover::adaptor_range<clover::addresses, 
>> clover::adaptor_range<clover::event& (&)(_cl_event*), 
>> clover::iterator_range<_cl_event* const*> > >, 
>> clover::detail::iterator_adaptor<clover::addresses<clover::detail::iterator_adaptor<clover::event&
>>  (&)(_cl_event*)<_cl_event* const*> > > >, 
>> clover::detail::iterator_adaptor<clover::event& (&)(_cl_event*)<_cl_event* 
>> const*> > >::operator std::vector<clover::event*, 
>> std::allocator<clover::detail::basic_range<clover::adaptor_range<clover::addresses,
>>  clover::adaptor_range<clover::event& (&)(_cl_event*), 
>> clover::iterator_range<_cl_event* const*> > >, 
>> clover::detail::iterator_adaptor<clover::addresses<clover::detail::iterator_adaptor<clover::event&
>>  (&)(_cl_event*)<_cl_event* const*> > > >, 
>> clover::detail::iterator_adaptor<clover::event& (&)(_cl_event*)<_cl_event* 
>> const*> > >::operator > ><std::vector<clover::event*, 
>> std::allocator<clover::detail::basic_range<clover::adaptor_range<clover::addresses,
>>  clover::adaptor_range<clover::event& (&)(_cl_event*), 
>> clover::iterator_range<_cl_event* const*> > >, 
>> clover::detail::iterator_adaptor<clover::addresses<clover::detail::iterator_adaptor<clover::event&
>>  (&)(_cl_event*)<_cl_event* const*> > > >, 
>> clover::detail::iterator_adaptor<clover::event& (&)(_cl_event*)<_cl_event* 
>> const*> > >::operator 
>> clover::detail::basic_range<clover::adaptor_range<clover::addresses, 
>> clover::adaptor_range<clover::event& (&)(_cl_event*), 
>> clover::iterator_range<_cl_event* const*> > >, 
>> clover::detail::iterator_adaptor<clover::addresses<clover::detail::iterator_adaptor<clover::event&
>>  (&)(_cl_event*)<_cl_event* const*> > > >, 
>> clover::detail::iterator_adaptor<clover::event& (&)(_cl_event*)<_cl_event* 
>> const*> > >::operator > >, void>() const
>> +
>> 

Reply via email to