Out-of-bounds read in radareorg/radare2

Valid

Reported on

Apr 1st 2022


Description

Out-of-bounds (OOB) read vulnerability exists in analop function in Radare2 5.6.7

Version

radare2 5.6.7 27722 @ linux-x86-64 git.5.6.6
commit: e876eef2a2f758157dd6028fb01809bcedacf00f build: 2022-04-01__07:03:35

Proof of Concept

radare2 -q -A poc

poc

ASAN

==2143069==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020000a2a17 at pc 0x7fabd14c6e67 bp 0x7ffcf252a750 sp 0x7ffcf252a748
READ of size 1 at 0x6020000a2a17 thread T0                                                                                                                                                                                                  
    #0 0x7fabd14c6e66 in analop /root/fuzzing/radare2_fuzzing/radare2/libr/..//libr/anal/p/anal_cris.c:65
    #1 0x7fabd15ee0b7 in r_anal_op /root/fuzzing/radare2_fuzzing/radare2/libr/anal/op.c:120
    #2 0x7fabd2edd954 in anal_block_cb /root/fuzzing/radare2_fuzzing/radare2/libr/core/canal.c:3502
    #3 0x7fabd1618bab in r_anal_block_recurse_depth_first /root/fuzzing/radare2_fuzzing/radare2/libr/anal/block.c:531
    #4 0x7fabd2ede480 in r_core_recover_vars /root/fuzzing/radare2_fuzzing/radare2/libr/core/canal.c:3553
    #5 0x7fabd2cf8d40 in r_core_af /root/fuzzing/radare2_fuzzing/radare2/libr/core/cmd_anal.c:3894
    #6 0x7fabd2ee2f29 in r_core_anal_all /root/fuzzing/radare2_fuzzing/radare2/libr/core/canal.c:4251
    #7 0x7fabd2d33ac1 in cmd_anal_all /root/fuzzing/radare2_fuzzing/radare2/libr/core/cmd_anal.c:11125
    #8 0x7fabd2d3bc5b in cmd_anal /root/fuzzing/radare2_fuzzing/radare2/libr/core/cmd_anal.c:12330
    #9 0x7fabd2eb7d8a in r_cmd_call /root/fuzzing/radare2_fuzzing/radare2/libr/core/cmd_api.c:531
    #10 0x7fabd2dece8c in r_core_cmd_subst_i /root/fuzzing/radare2_fuzzing/radare2/libr/core/cmd.c:4478
    #11 0x7fabd2de4103 in r_core_cmd_subst /root/fuzzing/radare2_fuzzing/radare2/libr/core/cmd.c:3364
    #12 0x7fabd2df3792 in run_cmd_depth /root/fuzzing/radare2_fuzzing/radare2/libr/core/cmd.c:5366
    #13 0x7fabd2df4002 in r_core_cmd /root/fuzzing/radare2_fuzzing/radare2/libr/core/cmd.c:5449
    #14 0x7fabd2df4b2c in r_core_cmd0 /root/fuzzing/radare2_fuzzing/radare2/libr/core/cmd.c:5606
    #15 0x7fabd54f93ca in r_main_radare2 /root/fuzzing/radare2_fuzzing/radare2/libr/main/radare2.c:1397
    #16 0x5652f8dde5f8 in main /root/fuzzing/radare2_fuzzing/radare2/binr/radare2/radare2.c:96
    #17 0x7fabd52f97fc in __libc_start_main ../csu/libc-start.c:332
    #18 0x5652f8dde179 in _start (/root/fuzzing/radare2_fuzzing/radare2/binr/radare2/radare2+0x1179)

