Access of Memory Location After End of Buffer in radareorg/radare2


Reported on

Jan 22nd 2022


This vulnerability is of out-of-bound read which accesses the address beyond/past the buffer. The bug exists in latest stable release (radare2-5.5.4) and lastest master branch (ed2030b79e68986bf04f3a6279463ab989fe400f, updated in Jan 22, 2022). Specifically, the vulnerable code and the bug's basic explanation is highlighted as follows:

// shlr/java/class.c
R_API RBinJavaAttrInfo *r_bin_java_signature_attr_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz, ut64 buf_offset) {
// line 3612
// the buffer[offset] can access memory beyond the buffer's size
// in our poc, it is the case that the second byte of the USHORT is out of the buffer's range
    attr->info.signature_attr.signature_idx = R_BIN_JAVA_USHORT (buffer, offset);

Proof of Concept

Build the radare2 (5.5.4 or latest commit ed2030b79e68986bf04f3a6279463ab989fe400f) and run it using the input POC.

# build the radare2 with address sanitizer
export CFLAGS=" -fsanitize=address "; export CXXFLAGS=" -fsanitize=address "; export LDFLAGS=" -fsanitize=address ";
CFGARG=" --enable-shared=no " PREFIX=`realpath install` bash sys/
# disable some features of address sanitizer to avoid false positives
export ASAN_OPTIONS=detect_leaks=0:abort_on_error=1:symbolize=0:allocator_may_return_null=1:detect_odr_violation=0
# trigger the crash
./radare2 -A -q POC_FILE

The crash stack is:

    #0 0x7ffff56ceba8  (/src/projects/radare2-5.5.4/lastest-radare2/install/lib/
    #1 0x7ffff56af317  (/src/projects/radare2-5.5.4/lastest-radare2/install/lib/
    #2 0x7ffff569f5a2  (/src/projects/radare2-5.5.4/lastest-radare2/install/lib/
    #3 0x7ffff56b3203  (/src/projects/radare2-5.5.4/lastest-radare2/install/lib/
    #4 0x7ffff56b5d33  (/src/projects/radare2-5.5.4/lastest-radare2/install/lib/
    #5 0x7ffff56c694f  (/src/projects/radare2-5.5.4/lastest-radare2/install/lib/
    #6 0x7ffff282d06a  (/src/projects/radare2-5.5.4/lastest-radare2/install/lib/
    #7 0x7ffff2597fea  (/src/projects/radare2-5.5.4/lastest-radare2/install/lib/
    #8 0x7ffff257df9e  (/src/projects/radare2-5.5.4/lastest-radare2/install/lib/
    #9 0x7ffff252179b  (/src/projects/radare2-5.5.4/lastest-radare2/install/lib/
    #10 0x7ffff2520876  (/src/projects/radare2-5.5.4/lastest-radare2/install/lib/
    #11 0x7ffff386facc  (/src/projects/radare2-5.5.4/lastest-radare2/install/lib/
    #12 0x7ffff76312ae  (/src/projects/radare2-5.5.4/lastest-radare2/install/lib/
    #13 0x7ffff73a50b2  (/lib/x86_64-linux-gnu/
    #14 0x55555557239d  (/src/projects/radare2-5.5.4/lastest-radare2/install/bin/radare2+0x1e39d)

0x602000067cb7 is located 0 bytes to the right of 7-byte region [0x602000067cb0,0x602000067cb7)
allocated by thread T0 here:
    #0 0x5555555ed772  (/src/projects/radare2-5.5.4/lastest-radare2/install/bin/radare2+0x99772)
    #1 0x7ffff569f50f  (/src/projects/radare2-5.5.4/lastest-radare2/install/lib/

SUMMARY: AddressSanitizer: heap-buffer-overflow (/src/projects/radare2-5.5.4/lastest-radare2/install/lib/
Shadow bytes around the buggy address:
  0x0c0480004f40: fa fa fd fa fa fa 05 fa fa fa 05 fa fa fa 01 fa
  0x0c0480004f50: fa fa 05 fa fa fa 01 fa fa fa 05 fa fa fa 01 fa
  0x0c0480004f60: fa fa 05 fa fa fa 01 fa fa fa 05 fa fa fa 01 fa
  0x0c0480004f70: fa fa 05 fa fa fa 01 fa fa fa 05 fa fa fa 01 fa
  0x0c0480004f80: fa fa 05 fa fa fa 01 fa fa fa 05 fa fa fa 00 fa
=>0x0c0480004f90: fa fa 05 fa fa fa[07]fa fa fa fa fa fa fa fa fa
  0x0c0480004fa0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0480004fb0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0480004fc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0480004fd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0480004fe0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 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

Program received signal SIGABRT, Aborted.
0x00007ffff73c418b in raise () from /lib/x86_64-linux-gnu/
(gdb) bt
#0  0x00007ffff73c418b in raise () from /lib/x86_64-linux-gnu/
#1  0x00007ffff73a3859 in abort () from /lib/x86_64-linux-gnu/
#2  0x000055555560ba77 in __sanitizer::Abort() ()
#3  0x0000555555609fa1 in __sanitizer::Die() ()
#4  0x00005555555f14e4 in __asan::ScopedInErrorReport::~ScopedInErrorReport() ()
#5  0x00005555555f30aa in __asan::ReportGenericError(unsigned long, unsigned long, unsigned long, unsigned long, bool, unsigned long, unsigned int, bool) ()
#6  0x00005555555f3798 in __asan_report_load1 ()
#7  0x00007ffff56ceba9 in r_bin_java_signature_attr_new (bin=<optimized out>, buffer=0x602000067cb0 "", sz=<optimized out>, buf_offset=<optimized out>) at class.c:3612
#8  0x00007ffff56af318 in r_bin_java_read_next_attr_from_buffer (bin=<optimized out>, buffer=<optimized out>, sz=6, buf_offset=140737341309323) at class.c:2095
#9  0x00007ffff569f5a3 in r_bin_java_read_next_attr (bin=<optimized out>, offset=<optimized out>, buf=<optimized out>, buf_len=<optimized out>) at class.c:2053
#10 0x00007ffff56b3204 in r_bin_java_parse_attrs (bin=<optimized out>, offset=3011, buf=0x61f00003aa80 "\312\376\272\276", len=<optimized out>) at class.c:2260
#11 0x00007ffff56b5d34 in r_bin_java_load_bin (bin=0x614000001240, buf=<optimized out>, buf_sz=<optimized out>) at class.c:2386
#12 0x00007ffff56b5954 in r_bin_java_new_bin (bin=<optimized out>, loadaddr=<optimized out>, kv=<optimized out>, buf=<optimized out>, len=<optimized out>) at class.c:2336
#13 0x00007ffff56c6950 in r_bin_java_new_buf (buf=<optimized out>, loadaddr=<optimized out>, kv=<optimized out>) at class.c:3157
#14 0x00007ffff282d06b in load_buffer (bf=<optimized out>, bin_obj=<optimized out>, buf=0x60300008afd0, loadaddr=0, sdb=0x626000396100)
    at /src/projects/radare2-5.5.4/lastest-radare2/libr/../libr/bin/p/bin_java.c:81
#15 0x00007ffff2597feb in r_bin_object_new (bf=0x60d0000006c0, plugin=<optimized out>, baseaddr=<optimized out>, loadaddr=<optimized out>, offset=<optimized out>,
    sz=<optimized out>) at bobj.c:147
#16 0x00007ffff257df9f in r_bin_file_new_from_buffer (bin=0x616000000980, file=<optimized out>, buf=<optimized out>, rawstr=<optimized out>, baseaddr=<optimized out>,
    loadaddr=<optimized out>, fd=<optimized out>, pluginname=<optimized out>) at bfile.c:560
