radareorg radare2 5.5.2 is vulnerable to Buffer Overflow via /libr/core/anal_objc.c mach-o parser.
cpe:2.3:a:radare:radare2:5.5.2:*:*:*:*:*:*:*
1D488ADA-AA17-4EFD-A47C-D809EB9B7982
OR
# Heap Buffer overflows in objc_build_refs

I have discovered two heap buffer 
overflows while parsing mach-o executables.
Please refer bellow for further information. 


## Environment


```sh
shad3@ubuntu:~/Desktop/$ uname -ms
Linux x86_64

shad3@ubuntu:~/Desktop/$ r2 -v
radare2 5.5.2 27243 @ linux-x86-64 git.5.5.0
commit: 79effabdf5db431e40ea2aafc7f322ca32edb876 build: 2021-12-07__12:18:24

shad3@ubuntu:~/Desktop/$ date
Tue Dec  7 14:07:20 PST 2021
```


## ASAN
Stack Trace from an ASAN build while triggering the firs bug

```
=================================================================
==91945==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6250004cb6a8 at pc 0x7f29c4016d1a bp 0x7ffe0c8bf8b0 sp 0x7ffe0c8bf058
WRITE of size 9896288 at 0x6250004cb6a8 thread T0
    #0 0x7f29c4016d19  (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x5ed19)
    #1 0x7f29c08c3157 in r_io_vread_at /home/shad3/Desktop/radare2/libr/io/io.c:203
    #2 0x7f29c08c33ec in internal_r_io_read_at /home/shad3/Desktop/radare2/libr/io/io.c:226
    #3 0x7f29c08c36b6 in r_io_read_at /home/shad3/Desktop/radare2/libr/io/io.c:264
    #4 0x7f29b99bf27b in objc_build_refs /home/shad3/Desktop/radare2/libr/core/anal_objc.c:150
    #5 0x7f29b99c0143 in objc_find_refs /home/shad3/Desktop/radare2/libr/core/anal_objc.c:231
    #6 0x7f29b99c14b5 in cmd_anal_objc /home/shad3/Desktop/radare2/libr/core/anal_objc.c:329
    #7 0x7f29b95fa8f0 in cmd_anal_all /home/shad3/Desktop/radare2/libr/core/cmd_anal.c:10595
    #8 0x7f29b9603d85 in cmd_anal /home/shad3/Desktop/radare2/libr/core/cmd_anal.c:11639
    #9 0x7f29b9828c92 in r_cmd_call /home/shad3/Desktop/radare2/libr/core/cmd_api.c:537
    #10 0x7f29b96fbea3 in r_core_cmd_subst_i /home/shad3/Desktop/radare2/libr/core/cmd.c:4392
    #11 0x7f29b96ef27b in r_core_cmd_subst /home/shad3/Desktop/radare2/libr/core/cmd.c:3279
    #12 0x7f29b9705da6 in run_cmd_depth /home/shad3/Desktop/radare2/libr/core/cmd.c:5279
    #13 0x7f29b9706add in r_core_cmd /home/shad3/Desktop/radare2/libr/core/cmd.c:5362
    #14 0x7f29b9707883 in r_core_cmd0 /home/shad3/Desktop/radare2/libr/core/cmd.c:5519
    #15 0x7f29c3151748 in r_main_radare2 /home/shad3/Desktop/radare2/libr/main/radare2.c:1390
    #16 0x560128934b4e in main /home/shad3/Desktop/radare2/binr/radare2/radare2.c:96
    #17 0x7f29c1fc8bf6 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21bf6)
    #18 0x560128934579 in _start (/home/shad3/Desktop/radare2/binr/radare2/radare2+0x1579)

0x6250004cb6a8 is located 0 bytes to the right of 9640-byte region [0x6250004c9100,0x6250004cb6a8)
allocated by thread T0 here:
    #0 0x7f29c4096d28 in __interceptor_calloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xded28)
    #1 0x7f29b99bf0a6 in objc_build_refs /home/shad3/Desktop/radare2/libr/core/anal_objc.c:145
    #2 0x7f29b99c0143 in objc_find_refs /home/shad3/Desktop/radare2/libr/core/anal_objc.c:231
    #3 0x7f29b99c14b5 in cmd_anal_objc /home/shad3/Desktop/radare2/libr/core/anal_objc.c:329
    #4 0x7f29b95fa8f0 in cmd_anal_all /home/shad3/Desktop/radare2/libr/core/cmd_anal.c:10595
    #5 0x7f29b9603d85 in cmd_anal /home/shad3/Desktop/radare2/libr/core/cmd_anal.c:11639
    #6 0x7f29b9828c92 in r_cmd_call /home/shad3/Desktop/radare2/libr/core/cmd_api.c:537
    #7 0x7f29b96fbea3 in r_core_cmd_subst_i /home/shad3/Desktop/radare2/libr/core/cmd.c:4392
    #8 0x7f29b96ef27b in r_core_cmd_subst /home/shad3/Desktop/radare2/libr/core/cmd.c:3279
    #9 0x7f29b9705da6 in run_cmd_depth /home/shad3/Desktop/radare2/libr/core/cmd.c:5279
    #10 0x7f29b9706add in r_core_cmd /home/shad3/Desktop/radare2/libr/core/cmd.c:5362
    #11 0x7f29b9707883 in r_core_cmd0 /home/shad3/Desktop/radare2/libr/core/cmd.c:5519
    #12 0x7f29c3151748 in r_main_radare2 /home/shad3/Desktop/radare2/libr/main/radare2.c:1390
    #13 0x560128934b4e in main /home/shad3/Desktop/radare2/binr/radare2/radare2.c:96
    #14 0x7f29c1fc8bf6 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21bf6)

SUMMARY: AddressSanitizer: heap-buffer-overflow (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x5ed19) 
Shadow bytes around the buggy address:
  0x0c4a80091680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c4a80091690: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c4a800916a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c4a800916b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c4a800916c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c4a800916d0: 00 00 00 00 00[fa]fa fa fa fa fa fa fa fa fa fa
  0x0c4a800916e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c4a800916f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c4a80091700: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c4a80091710: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c4a80091720: 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
==91945==ABORTING
````

## Explanation of the vulnerabilities


The vulnerability lies in the ``objc_build_refs`` function that
is responsible of building the references of a mach-o file as its name
suggests.

The function can be found out at:
```
/radare2/libr/core/anal_objc.c
```

Please consider the following code 
bellow  which has been simplified for readability:
```c