0x6020000a2a17 is located 0 bytes to the right of 7-byte region [0x6020000a2a10,0x6020000a2a17)
allocated by thread T0 here:                                                                                                                                                                                                                
    #0 0x7fabd59fe7cf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
    #1 0x7fabd2edd2ef in anal_block_cb /root/fuzzing/radare2_fuzzing/radare2/libr/core/canal.c:3452
    #2 0x7fabd1618bab in r_anal_block_recurse_depth_first /root/fuzzing/radare2_fuzzing/radare2/libr/anal/block.c:531
    #3 0x7fabd2ede480 in r_core_recover_vars /root/fuzzing/radare2_fuzzing/radare2/libr/core/canal.c:3553
    #4 0x7fabd2cf8d40 in r_core_af /root/fuzzing/radare2_fuzzing/radare2/libr/core/cmd_anal.c:3894
    #5 0x7fabd2ee2f29 in r_core_anal_all /root/fuzzing/radare2_fuzzing/radare2/libr/core/canal.c:4251
    #6 0x7fabd2d33ac1 in cmd_anal_all /root/fuzzing/radare2_fuzzing/radare2/libr/core/cmd_anal.c:11125
    #7 0x7fabd2d3bc5b in cmd_anal /root/fuzzing/radare2_fuzzing/radare2/libr/core/cmd_anal.c:12330
    #8 0x7fabd2eb7d8a in r_cmd_call /root/fuzzing/radare2_fuzzing/radare2/libr/core/cmd_api.c:531
    #9 0x7fabd2dece8c in r_core_cmd_subst_i /root/fuzzing/radare2_fuzzing/radare2/libr/core/cmd.c:4478
    #10 0x7fabd2de4103 in r_core_cmd_subst /root/fuzzing/radare2_fuzzing/radare2/libr/core/cmd.c:3364
    #11 0x7fabd2df3792 in run_cmd_depth /root/fuzzing/radare2_fuzzing/radare2/libr/core/cmd.c:5366
    #12 0x7fabd2df4002 in r_core_cmd /root/fuzzing/radare2_fuzzing/radare2/libr/core/cmd.c:5449
    #13 0x7fabd2df4b2c in r_core_cmd0 /root/fuzzing/radare2_fuzzing/radare2/libr/core/cmd.c:5606
    #14 0x7fabd54f93ca in r_main_radare2 /root/fuzzing/radare2_fuzzing/radare2/libr/main/radare2.c:1397
    #15 0x5652f8dde5f8 in main /root/fuzzing/radare2_fuzzing/radare2/binr/radare2/radare2.c:96
    #16 0x7fabd52f97fc in __libc_start_main ../csu/libc-start.c:332

SUMMARY: AddressSanitizer: heap-buffer-overflow /root/fuzzing/radare2_fuzzing/radare2/libr/..//libr/anal/p/anal_cris.c:65 in analop
Shadow bytes around the buggy address:
  0x0c048000c4f0: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x0c048000c500: fa fa fd fa fa fa fd fa fa fa 06 fa fa fa fd fa
  0x0c048000c510: fa fa fd fa fa fa fd fa fa fa fd fd fa fa 00 05
  0x0c048000c520: fa fa 00 fa fa fa 00 02 fa fa fd fd fa fa 00 05
  0x0c048000c530: fa fa 00 05 fa fa 00 05 fa fa fd fd fa fa fd fd
=>0x0c048000c540: fa fa[07]fa fa fa 04 fa fa fa 03 fa fa fa 03 fa
  0x0c048000c550: fa fa 03 fa fa fa 03 fa fa fa fa fa fa fa fa fa
  0x0c048000c560: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c048000c570: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c048000c580: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c048000c590: 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
==2143069==ABORTING

Backtrace

