Project

General

Profile

Actions

Bug #16105

closed

heap-use-after-free in String#sub!

Added by bannable (Joe Truba) over 5 years ago. Updated over 5 years ago.

Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
ruby 2.7.0dev (2019-08-14T18:22:07Z master d5c60214c4) [x86_64-linux]
[ruby-core:94356]

Description

#15946 caught my eye, so I ran the reproducer there through a build with AddressSanitizer (ASAN) enabled. It looks like String#sub! still has some corruption going on even after the memmove change.

Reproducer:

a = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
b = a.dup
c = a.slice(1, 100)
b.sub!(c, b)

Crash:

=================================================================
==65063==ERROR: AddressSanitizer: heap-use-after-free on address 0x604000095850 at pc 0x55a9c2dda9c1 bp 0x7ffc5a735af0 sp 0x7ffc5a735ae8
READ of size 35 at 0x604000095850 thread T0
    #0 0x55a9c2dda9c0 in rb_str_sub_bang /home/jtruba/rubies/ruby-trunk/string.c:5110
    #1 0x55a9c2e9b7b2 in call_cfunc_m1 /home/jtruba/rubies/ruby-trunk/vm_insnhelper.c:2034
    #2 0x55a9c2e9d642 in vm_call_cfunc_with_frame /home/jtruba/rubies/ruby-trunk/vm_insnhelper.c:2200
    #3 0x55a9c2e9d90a in vm_call_cfunc /home/jtruba/rubies/ruby-trunk/vm_insnhelper.c:2218
    #4 0x55a9c2ea0937 in vm_call_method_each_type /home/jtruba/rubies/ruby-trunk/vm_insnhelper.c:2553
    #5 0x55a9c2ea19b9 in vm_call_method /home/jtruba/rubies/ruby-trunk/vm_insnhelper.c:2682
    #6 0x55a9c2ea1e92 in vm_call_general /home/jtruba/rubies/ruby-trunk/vm_insnhelper.c:2726
    #7 0x55a9c2ea5a2c in vm_sendish /home/jtruba/rubies/ruby-trunk/vm_insnhelper.c:3619
    #8 0x55a9c2eb22b7 in vm_exec_core /home/jtruba/rubies/ruby-trunk/insns.def:789
    #9 0x55a9c2ed8418 in rb_vm_exec /home/jtruba/rubies/ruby-trunk/vm.c:1888
    #10 0x55a9c2eda90d in rb_iseq_eval_main /home/jtruba/rubies/ruby-trunk/vm.c:2147
    #11 0x55a9c2b0ea10 in rb_ec_exec_node /home/jtruba/rubies/ruby-trunk/eval.c:273
    #12 0x55a9c2b0ed09 in ruby_run_node /home/jtruba/rubies/ruby-trunk/eval.c:331
    #13 0x55a9c2b07a6e in main main.c:50
    #14 0x7f73d3407b44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b44)
    #15 0x55a9c2b07868 (/home/jtruba/.rubies/ruby-trunk/bin/ruby+0xc7868)

0x604000095850 is located 0 bytes inside of 36-byte region [0x604000095850,0x604000095874)
freed by thread T0 here:
    #0 0x7f73d45c99f6 in __interceptor_realloc (/usr/lib/x86_64-linux-gnu/libasan.so.1+0x549f6)
    #1 0x55a9c2b54c92 in objspace_xrealloc /home/jtruba/rubies/ruby-trunk/gc.c:9740
    #2 0x55a9c2b5513a in ruby_sized_xrealloc2 /home/jtruba/rubies/ruby-trunk/gc.c:9953
    #3 0x55a9c2b5516e in ruby_xrealloc2_body /home/jtruba/rubies/ruby-trunk/gc.c:9959
    #4 0x55a9c2b5bd0b in ruby_xrealloc2 /home/jtruba/rubies/ruby-trunk/gc.c:11793
    #5 0x55a9c2dda6eb in rb_str_sub_bang /home/jtruba/rubies/ruby-trunk/string.c:5104
    #6 0x55a9c2e9b7b2 in call_cfunc_m1 /home/jtruba/rubies/ruby-trunk/vm_insnhelper.c:2034
    #7 0x55a9c2e9d642 in vm_call_cfunc_with_frame /home/jtruba/rubies/ruby-trunk/vm_insnhelper.c:2200
    #8 0x55a9c2e9d90a in vm_call_cfunc /home/jtruba/rubies/ruby-trunk/vm_insnhelper.c:2218
    #9 0x55a9c2ea0937 in vm_call_method_each_type /home/jtruba/rubies/ruby-trunk/vm_insnhelper.c:2553
    #10 0x55a9c2ea19b9 in vm_call_method /home/jtruba/rubies/ruby-trunk/vm_insnhelper.c:2682
    #11 0x55a9c2ea1e92 in vm_call_general /home/jtruba/rubies/ruby-trunk/vm_insnhelper.c:2726
    #12 0x55a9c2ea5a2c in vm_sendish /home/jtruba/rubies/ruby-trunk/vm_insnhelper.c:3619
    #13 0x55a9c2eb22b7 in vm_exec_core /home/jtruba/rubies/ruby-trunk/insns.def:789
    #14 0x55a9c2ed8418 in rb_vm_exec /home/jtruba/rubies/ruby-trunk/vm.c:1888
    #15 0x55a9c2eda90d in rb_iseq_eval_main /home/jtruba/rubies/ruby-trunk/vm.c:2147
    #16 0x55a9c2b0ea10 in rb_ec_exec_node /home/jtruba/rubies/ruby-trunk/eval.c:273
    #17 0x55a9c2b0ed09 in ruby_run_node /home/jtruba/rubies/ruby-trunk/eval.c:331
    #18 0x55a9c2b07a6e in main main.c:50
    #19 0x7f73d3407b44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b44)

