Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Heap buffer overflows in function objc_build_refs while parsing mach-o files. #19476

Closed
0xShad3 opened this issue Dec 7, 2021 · 2 comments
Closed

Comments

@0xShad3
Copy link

0xShad3 commented Dec 7, 2021

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

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:

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.

	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.

@0xShad3
Copy link
Author

0xShad3 commented Dec 7, 2021

crash.zip

@0xShad3 0xShad3 changed the title Heap buffer overflow in function objc_build_refs while parsing mach-o files. Heap buffer overflows in function objc_build_refs while parsing mach-o files. Dec 7, 2021
trufae pushed a commit that referenced this issue Dec 9, 2021
@trufae trufae closed this as completed in fdc9f4c Dec 9, 2021
aemmitt-ns pushed a commit to aemmitt-ns/radare2 that referenced this issue Jan 26, 2022
@dglynos
Copy link

dglynos commented May 24, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants