heap-use-after-free in radareorg/radare2

Valid

Reported on

Apr 6th 2022


Description

Whilst experimenting with radare2, built from version 5.6.6, we are able to induce a vulnerability at reg.c:101 in function r_reg_get_name_idx , using radare2 as a harness.

  99:  R_API int r_reg_get_name_idx(const char *type) {
100:    r_return_val_if_fail (type, -1);
//use-after-free here
101:    if (type[0] && type[1] && !type[2])
102:    switch (*type | (type[1] << 8)) {
103:    /* flags */
104:    case 'Z' + ('F' << 8): return R_REG_NAME_ZF;
105:    case 'S' + ('F' << 8): return R_REG_NAME_SF;
106:    case 'C' + ('F' << 8): return R_REG_NAME_CF;
107:    case 'O' + ('F' << 8): return R_REG_NAME_OF;
108:    /* gpr */
109:    case 'P' + ('C' << 8): return R_REG_NAME_PC;
110:    case 'S' + ('R' << 8): return R_REG_NAME_SR;
111:    case 'L' + ('R' << 8): return R_REG_NAME_LR;
112:    case 'S' + ('P' << 8): return R_REG_NAME_SP;
113:    case 'B' + ('P' << 8): return R_REG_NAME_BP;
114:    case 'S' + ('N' << 8): return R_REG_NAME_SN;
115:    /* args */
116:    case 'A' + ('0' << 8): return R_REG_NAME_A0;
117:    case 'A' + ('1' << 8): return R_REG_NAME_A1;
118:    case 'A' + ('2' << 8): return R_REG_NAME_A2;
119:    case 'A' + ('3' << 8): return R_REG_NAME_A3;
120:    case 'A' + ('4' << 8): return R_REG_NAME_A4;
121:    case 'A' + ('5' << 8): return R_REG_NAME_A5;
122:    case 'A' + ('6' << 8): return R_REG_NAME_A6;
123:    case 'A' + ('7' << 8): return R_REG_NAME_A7;
124:    case 'A' + ('8' << 8): return R_REG_NAME_A8;
125:    case 'A' + ('9' << 8): return R_REG_NAME_A9;
126:    /* return values */
127:    case 'R' + ('0' << 8): return R_REG_NAME_R0;
128:    case 'R' + ('1' << 8): return R_REG_NAME_R1;
129:    case 'R' + ('2' << 8): return R_REG_NAME_R2;
130:    case 'R' + ('3' << 8): return R_REG_NAME_R3;
131:    case 'F' + ('0' << 8): return R_REG_NAME_F0;
132:    case 'F' + ('1' << 8): return R_REG_NAME_F1;
133:    case 'F' + ('2' << 8): return R_REG_NAME_F2;
134:    case 'F' + ('3' << 8): return R_REG_NAME_F3;
135:    }
136:    return -1;
137:  }

Due to not properly handling pointers, a heap-based use-after-free will be triggered when the software encounters a malformed file, which could result in denial of service.

We found that the vulnerability exists in the latest master branch as well.

Environment

Ubuntu 20.04 LTS x86_64

gcc 10.3.0

Proof of Concept

The POC is: poc

The reproducing process is:

# build with address sanitizer
SANITIZE=address ./sys/sanitize.sh
# disable some features of address sanitizer to avoid false positives
export ASAN_OPTIONS=detect_leaks=0:abort_on_error=1:symbolize=1:allocator_may_return_null=1:detect_odr_violation=0
# trigger the crash
./radare2 -AA -qq POC_FILE

The ASAN report is:

==92948==ERROR: AddressSanitizer: heap-use-after-free on address 0x60200031b590 at pc 0x7ffff1d1e8f6 bp 0x7fffffffc8a0 sp 0x7fffffffc890
READ of size 1 at 0x60200031b590 thread T0
    #0 0x7ffff1d1e8f5 in r_reg_get_name_idx /work/libraries/radare2-5.6.6/libr/reg/reg.c:101
    #1 0x7ffff1d204f9 in r_reg_get /work/libraries/radare2-5.6.6/libr/reg/reg.c:325
    #2 0x7ffff1d203a4 in r_reg_getv /work/libraries/radare2-5.6.6/libr/reg/reg.c:311
    #3 0x7ffff4736f70 in r_core_anal_esil /work/libraries/radare2-5.6.6/libr/core/canal.c:5414
    #4 0x7ffff4581bea in cmd_anal_all /work/libraries/radare2-5.6.6/libr/core/cmd_anal.c:11349
    #5 0x7ffff45874d8 in cmd_anal /work/libraries/radare2-5.6.6/libr/core/cmd_anal.c:12264
    #6 0x7ffff47024c3 in r_cmd_call /work/libraries/radare2-5.6.6/libr/core/cmd_api.c:531
    #7 0x7ffff4638043 in r_core_cmd_subst_i /work/libraries/radare2-5.6.6/libr/core/cmd.c:4478
    #8 0x7ffff462f347 in r_core_cmd_subst /work/libraries/radare2-5.6.6/libr/core/cmd.c:3364
    #9 0x7ffff463e901 in run_cmd_depth /work/libraries/radare2-5.6.6/libr/core/cmd.c:5366
    #10 0x7ffff463f15d in r_core_cmd /work/libraries/radare2-5.6.6/libr/core/cmd.c:5449
    #11 0x7ffff463fd0b in r_core_cmd0 /work/libraries/radare2-5.6.6/libr/core/cmd.c:5606
    #12 0x7ffff458090f in cmd_anal_all /work/libraries/radare2-5.6.6/libr/core/cmd_anal.c:11214
    #13 0x7ffff45874d8 in cmd_anal /work/libraries/radare2-5.6.6/libr/core/cmd_anal.c:12264
    #14 0x7ffff47024c3 in r_cmd_call /work/libraries/radare2-5.6.6/libr/core/cmd_api.c:531
    #15 0x7ffff4638043 in r_core_cmd_subst_i /work/libraries/radare2-5.6.6/libr/core/cmd.c:4478
    #16 0x7ffff462f347 in r_core_cmd_subst /work/libraries/radare2-5.6.6/libr/core/cmd.c:3364
    #17 0x7ffff463e901 in run_cmd_depth /work/libraries/radare2-5.6.6/libr/core/cmd.c:5366
    #18 0x7ffff463f15d in r_core_cmd /work/libraries/radare2-5.6.6/libr/core/cmd.c:5449
    #19 0x7ffff463fd0b in r_core_cmd0 /work/libraries/radare2-5.6.6/libr/core/cmd.c:5606
    #20 0x7ffff7185010 in r_main_radare2 /work/libraries/radare2-5.6.6/libr/main/radare2.c:1398
    #21 0x5555555556ff in main /work/libraries/radare2-5.6.6/binr/radare2/radare2.c:96
    #22 0x7ffff6f6b0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
    #23 0x55555555528d in _start (/work/libraries/radare2-5.6.6/binr/radare2/radare2+0x128d)