previously allocated by thread T0 here:
    #0 0x7f73d45c973f in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.1+0x5473f)
    #1 0x55a9c2b54a64 in objspace_xmalloc0 /home/jtruba/rubies/ruby-trunk/gc.c:9698
    #2 0x55a9c2b54ebd in ruby_xmalloc2_body /home/jtruba/rubies/ruby-trunk/gc.c:9905
    #3 0x55a9c2b5bc94 in ruby_xmalloc2 /home/jtruba/rubies/ruby-trunk/gc.c:11763
    #4 0x55a9c2dc6f53 in str_make_independent_expand /home/jtruba/rubies/ruby-trunk/string.c:2132
    #5 0x55a9c2db899f in str_make_independent /home/jtruba/rubies/ruby-trunk/string.c:193
    #6 0x55a9c2dc739d in rb_str_modify /home/jtruba/rubies/ruby-trunk/string.c:2152
    #7 0x55a9c2dd9eec in rb_str_sub_bang /home/jtruba/rubies/ruby-trunk/string.c:5089
    #8 0x55a9c2e9b7b2 in call_cfunc_m1 /home/jtruba/rubies/ruby-trunk/vm_insnhelper.c:2034
    #9 0x55a9c2e9d642 in vm_call_cfunc_with_frame /home/jtruba/rubies/ruby-trunk/vm_insnhelper.c:2200
    #10 0x55a9c2e9d90a in vm_call_cfunc /home/jtruba/rubies/ruby-trunk/vm_insnhelper.c:2218
    #11 0x55a9c2ea0937 in vm_call_method_each_type /home/jtruba/rubies/ruby-trunk/vm_insnhelper.c:2553
    #12 0x55a9c2ea19b9 in vm_call_method /home/jtruba/rubies/ruby-trunk/vm_insnhelper.c:2682
    #13 0x55a9c2ea1e92 in vm_call_general /home/jtruba/rubies/ruby-trunk/vm_insnhelper.c:2726
    #14 0x55a9c2ea5a2c in vm_sendish /home/jtruba/rubies/ruby-trunk/vm_insnhelper.c:3619
    #15 0x55a9c2eb22b7 in vm_exec_core /home/jtruba/rubies/ruby-trunk/insns.def:789
    #16 0x55a9c2ed8418 in rb_vm_exec /home/jtruba/rubies/ruby-trunk/vm.c:1888
    #17 0x55a9c2eda90d in rb_iseq_eval_main /home/jtruba/rubies/ruby-trunk/vm.c:2147
    #18 0x55a9c2b0ea10 in rb_ec_exec_node /home/jtruba/rubies/ruby-trunk/eval.c:273
    #19 0x55a9c2b0ed09 in ruby_run_node /home/jtruba/rubies/ruby-trunk/eval.c:331
    #20 0x55a9c2b07a6e in main main.c:50
    #21 0x7f73d3407b44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b44)

SUMMARY: AddressSanitizer: heap-use-after-free /home/jtruba/rubies/ruby-trunk/string.c:5110 rb_str_sub_bang
Shadow bytes around the buggy address:
  0x0c088000aab0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c088000aac0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c088000aad0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c088000aae0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c088000aaf0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c088000ab00: fa fa 00 00 00 00 05 fa fa fa[fd]fd fd fd fd fa
  0x0c088000ab10: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 03
  0x0c088000ab20: fa fa 00 00 00 00 00 02 fa fa 00 00 00 00 03 fa
  0x0c088000ab30: fa fa 00 00 00 00 04 fa fa fa 00 00 00 00 00 05
  0x0c088000ab40: fa fa 00 00 00 00 03 fa fa fa 00 00 00 00 06 fa
  0x0c088000ab50: fa fa 00 00 00 00 00 00 fa fa 00 00 00 00 00 00
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
  Heap right redzone:      fb
  Freed heap region:       fd

I compiled w/ ASAN as follows:

./configure CFLAGS="-O0 -fno-omit-frame-pointer -g3 -fsanitize=address" LDFLAGS="-O0 -fno-omit-frame-pointer -g3 -fsanitize=address" --prefix ~/.rubies/ruby-trunk --disable-install-doc --disable-install-rdoc
LDFLAGS="-O0 -fno-omit-frame-pointer -g3 -fsanitize=address" CFLAGS="-O0 -fno-omit-frame-pointer -g3 -fsanitize=address" ASAN_OPTIONS=detect_leaks=0 make
Actions #1

Updated by nobu (Nobuyoshi Nakada) over 5 years ago

  • Status changed from Open to Closed

Applied in changeset git|d5c33364e3c0efb15e11df417c925afee2cdb9c9.


Fixed heap-use-after-free

  • string.c (rb_str_sub_bang): retrieves a pointer to the
    replacement string buffer just before using it, for the case of
    replacement with the receiver string itself. [Bug #16105]
Actions #2

Updated by nobu (Nobuyoshi Nakada) over 5 years ago

  • Backport changed from 2.5: UNKNOWN, 2.6: UNKNOWN to 2.5: REQUIRED, 2.6: REQUIRED

Updated by nagachika (Tomoyuki Chikanaga) over 5 years ago

  • Backport changed from 2.5: REQUIRED, 2.6: REQUIRED to 2.5: REQUIRED, 2.6: DONE

ruby_2_6 r67747 merged revision(s) d5c33364e3c0efb15e11df417c925afee2cdb9c9.

Updated by usa (Usaku NAKAMURA) over 5 years ago

  • Backport changed from 2.5: REQUIRED, 2.6: DONE to 2.5: DONE, 2.6: DONE

ruby_2_5 r67773 merged revision(s) d5c33364e3c0efb15e11df417c925afee2cdb9c9.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0