static bool objc_build_refs(RCoreObjc *objc) {
	...

	size_t ss_selrefs = objc->_selrefs->vsize;

	size_t maxsize = R_MAX (ss_const, ss_selrefs); // 1a
	maxsize = R_MIN (maxsize, objc->file_size);    // 1b

	ut8 *buf = calloc (1, maxsize);				   // 2
	if (!buf) {
		return false;
	}

	...
	if (!r_io_read_at (objc->core->io, va_selrefs, buf, ss_selrefs)) { // 3
		eprintf ("aao: Cannot read the whole selrefs section\n");
		return false;
	}
	...
	free (buf);
	return true;
}
```

At points ``1a`` and ``1b`` theres an attempt to sanitize the ``ss_selrefs``
variable as it has to be done. Based on the return value of the two macros
which is stored in the ``maxsize`` variable* an internal buffer of the function
is allocated, here called ``buf``. At point 3 there's a read operation perfomed
to the buffer based on the __unsanitized__ ``ss_selfrefs`` variable instead of the
``maxsize`` one. In case where the ``ss_selrefs`` is greater than the ``maxsize``
variable this read operation results in a heap buffer overflow.


The same vulnerability exists on the other read operation performed in the same function.
Which also results in a heap buffer overflow. 
```c
	size_t ss_const = objc->_const->vsize;
....
	if (!r_io_read_at (objc->core->io, objc->_const->vaddr, buf, ss_const)) {
		eprintf ("aao: Cannot read the whole const section %zu\n", ss_const);
		return false;
	}
	
```


PS: ``maxsize`` seems like an obscure name for that variable, it might 
be better to consider changing that, unless there's a specific reason.





## Proposed fixes
The ``r_io_read_at``  functions to be to be called with the variable
``maxsize`` instead of the ``ss_selrefs`` and ``ss_const`` as an argument.

## Notes

- Please check the attached binary that crashes
  the radare2 binary and reproduces the first vulnerability
  by running the following command e.g. in an ASAN build
  ``r2 -qq -AA crash``

- I would highly appreciate if these bugs qualify for
  CVEs to request them for me.

Heap buffer overflows in function objc_build_refs while parsing mach-o files.
This is a GitHub Issue
repo:radare2
owner:radareorg
Title : Heap buffer overflows in function objc_build_refs while parsing mach-o files.
Issue date:

--- start body ---
# Heap Buffer overflows in objc_build_refs

I have discovered two heap buffer 
overflows while parsing mach-o executables.
Please refer bellow for further information. 


## Environment


```sh
shad3@ubuntu:~/Desktop/$ uname -ms
Linux x86_64

