Skip to content

Commit

Permalink
Fix heap-buffer-overflow read in set_number_literal
Browse files Browse the repository at this point in the history
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]
  • Loading branch information
KJTsanaktsidis committed Mar 28, 2024
1 parent 0159887 commit f5f9a02
Showing 1 changed file with 4 additions and 4 deletions.
8 changes: 4 additions & 4 deletions parse.y
Expand Up @@ -9315,16 +9315,16 @@ set_number_literal(struct parser_params *p, enum yytokentype type, int suffix, i

switch (type) {
case tINTEGER:
set_yylval_node(NEW_INTEGER(strdup(tok(p)), base, &_cur_loc));
set_yylval_node(NEW_INTEGER(strndup(tok(p), toklen(p)), base, &_cur_loc));
break;
case tFLOAT:
set_yylval_node(NEW_FLOAT(strdup(tok(p)), &_cur_loc));
set_yylval_node(NEW_FLOAT(strndup(tok(p), toklen(p)), &_cur_loc));
break;
case tRATIONAL:
set_yylval_node(NEW_RATIONAL(strdup(tok(p)), base, seen_point, &_cur_loc));
set_yylval_node(NEW_RATIONAL(strndup(tok(p), toklen(p)), base, seen_point, &_cur_loc));
break;
case tIMAGINARY:
set_yylval_node(NEW_IMAGINARY(strdup(tok(p)), base, seen_point, numeric_type, &_cur_loc));
set_yylval_node(NEW_IMAGINARY(strndup(tok(p), toklen(p)), base, seen_point, numeric_type, &_cur_loc));
(void)numeric_type; /* for ripper */
break;
default:
Expand Down

0 comments on commit f5f9a02

Please sign in to comment.