#7  0x00007ffff3149e67 in analop (a=0x61a000000680, op=0x7fffffffd170, addr=65542, buf=0x6020000a2a96 "\001", len=1, mask=7) at /root/fuzzing/radare2_fuzzing/radare2/libr/..//libr/anal/p/anal_cris.c:65
#8  0x00007ffff32710b8 in r_anal_op (anal=0x61a000000680, op=0x7fffffffd170, addr=65542, data=0x6020000a2a96 "\001", len=1, mask=7) at op.c:120
#9  0x00007ffff4b60955 in anal_block_cb (bb=0x611000014e00, ctx=0x7fffffffd580) at canal.c:3502
#10 0x00007ffff329bbac in r_anal_block_recurse_depth_first (block=0x611000014e00, cb=0x7ffff4b600da <anal_block_cb>, on_exit=0x7ffff4b5ff63 <anal_block_on_exit>, user=0x7fffffffd580) at block.c:531
#11 0x00007ffff4b61481 in r_core_recover_vars (core=0x7fffef60f800, fcn=0x611000014cc0, argonly=true) at canal.c:3553
#12 0x00007ffff497bd41 in r_core_af (core=0x7fffef60f800, addr=65536, name=0x0, anal_calls=false) at /root/fuzzing/radare2_fuzzing/radare2/libr/core/cmd_anal.c:3894
#13 0x00007ffff4b65f2a in r_core_anal_all (core=0x7fffef60f800) at canal.c:4251
#14 0x00007ffff49b6ac2 in cmd_anal_all (core=0x7fffef60f800, input=0x6020000a26d2 "aa") at /root/fuzzing/radare2_fuzzing/radare2/libr/core/cmd_anal.c:11125
#15 0x00007ffff49bec5c in cmd_anal (data=0x7fffef60f800, input=0x6020000a26d1 "aaa") at /root/fuzzing/radare2_fuzzing/radare2/libr/core/cmd_anal.c:12330
#16 0x00007ffff4b3ad8b in r_cmd_call (cmd=0x620000000080, input=0x6020000a26d0 "aaaa") at cmd_api.c:531
#17 0x00007ffff4a6fe8d in r_core_cmd_subst_i (core=0x7fffef60f800, cmd=0x6020000a26d0 "aaaa", colon=0x0, tmpseek=0x7fffffffdea0) at cmd.c:4478
#18 0x00007ffff4a67104 in r_core_cmd_subst (core=0x7fffef60f800, cmd=0x6020000a26d0 "aaaa") at cmd.c:3364
#19 0x00007ffff4a76793 in run_cmd_depth (core=0x7fffef60f800, cmd=0x6210000ec500 "aaaa") at cmd.c:5366
#20 0x00007ffff4a77003 in r_core_cmd (core=0x7fffef60f800, cstr=0x7ffff7196a80 "aaaa", log=false) at cmd.c:5449
#21 0x00007ffff4a77b2d in r_core_cmd0 (core=0x7fffef60f800, cmd=0x7ffff7196a80 "aaaa") at cmd.c:5606
#22 0x00007ffff717c3cb in r_main_radare2 (argc=4, argv=0x7fffffffe468) at radare2.c:1397
#23 0x00005555555555f9 in main (argc=4, argv=0x7fffffffe468) at radare2.c:96
#24 0x00007ffff6f7c7fd in __libc_start_main (main=0x555555555581 <main>, argc=4, argv=0x7fffffffe468, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe458) at ../csu/libc-start.c:332
#25 0x000055555555517a in _start ()

Analysis

The buffer is allocated at /libr/core/canal.c:3452 with bb->size

static bool anal_block_cb(RAnalBlock *bb, BlockRecurseCtx *ctx) {
    if (r_cons_is_breaked ()) {
        return false;
    }
    if (bb->size < 1) {
        return true;
    }
    if (bb->size > ctx->core->anal->opt.bb_max_size) {
        return true;
    }
    ut8 *buf = malloc (bb->size);
    if (!buf) {
        return false;
    }
    (void) r_io_read_at (ctx->core->io, bb->addr, buf, bb->size);

Then at /libr/core/canal.c:3502, pos value is added to the pointer buf before being passed to r_anal_op function

#else
        pos = (opaddr - bb->addr);
        if (r_anal_op (core->anal, &op, opaddr, buf + pos, bb->size - pos, mask) < 1) {
            break;
        }

r_anal_op function passes the arguments to op function without any validiation on data

ret = anal->cur->op (anal, op, addr, data, len, mask);

The OOB read happens at /libr/anal/p/anal_cris.c:65 when it tries to read buf[1]

static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len, RAnalOpMask mask) {
    default:
        switch (buf[1]) {               // <<<<< OOB read
        case 0x00:
            op->type = R_ANAL_OP_TYPE_CJMP; // BCC
            break;

Suggested Fix

Validate buf size after adding posat /libr/core/canal.c:3502

Impact

This vulnerability allows attackers to read sensitive information from outside the allocated buffer boundary.

We are processing your report and will contact the radareorg/radare2 team within 24 hours. 2 months ago
hmsec modified the report
2 months ago
hmsec modified the report
2 months ago
hmsec modified the report
2 months ago
pancake validated this vulnerability 2 months ago
hmsec has been awarded the disclosure bounty
The fix bounty is now up for grabs
pancake confirmed that a fix has been merged on 605785 2 months ago
pancake has been awarded the fix bounty
to join this conversation