#17 0x00007ffff252179c in r_bin_open_buf (bin=<optimized out>, buf=<optimized out>, opt=<optimized out>) at bin.c:279
#18 0x00007ffff2520877 in r_bin_open_io (bin=0x616000000980, opt=<optimized out>) at bin.c:339
#19 0x00007ffff386facd in r_core_file_do_load_for_io_plugin (r=0x7fffec332800, baseaddr=18446744073709551615, loadaddr=0) at cfile.c:435
#20 r_core_bin_load (r=0x7fffec332800, filenameuri=<optimized out>, baddr=<optimized out>) at cfile.c:636
#21 0x00007ffff76312af in r_main_radare2 (argc=<optimized out>, argv=<optimized out>) at radare2.c:1177
#22 0x00007ffff73a50b3 in __libc_start_main () from /lib/x86_64-linux-gnu/
#23 0x000055555557239e in _start ()


The bug causes the program reads data past the end of the intented buffer. Typically, this can allow attackers to read sensitive information from other memory locations or cause a crash. More details see CWE-125: Out-of-bounds read.


We are processing your report and will contact the radareorg/radare2 team within 24 hours. 4 months ago
Cen Zhang modified the report
4 months ago
We have contacted a member of the radareorg/radare2 team and are waiting to hear back 4 months ago
We have sent a follow up to the radareorg/radare2 team. We will try again in 7 days. 4 months ago
We have sent a second follow up to the radareorg/radare2 team. We will try again in 10 days. 4 months ago
pancake validated this vulnerability 4 months ago
Cen Zhang has been awarded the disclosure bounty
The fix bounty is now up for grabs
4 months ago


Fixed in

pancake confirmed that a fix has been merged on 6c4428 4 months ago
pancake has been awarded the fix bounty
4 months ago


As long as huntr seems to be a friendly and clean way to report and track vulnerabilities to opensource projects. it would be good to have a way to also automate the check for the fix. I am adding all those samples to the fuzz suite of r2, so my CI is verifying that no future commits will reintroduce those bugs, but when there are lot of tickets to track it's sometimes hard to match the right commit (sometimes one commit fixes multiple crash files).

Clusterfuzz already verifies from time to time that their samples arent regressing and detect when the fix has been commited upstream. Sumarizing my thoughs:

  • huntr should recommend/provide a reference ID (can we we the boundy id/url) for the commits
  • how to automate checking if the sample has been fixed and in which commit
  • is there a way to assign the CVE before the commit hits master? that would force me to not merge fixes in master, unless we have a different ID to associate the commit with the bounty, the reproducer sample

Thanks for such an awesome bugtracking/bounty platform!

Cen Zhang
4 months ago


lol, really great and practical feedback from developer's perspective for improving huntr @admin

Jamie Slome
4 months ago


Amazing feedback @pancake - we really value your honesty and depth into your workflow and how our platform can help serve you better ♥️

I'd love to invite you to create a feature request ticket on our public roadmap HERE.

We can give you better responses on your ideas and also keep you updated there with any progress we have made in helping to achieve your visions! 🌞

Let me know if you would not like to create the issue, and I will do it on your behalf!

4 months ago


Thanks will do

to join this conversation