shad3@ubuntu:~/Desktop/$ r2 -v
radare2 5.5.2 27243 @ linux-x86-64 git.5.5.0
commit: 79effabdf5db431e40ea2aafc7f322ca32edb876 build: 2021-12-07__12:18:24

shad3@ubuntu:~/Desktop/$ date
Tue Dec  7 14:07:20 PST 2021
```


## ASAN
Stack Trace from an ASAN build while triggering the firs bug

```
=================================================================
==91945==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6250004cb6a8 at pc 0x7f29c4016d1a bp 0x7ffe0c8bf8b0 sp 0x7ffe0c8bf058
WRITE of size 9896288 at 0x6250004cb6a8 thread T0
    #0 0x7f29c4016d19  (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x5ed19)
    #1 0x7f29c08c3157 in r_io_vread_at /home/shad3/Desktop/radare2/libr/io/io.c:203
    #2 0x7f29c08c33ec in internal_r_io_read_at /home/shad3/Desktop/radare2/libr/io/io.c:226
    #3 0x7f29c08c36b6 in r_io_read_at /home/shad3/Desktop/radare2/libr/io/io.c:264
    #4 0x7f29b99bf27b in objc_build_refs /home/shad3/Desktop/radare2/libr/core/anal_objc.c:150
    #5 0x7f29b99c0143 in objc_find_refs /home/shad3/Desktop/radare2/libr/core/anal_objc.c:231
    #6 0x7f29b99c14b5 in cmd_anal_objc /home/shad3/Desktop/radare2/libr/core/anal_objc.c:329
    #7 0x7f29b95fa8f0 in cmd_anal_all /home/shad3/Desktop/radare2/libr/core/cmd_anal.c:10595
    #8 0x7f29b9603d85 in cmd_anal /home/shad3/Desktop/radare2/libr/core/cmd_anal.c:11639
    #9 0x7f29b9828c92 in r_cmd_call /home/shad3/Desktop/radare2/libr/core/cmd_api.c:537
    #10 0x7f29b96fbea3 in r_core_cmd_subst_i /home/shad3/Desktop/radare2/libr/core/cmd.c:4392
    #11 0x7f29b96ef27b in r_core_cmd_subst /home/shad3/Desktop/radare2/libr/core/cmd.c:3279
    #12 0x7f29b9705da6 in run_cmd_depth /home/shad3/Desktop/radare2/libr/core/cmd.c:5279
    #13 0x7f29b9706add in r_core_cmd /home/shad3/Desktop/radare2/libr/core/cmd.c:5362
    #14 0x7f29b9707883 in r_core_cmd0 /home/shad3/Desktop/radare2/libr/core/cmd.c:5519
    #15 0x7f29c3151748 in r_main_radare2 /home/shad3/Desktop/radare2/libr/main/radare2.c:1390
    #16 0x560128934b4e in main /home/shad3/Desktop/radare2/binr/radare2/radare2.c:96
    #17 0x7f29c1fc8bf6 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21bf6)
    #18 0x560128934579 in _start (/home/shad3/Desktop/radare2/binr/radare2/radare2+0x1579)

