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

[Bug #20398] Fix heap-buffer-overflow read in set_number_literal #10393

Conversation

KJTsanaktsidis
Copy link
Contributor

@KJTsanaktsidis KJTsanaktsidis commented Mar 28, 2024

It appears that tok(p) is not NULL terminated here, so we need to use strndup to copy only the correct number of bytes.

[1/1] TestRubyLiteral#test_integer================================================================= ==484771==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x5060001ab1fc at pc 0x5597fe21d8e1 bp 0x7ffdc6fb0a50 sp 0x7ffdc6fb0210 READ of size 61 at 0x5060001ab1fc thread T0
    #0 0x5597fe21d8e0 in strlen.part.0 /home/kj/llvm-project/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:391:5
    #1 0x5597fe6b2feb in ruby_strdup /home/kj/ruby/build/../util.c:538:18
    #2 0x5597fe4cb1c5 in set_number_literal /home/kj/ruby/build/parse.y:9694:9
    #3 0x5597fe4cab3d in no_digits /home/kj/ruby/build/parse.y:10409:12
    #4 0x5597fe4b9de9 in parse_numeric /home/kj/ruby/build/parse.y
    #5 0x5597fe4a8adf in parser_yylex /home/kj/ruby/build/parse.y
    #6 0x5597fe45c5cd in yylex /home/kj/ruby/build/parse.y:11916:9
    #7 0x5597fe45c5cd in ruby_yyparse /home/kj/ruby/build/parse.c:11200:16
    #8 0x5597fe49dc00 in yycompile0 /home/kj/ruby/build/parse.y:8121:9
    #9 0x5597fe76db1b in rb_suppress_tracing /home/kj/ruby/build/../vm_trace.c:487:18
    #10 0x5597fe494416 in yycompile /home/kj/ruby/build/parse.y:8177:5
    #11 0x5597fe494416 in parser_compile_string /home/kj/ruby/build/parse.y:8240:12
    #12 0x5597fe494416 in rb_ruby_parser_compile_string_path /home/kj/ruby/build/parse.y:8247:12
    #13 0x5597fe498858 in rb_parser_compile_string_path /home/kj/ruby/build/parse.y:16663:12
    #14 0x5597fe75688c in eval_make_iseq /home/kj/ruby/build/../vm_eval.c:1799:11
    #15 0x5597fe70c8fa in eval_string_with_cref /home/kj/ruby/build/../vm_eval.c:1837:12
    #16 0x5597fe70c396 in rb_f_eval /home/kj/ruby/build/../vm_eval.c:1912:16
    #17 0x5597fe73f5e2 in vm_call_cfunc_with_frame_ /home/kj/ruby/build/../vm_insnhelper.c:3492:11
    #18 0x5597fe6dca64 in vm_sendish /home/kj/ruby/build/../vm_callinfo.h
    #19 0x5597fe6e64fa in vm_exec_core /home/kj/ruby/build/../insns.def:867:11
    #20 0x5597fe6dde00 in vm_exec_loop /home/kj/ruby/build/../vm.c:2578:22
    #21 0x5597fe6dde00 in rb_vm_exec /home/kj/ruby/build/../vm.c:2557:18
    #22 0x5597fe758bc4 in invoke_block /home/kj/ruby/build/../vm.c:1515:12
    #23 0x5597fe758bc4 in invoke_iseq_block_from_c /home/kj/ruby/build/../vm.c:1585:16
    #24 0x5597fe758bc4 in invoke_block_from_c_bh /home/kj/ruby/build/../vm.c:1603:20
    #25 0x5597fe70e4b7 in vm_yield_with_cref /home/kj/ruby/build/../vm.c:1640:12
    #26 0x5597fe709861 in vm_yield /home/kj/ruby/build/../vm.c:1648:12
    #27 0x5597fe709861 in rb_yield_0 /home/kj/ruby/build/../vm_eval.c:1366:12
    #28 0x5597fe709861 in rb_yield /home/kj/ruby/build/../vm_eval.c
    #29 0x5597fec0eff9 in rb_ary_collect /home/kj/ruby/build/../array.c:3601:30
    #30 0x5597fe73f5e2 in vm_call_cfunc_with_frame_ /home/kj/ruby/build/../vm_insnhelper.c:3492:11
    #31 0x5597fe6dca64 in vm_sendish /home/kj/ruby/build/../vm_callinfo.h
    #32 0x5597fe6e2d8f in vm_exec_core /home/kj/ruby/build/../insns.def:847:11
    #33 0x5597fe6dde00 in vm_exec_loop /home/kj/ruby/build/../vm.c:2578:22
    #34 0x5597fe6dde00 in rb_vm_exec /home/kj/ruby/build/../vm.c:2557:18
    #35 0x5597fe3ffe9e in load_iseq_eval /home/kj/ruby/build/../load.c:778:5
    #36 0x5597fe3fb498 in require_internal /home/kj/ruby/build/../load.c:1284:21
    #37 0x5597fe3f9bf3 in rb_require_string_internal /home/kj/ruby/build/../load.c:1383:18
    #38 0x5597fe73f5e2 in vm_call_cfunc_with_frame_ /home/kj/ruby/build/../vm_insnhelper.c:3492:11
    #39 0x5597fe6dca64 in vm_sendish /home/kj/ruby/build/../vm_callinfo.h
    #40 0x5597fe6e64fa in vm_exec_core /home/kj/ruby/build/../insns.def:867:11
    #41 0x5597fe6dda82 in rb_vm_exec /home/kj/ruby/build/../vm.c:2551:22
    #42 0x5597fe30a753 in rb_ec_exec_node /home/kj/ruby/build/../eval.c:283:9
    #43 0x5597fe30a43d in ruby_run_node /home/kj/ruby/build/../eval.c:323:30
    #44 0x5597fe3059b0 in rb_main /home/kj/ruby/build/../main.c:40:12
    #45 0x5597fe3059b0 in main /home/kj/ruby/build/../main.c:59:12
    #46 0x7f1a93141149 in __libc_start_call_main /usr/src/debug/glibc-2.38-16.fc39.x86_64/csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #47 0x7f1a9314120a in __libc_start_main@GLIBC_2.2.5 /usr/src/debug/glibc-2.38-16.fc39.x86_64/csu/../csu/libc-start.c:360:3
    #48 0x5597fe1d3e34 in _start (/home/kj/ruby/build/ruby+0x38ae34)

0x5060001ab1fc is located 0 bytes after 60-byte region [0x5060001ab1c0,0x5060001ab1fc) allocated by thread T0 here:
    #0 0x5597fe2bde4f in malloc /home/kj/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:68:3
    #1 0x5597fe3491a9 in objspace_xmalloc0 /home/kj/ruby/build/../gc.c:12605:5
    #2 0x5597fe4a8adf in parser_yylex /home/kj/ruby/build/parse.y
    #3 0x5597fe45c5cd in yylex /home/kj/ruby/build/parse.y:11916:9
    #4 0x5597fe45c5cd in ruby_yyparse /home/kj/ruby/build/parse.c:11200:16
    #5 0x5597fe49dc00 in yycompile0 /home/kj/ruby/build/parse.y:8121:9

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/kj/ruby/build/../util.c:538:18 in ruby_strdup Shadow bytes around the buggy address:
  0x5060001aaf00: fa fa fa fa fd fd fd fd fd fd fd fd fa fa fa fa
  0x5060001aaf80: 00 00 00 00 00 00 00 04 fa fa fa fa 00 00 00 00
  0x5060001ab000: 00 00 00 fa fa fa fa fa 00 00 00 00 00 00 00 fa
  0x5060001ab080: fa fa fa fa 00 00 00 00 00 00 00 00 fa fa fa fa
  0x5060001ab100: 00 00 00 00 00 00 00 00 fa fa fa fa 00 00 00 00
=>0x5060001ab180: 00 00 00 00 fa fa fa fa 00 00 00 00 00 00 00[04]
  0x5060001ab200: fa fa fa fa fd fd fd fd fd fd fd fd fa fa fa fa
  0x5060001ab280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x5060001ab300: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x5060001ab380: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x5060001ab400: 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
==484771==ABORTING

[Bug #20398]

@KJTsanaktsidis
Copy link
Contributor Author

Oh, strndup is a GNU-ism and not in visual studio. Hm. I'll add a basic implementation to missing/strndup.c

Visual studio doesn't seem to have it. I copied the implementation from
OpenBSD, since there are other OpenBSD string functions in missing/ and
they are appropriately licensed.
It appears that tok(p) is not NULL terminated here, so we need to use
strndup to copy only the correct number of bytes.

[1/1] TestRubyLiteral#test_integer=================================================================
==484771==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x5060001ab1fc at pc 0x5597fe21d8e1 bp 0x7ffdc6fb0a50 sp 0x7ffdc6fb0210
READ of size 61 at 0x5060001ab1fc thread T0
    #0 0x5597fe21d8e0 in strlen.part.0 /home/kj/llvm-project/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:391:5
    #1 0x5597fe6b2feb in ruby_strdup /home/kj/ruby/build/../util.c:538:18
    ruby#2 0x5597fe4cb1c5 in set_number_literal /home/kj/ruby/build/parse.y:9694:9
    ruby#3 0x5597fe4cab3d in no_digits /home/kj/ruby/build/parse.y:10409:12
    ruby#4 0x5597fe4b9de9 in parse_numeric /home/kj/ruby/build/parse.y
    ruby#5 0x5597fe4a8adf in parser_yylex /home/kj/ruby/build/parse.y
    ruby#6 0x5597fe45c5cd in yylex /home/kj/ruby/build/parse.y:11916:9
    ruby#7 0x5597fe45c5cd in ruby_yyparse /home/kj/ruby/build/parse.c:11200:16
    ruby#8 0x5597fe49dc00 in yycompile0 /home/kj/ruby/build/parse.y:8121:9
    ruby#9 0x5597fe76db1b in rb_suppress_tracing /home/kj/ruby/build/../vm_trace.c:487:18
    ruby#10 0x5597fe494416 in yycompile /home/kj/ruby/build/parse.y:8177:5
    ruby#11 0x5597fe494416 in parser_compile_string /home/kj/ruby/build/parse.y:8240:12
    ruby#12 0x5597fe494416 in rb_ruby_parser_compile_string_path /home/kj/ruby/build/parse.y:8247:12
    ruby#13 0x5597fe498858 in rb_parser_compile_string_path /home/kj/ruby/build/parse.y:16663:12
    ruby#14 0x5597fe75688c in eval_make_iseq /home/kj/ruby/build/../vm_eval.c:1799:11
    ruby#15 0x5597fe70c8fa in eval_string_with_cref /home/kj/ruby/build/../vm_eval.c:1837:12
    ruby#16 0x5597fe70c396 in rb_f_eval /home/kj/ruby/build/../vm_eval.c:1912:16
    ruby#17 0x5597fe73f5e2 in vm_call_cfunc_with_frame_ /home/kj/ruby/build/../vm_insnhelper.c:3492:11
    ruby#18 0x5597fe6dca64 in vm_sendish /home/kj/ruby/build/../vm_callinfo.h
    ruby#19 0x5597fe6e64fa in vm_exec_core /home/kj/ruby/build/../insns.def:867:11
    #20 0x5597fe6dde00 in vm_exec_loop /home/kj/ruby/build/../vm.c:2578:22
    ruby#21 0x5597fe6dde00 in rb_vm_exec /home/kj/ruby/build/../vm.c:2557:18
    ruby#22 0x5597fe758bc4 in invoke_block /home/kj/ruby/build/../vm.c:1515:12
    ruby#23 0x5597fe758bc4 in invoke_iseq_block_from_c /home/kj/ruby/build/../vm.c:1585:16
    ruby#24 0x5597fe758bc4 in invoke_block_from_c_bh /home/kj/ruby/build/../vm.c:1603:20
    ruby#25 0x5597fe70e4b7 in vm_yield_with_cref /home/kj/ruby/build/../vm.c:1640:12
    ruby#26 0x5597fe709861 in vm_yield /home/kj/ruby/build/../vm.c:1648:12
    ruby#27 0x5597fe709861 in rb_yield_0 /home/kj/ruby/build/../vm_eval.c:1366:12
    ruby#28 0x5597fe709861 in rb_yield /home/kj/ruby/build/../vm_eval.c
    ruby#29 0x5597fec0eff9 in rb_ary_collect /home/kj/ruby/build/../array.c:3601:30
    ruby#30 0x5597fe73f5e2 in vm_call_cfunc_with_frame_ /home/kj/ruby/build/../vm_insnhelper.c:3492:11
    ruby#31 0x5597fe6dca64 in vm_sendish /home/kj/ruby/build/../vm_callinfo.h
    ruby#32 0x5597fe6e2d8f in vm_exec_core /home/kj/ruby/build/../insns.def:847:11
    ruby#33 0x5597fe6dde00 in vm_exec_loop /home/kj/ruby/build/../vm.c:2578:22
    ruby#34 0x5597fe6dde00 in rb_vm_exec /home/kj/ruby/build/../vm.c:2557:18
    ruby#35 0x5597fe3ffe9e in load_iseq_eval /home/kj/ruby/build/../load.c:778:5
    ruby#36 0x5597fe3fb498 in require_internal /home/kj/ruby/build/../load.c:1284:21
    ruby#37 0x5597fe3f9bf3 in rb_require_string_internal /home/kj/ruby/build/../load.c:1383:18
    ruby#38 0x5597fe73f5e2 in vm_call_cfunc_with_frame_ /home/kj/ruby/build/../vm_insnhelper.c:3492:11
    ruby#39 0x5597fe6dca64 in vm_sendish /home/kj/ruby/build/../vm_callinfo.h
    ruby#40 0x5597fe6e64fa in vm_exec_core /home/kj/ruby/build/../insns.def:867:11
    ruby#41 0x5597fe6dda82 in rb_vm_exec /home/kj/ruby/build/../vm.c:2551:22
    ruby#42 0x5597fe30a753 in rb_ec_exec_node /home/kj/ruby/build/../eval.c:283:9
    ruby#43 0x5597fe30a43d in ruby_run_node /home/kj/ruby/build/../eval.c:323:30
    ruby#44 0x5597fe3059b0 in rb_main /home/kj/ruby/build/../main.c:40:12
    ruby#45 0x5597fe3059b0 in main /home/kj/ruby/build/../main.c:59:12
    ruby#46 0x7f1a93141149 in __libc_start_call_main /usr/src/debug/glibc-2.38-16.fc39.x86_64/csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    ruby#47 0x7f1a9314120a in __libc_start_main@GLIBC_2.2.5 /usr/src/debug/glibc-2.38-16.fc39.x86_64/csu/../csu/libc-start.c:360:3
    ruby#48 0x5597fe1d3e34 in _start (/home/kj/ruby/build/ruby+0x38ae34)

0x5060001ab1fc is located 0 bytes after 60-byte region [0x5060001ab1c0,0x5060001ab1fc)
allocated by thread T0 here:
    #0 0x5597fe2bde4f in malloc /home/kj/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:68:3
    #1 0x5597fe3491a9 in objspace_xmalloc0 /home/kj/ruby/build/../gc.c:12605:5
    ruby#2 0x5597fe4a8adf in parser_yylex /home/kj/ruby/build/parse.y
    ruby#3 0x5597fe45c5cd in yylex /home/kj/ruby/build/parse.y:11916:9
    ruby#4 0x5597fe45c5cd in ruby_yyparse /home/kj/ruby/build/parse.c:11200:16
    ruby#5 0x5597fe49dc00 in yycompile0 /home/kj/ruby/build/parse.y:8121:9

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/kj/ruby/build/../util.c:538:18 in ruby_strdup
Shadow bytes around the buggy address:
  0x5060001aaf00: fa fa fa fa fd fd fd fd fd fd fd fd fa fa fa fa
  0x5060001aaf80: 00 00 00 00 00 00 00 04 fa fa fa fa 00 00 00 00
  0x5060001ab000: 00 00 00 fa fa fa fa fa 00 00 00 00 00 00 00 fa
  0x5060001ab080: fa fa fa fa 00 00 00 00 00 00 00 00 fa fa fa fa
  0x5060001ab100: 00 00 00 00 00 00 00 00 fa fa fa fa 00 00 00 00
=>0x5060001ab180: 00 00 00 00 fa fa fa fa 00 00 00 00 00 00 00[04]
  0x5060001ab200: fa fa fa fa fd fd fd fd fd fd fd fd fa fa fa fa
  0x5060001ab280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x5060001ab300: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x5060001ab380: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x5060001ab400: 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
==484771==ABORTING

[Bug #20398]
@KJTsanaktsidis KJTsanaktsidis force-pushed the ktsanaktsidis/parser_heap_overflow_numeric_lit branch from 55c6dd2 to f5f9a02 Compare March 28, 2024 05:17
@KJTsanaktsidis
Copy link
Contributor Author

Fixed by 2ab9fb1 instead

@KJTsanaktsidis KJTsanaktsidis deleted the ktsanaktsidis/parser_heap_overflow_numeric_lit branch March 29, 2024 06:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
1 participant