0x60200031b590 is located 0 bytes inside of 4-byte region [0x60200031b590,0x60200031b594)
freed by thread T0 here:
    #0 0x7ffff769b8f7 in __interceptor_free ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:127
    #1 0x7ffff1d1f125 in r_reg_free_internal /work/libraries/radare2-5.6.6/libr/reg/reg.c:182
    #2 0x7ffff1d2bd9f in r_reg_set_profile_string /work/libraries/radare2-5.6.6/libr/reg/profile.c:150
    #3 0x7ffff2b9ffd5 in r_anal_set_reg_profile /work/libraries/radare2-5.6.6/libr/anal/anal.c:258
    #4 0x7ffff2ba04d7 in r_anal_set_bits /work/libraries/radare2-5.6.6/libr/anal/anal.c:324
    #5 0x7ffff464fe19 in cb_asmbits /work/libraries/radare2-5.6.6/libr/core/cconfig.c:884
    #6 0x7ffff6da6bce in r_config_set_i /work/libraries/radare2-5.6.6/libr/config/config.c:574
    #7 0x7ffff4693017 in r_core_seek_arch_bits /work/libraries/radare2-5.6.6/libr/core/cio.c:377
    #8 0x7ffff4736884 in r_core_anal_esil /work/libraries/radare2-5.6.6/libr/core/canal.c:5352
    #9 0x7ffff4581bea in cmd_anal_all /work/libraries/radare2-5.6.6/libr/core/cmd_anal.c:11349
    #10 0x7ffff45874d8 in cmd_anal /work/libraries/radare2-5.6.6/libr/core/cmd_anal.c:12264
    #11 0x7ffff47024c3 in r_cmd_call /work/libraries/radare2-5.6.6/libr/core/cmd_api.c:531
    #12 0x7ffff4638043 in r_core_cmd_subst_i /work/libraries/radare2-5.6.6/libr/core/cmd.c:4478
    #13 0x7ffff462f347 in r_core_cmd_subst /work/libraries/radare2-5.6.6/libr/core/cmd.c:3364
    #14 0x7ffff463e901 in run_cmd_depth /work/libraries/radare2-5.6.6/libr/core/cmd.c:5366
    #15 0x7ffff463f15d in r_core_cmd /work/libraries/radare2-5.6.6/libr/core/cmd.c:5449
    #16 0x7ffff463fd0b in r_core_cmd0 /work/libraries/radare2-5.6.6/libr/core/cmd.c:5606
    #17 0x7ffff458090f in cmd_anal_all /work/libraries/radare2-5.6.6/libr/core/cmd_anal.c:11214
    #18 0x7ffff45874d8 in cmd_anal /work/libraries/radare2-5.6.6/libr/core/cmd_anal.c:12264
    #19 0x7ffff47024c3 in r_cmd_call /work/libraries/radare2-5.6.6/libr/core/cmd_api.c:531
    #20 0x7ffff4638043 in r_core_cmd_subst_i /work/libraries/radare2-5.6.6/libr/core/cmd.c:4478
    #21 0x7ffff462f347 in r_core_cmd_subst /work/libraries/radare2-5.6.6/libr/core/cmd.c:3364
    #22 0x7ffff463e901 in run_cmd_depth /work/libraries/radare2-5.6.6/libr/core/cmd.c:5366
    #23 0x7ffff463f15d in r_core_cmd /work/libraries/radare2-5.6.6/libr/core/cmd.c:5449
    #24 0x7ffff463fd0b in r_core_cmd0 /work/libraries/radare2-5.6.6/libr/core/cmd.c:5606
    #25 0x7ffff7185010 in r_main_radare2 /work/libraries/radare2-5.6.6/libr/main/radare2.c:1398
    #26 0x5555555556ff in main /work/libraries/radare2-5.6.6/binr/radare2/radare2.c:96
    #27 0x7ffff6f6b0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)