0x6250004cb6a8 is located 0 bytes to the right of 9640-byte region [0x6250004c9100,0x6250004cb6a8)
allocated by thread T0 here:
    #0 0x7f29c4096d28 in __interceptor_calloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xded28)
    #1 0x7f29b99bf0a6 in objc_build_refs /home/shad3/Desktop/radare2/libr/core/anal_objc.c:145
    #2 0x7f29b99c0143 in objc_find_refs /home/shad3/Desktop/radare2/libr/core/anal_objc.c:231
    #3 0x7f29b99c14b5 in cmd_anal_objc /home/shad3/Desktop/radare2/libr/core/anal_objc.c:329
    #4 0x7f29b95fa8f0 in cmd_anal_all /home/shad3/Desktop/radare2/libr/core/cmd_anal.c:10595
    #5 0x7f29b9603d85 in cmd_anal /home/shad3/Desktop/radare2/libr/core/cmd_anal.c:11639
    #6 0x7f29b9828c92 in r_cmd_call /home/shad3/Desktop/radare2/libr/core/cmd_api.c:537
    #7 0x7f29b96fbea3 in r_core_cmd_subst_i /home/shad3/Desktop/radare2/libr/core/cmd.c:4392
    #8 0x7f29b96ef27b in r_core_cmd_subst /home/shad3/Desktop/radare2/libr/core/cmd.c:3279
    #9 0x7f29b9705da6 in run_cmd_depth /home/shad3/Desktop/radare2/libr/core/cmd.c:5279
    #10 0x7f29b9706add in r_core_cmd /home/shad3/Desktop/radare2/libr/core/cmd.c:5362
    #11 0x7f29b9707883 in r_core_cmd0 /home/shad3/Desktop/radare2/libr/core/cmd.c:5519
    #12 0x7f29c3151748 in r_main_radare2 /home/shad3/Desktop/radare2/libr/main/radare2.c:1390
    #13 0x560128934b4e in main /home/shad3/Desktop/radare2/binr/radare2/radare2.c:96
    #14 0x7f29c1fc8bf6 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21bf6)

SUMMARY: AddressSanitizer: heap-buffer-overflow (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x5ed19) 
Shadow bytes around the buggy address:
  0x0c4a80091680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c4a80091690: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c4a800916a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c4a800916b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c4a800916c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c4a800916d0: 00 00 00 00 00[fa]fa fa fa fa fa fa fa fa fa fa
  0x0c4a800916e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c4a800916f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c4a80091700: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c4a80091710: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c4a80091720: 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
==91945==ABORTING
````

## Explanation of the vulnerabilities


The vulnerability lies in the ``objc_build_refs`` function that
is responsible of building the references of a mach-o file as its name
suggests.

The function can be found out at:
```
/radare2/libr/core/anal_objc.c
```

Please consider the following code 
bellow  which has been simplified for readability:
```c


static bool objc_build_refs(RCoreObjc *objc) {
	...

	size_t ss_selrefs = objc->_selrefs->vsize;

	size_t maxsize = R_MAX (ss_const, ss_selrefs); // 1a
	maxsize = R_MIN (maxsize, objc->file_size);    // 1b

	ut8 *buf = calloc (1, maxsize);				   // 2
	if (!buf) {
		return false;
	}

	...
	if (!r_io_read_at (objc->core->io, va_selrefs, buf, ss_selrefs)) { // 3
		eprintf ("aao: Cannot read the whole selrefs section\n");
		return false;
	}
	...
	free (buf);
	return true;
}
```

At points ``1a`` and ``1b`` theres an attempt to sanitize the ``ss_selrefs``
variable as it has to be done. Based on the return value of the two macros
which is stored in the ``maxsize`` variable* an internal buffer of the function
is allocated, here called ``buf``. At point 3 there's a read operation perfomed
to the buffer based on the __unsanitized__ ``ss_selfrefs`` variable instead of the
``maxsize`` one. In case where the ``ss_selrefs`` is greater than the ``maxsize``
variable this read operation results in a heap buffer overflow.


The same vulnerability exists on the other read operation performed in the same function.
Which also results in a heap buffer overflow. 
```c
	size_t ss_const = objc->_const->vsize;
....
	if (!r_io_read_at (objc->core->io, objc->_const->vaddr, buf, ss_const)) {
		eprintf ("aao: Cannot read the whole const section %zu\n", ss_const);
		return false;
	}
	
```


PS: ``maxsize`` seems like an obscure name for that variable, it might 
be better to consider changing that, unless there's a specific reason.





## Proposed fixes
The ``r_io_read_at``  functions to be to be called with the variable
``maxsize`` instead of the ``ss_selrefs`` and ``ss_const`` as an argument.

## Notes

- Please check the attached binary that crashes
  the radare2 binary and reproduces the first vulnerability
  by running the following command e.g. in an ASAN build
  ``r2 -qq -AA crash``

- I would highly appreciate if these bugs qualify for
  CVEs to request them for me.

--- end body ---

comments :
--- start comments ---

--- end comments ---