previously allocated by thread T0 here:
    #0 0x7ffff76429f7 in __interceptor_strdup ../../../../src/libsanitizer/asan/asan_interceptors.cpp:454
    #1 0x7ffff72b2ed8 in r_str_new /work/libraries/radare2-5.6.6/libr/util/str.c:688
    #2 0x7ffff72b3e62 in r_str_dup /work/libraries/radare2-5.6.6/libr/util/str.c:865
    #3 0x7ffff1d1ede8 in r_reg_set_name /work/libraries/radare2-5.6.6/libr/reg/reg.c:142
    #4 0x7ffff1d2ab6c in parse_alias /work/libraries/radare2-5.6.6/libr/reg/profile.c:10
    #5 0x7ffff1d2c556 in r_reg_set_profile_string /work/libraries/radare2-5.6.6/libr/reg/profile.c:220
    #6 0x7ffff2b9ffd5 in r_anal_set_reg_profile /work/libraries/radare2-5.6.6/libr/anal/anal.c:258
    #7 0x7ffff2ba04d7 in r_anal_set_bits /work/libraries/radare2-5.6.6/libr/anal/anal.c:324
    #8 0x7ffff464fe19 in cb_asmbits /work/libraries/radare2-5.6.6/libr/core/cconfig.c:884
    #9 0x7ffff6da6bce in r_config_set_i /work/libraries/radare2-5.6.6/libr/config/config.c:574
    #10 0x7ffff4693017 in r_core_seek_arch_bits /work/libraries/radare2-5.6.6/libr/core/cio.c:377
    #11 0x7ffff4736884 in r_core_anal_esil /work/libraries/radare2-5.6.6/libr/core/canal.c:5352
    #12 0x7ffff4581bea in cmd_anal_all /work/libraries/radare2-5.6.6/libr/core/cmd_anal.c:11349
    #13 0x7ffff45874d8 in cmd_anal /work/libraries/radare2-5.6.6/libr/core/cmd_anal.c:12264
    #14 0x7ffff47024c3 in r_cmd_call /work/libraries/radare2-5.6.6/libr/core/cmd_api.c:531
    #15 0x7ffff4638043 in r_core_cmd_subst_i /work/libraries/radare2-5.6.6/libr/core/cmd.c:4478
    #16 0x7ffff462f347 in r_core_cmd_subst /work/libraries/radare2-5.6.6/libr/core/cmd.c:3364
    #17 0x7ffff463e901 in run_cmd_depth /work/libraries/radare2-5.6.6/libr/core/cmd.c:5366
    #18 0x7ffff463f15d in r_core_cmd /work/libraries/radare2-5.6.6/libr/core/cmd.c:5449
    #19 0x7ffff463fd0b in r_core_cmd0 /work/libraries/radare2-5.6.6/libr/core/cmd.c:5606
    #20 0x7ffff458090f in cmd_anal_all /work/libraries/radare2-5.6.6/libr/core/cmd_anal.c:11214
    #21 0x7ffff45874d8 in cmd_anal /work/libraries/radare2-5.6.6/libr/core/cmd_anal.c:12264
    #22 0x7ffff47024c3 in r_cmd_call /work/libraries/radare2-5.6.6/libr/core/cmd_api.c:531
    #23 0x7ffff4638043 in r_core_cmd_subst_i /work/libraries/radare2-5.6.6/libr/core/cmd.c:4478
    #24 0x7ffff462f347 in r_core_cmd_subst /work/libraries/radare2-5.6.6/libr/core/cmd.c:3364
    #25 0x7ffff463e901 in run_cmd_depth /work/libraries/radare2-5.6.6/libr/core/cmd.c:5366
    #26 0x7ffff463f15d in r_core_cmd /work/libraries/radare2-5.6.6/libr/core/cmd.c:5449
    #27 0x7ffff463fd0b in r_core_cmd0 /work/libraries/radare2-5.6.6/libr/core/cmd.c:5606
    #28 0x7ffff7185010 in r_main_radare2 /work/libraries/radare2-5.6.6/libr/main/radare2.c:1398
    #29 0x5555555556ff in main /work/libraries/radare2-5.6.6/binr/radare2/radare2.c:96

SUMMARY: AddressSanitizer: heap-use-after-free /work/libraries/radare2-5.6.6/libr/reg/reg.c:101 in r_reg_get_name_idx
Shadow bytes around the buggy address:
  0x0c048005b660: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x0c048005b670: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x0c048005b680: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x0c048005b690: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x0c048005b6a0: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
=>0x0c048005b6b0: fa fa[fd]fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x0c048005b6c0: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x0c048005b6d0: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x0c048005b6e0: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x0c048005b6f0: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x0c048005b700: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==92948==ABORTING
Aborted

Impact

This vulnerability is capable of inducing denial of service.

We are processing your report and will contact the radareorg/radare2 team within 24 hours. 2 months ago
We have contacted a member of the radareorg/radare2 team and are waiting to hear back 2 months ago
pancake
2 months ago

Maintainer


I can reproduce! working on the fix right now

pancake
2 months ago

Maintainer


Good catch! thank you for reporting! this is causing a random DoS

pancake validated this vulnerability 2 months ago
hdthky has been awarded the disclosure bounty
The fix bounty is now up for grabs
pancake confirmed that a fix has been merged on 64a82e 2 months ago
pancake has been awarded the fix bounty
hdthky
a month ago

Researcher


This bug was found by Xingyuan Mo from 360 IceSword Lab

to join this conversation