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

Multiple AddressSanitizer memory violations #351

Open
mschwager opened this issue Mar 28, 2024 · 3 comments
Open

Multiple AddressSanitizer memory violations #351

mschwager opened this issue Mar 28, 2024 · 3 comments

Comments

@mschwager
Copy link

Hi there,

I've been working on a new fuzzer for Ruby, and I used your library as a test harness. I've found a number of AddressSanitizer memory violations occurring when parsing malformed XML files. I haven't had time to dig into each one and confirm the bug, but I wanted to get them in front of you and see what you think. Note that reproducing these violations requires compiling the ox C extension with AddressSanitizer.

I targeted two functions: Ox.parse and Ox.sax_parse.


First, Ox.parse. I used the following harness to fuzz it:

require 'ox'

test_one_input = lambda do |data|
  begin
    Ox.parse(data)
  rescue Ox::ParseError, Ox::SyntaxError, EncodingError
    # Ignore these exceptions
  end
  return 0
end

Fuzzing produced the following three violations:

stack-buffer-overflow in collapse_special
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 3541394060
INFO: Loaded 1 modules   (2917 inline 8-bit counters): 2917 [0xffff90c058e0, 0xffff90c06445), 
INFO: Loaded 1 PC tables (2917 PCs): 2917 [0xffff90c06448,0xffff90c11a98), 
bin/test_harness_ox.rb: Running 1 inputs 1 time(s) each.
Running: crashes/crash-765a10b8075fbb3078b1c84f6449ce179280f013.txt
=================================================================
==146==ERROR: AddressSanitizer: stack-buffer-overflow on address 0xffffae10003f at pc 0xffff90bb02f4 bp 0xfffffc9190f0 sp 0xfffffc9190e8
WRITE of size 1 at 0xffffae10003f thread T0
    #0 0xffff90bb02f0 in collapse_special /usr/local/bundle/gems/ox-2.14.18/ext/ox/parse.c:1155:24
    #1 0xffff90ba97d8 in read_element /usr/local/bundle/gems/ox-2.14.18/ext/ox/parse.c:528:26
    #2 0xffff90ba5894 in ox_parse /usr/local/bundle/gems/ox-2.14.18/ext/ox/parse.c:207:13
    #3 0xffff90b9cd28 in to_gen /usr/local/bundle/gems/ox-2.14.18/ext/ox/ox.c:724:11
    #4 0xffffb0926a38 in vm_call_cfunc_with_frame_ /usr/src/ruby/vm_insnhelper.c:3490:12
    #5 0xffffb0926a38 in vm_call_cfunc_with_frame /usr/src/ruby/vm_insnhelper.c:3518:12
    #6 0xffffb0926a38 in vm_call_cfunc_other /usr/src/ruby/vm_insnhelper.c:3544:16
    #7 0xffffb09377ac in vm_sendish /usr/src/ruby/vm_insnhelper.c:5581:15
    #8 0xffffb09377ac in vm_exec_core /usr/src/ruby/insns.def:834:11
    #9 0xffffb093da28 in rb_vm_exec /usr/src/ruby/vm.c:2486:22
    #10 0xffffb083a04c in rb_proc_call_kw /usr/src/ruby/proc.c:978:12
    #11 0xffff90d6a1f0 in proc_caller /usr/local/bundle/gems/ruzzy-0.6.0/ext/cruzzy/cruzzy.c:90:20
    #12 0xffffb0c9a32c in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/usr/local/bundle/gems/ruzzy-0.6.0/ext/cruzzy/asan_with_fuzzer.so+0x5a32c) (BuildId: 188a77e6054cdc90dfa3aef17adf0640f0bc7de1)
    #13 0xffffb0c856e8 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) (/usr/local/bundle/gems/ruzzy-0.6.0/ext/cruzzy/asan_with_fuzzer.so+0x456e8) (BuildId: 188a77e6054cdc90dfa3aef17adf0640f0bc7de1)
    #14 0xffffb0c8ab60 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/usr/local/bundle/gems/ruzzy-0.6.0/ext/cruzzy/asan_with_fuzzer.so+0x4ab60) (BuildId: 188a77e6054cdc90dfa3aef17adf0640f0bc7de1)
    #15 0xffff90d69f20 in c_fuzz /usr/local/bundle/gems/ruzzy-0.6.0/ext/cruzzy/cruzzy.c:147:18
    #16 0xffffb0926a38 in vm_call_cfunc_with_frame_ /usr/src/ruby/vm_insnhelper.c:3490:12
    #17 0xffffb0926a38 in vm_call_cfunc_with_frame /usr/src/ruby/vm_insnhelper.c:3518:12
    #18 0xffffb0926a38 in vm_call_cfunc_other /usr/src/ruby/vm_insnhelper.c:3544:16
    #19 0xffffb09377ac in vm_sendish /usr/src/ruby/vm_insnhelper.c:5581:15
    #20 0xffffb09377ac in vm_exec_core /usr/src/ruby/insns.def:834:11
    #21 0xffffb093dc30 in vm_exec_loop /usr/src/ruby/vm.c:2513:22
    #22 0xffffb093dc30 in rb_vm_exec /usr/src/ruby/vm.c:2492:18
    #23 0xffffb075f338 in rb_ec_exec_node /usr/src/ruby/eval.c:287:9
    #24 0xffffb0763078 in ruby_run_node /usr/src/ruby/eval.c:328:30
    #25 0xaaaabef90b28 in rb_main /usr/src/ruby/./main.c:39:12
    #26 0xaaaabef90b28 in main /usr/src/ruby/./main.c:58:12
    #27 0xffffb02f777c  (/lib/aarch64-linux-gnu/libc.so.6+0x2777c) (BuildId: 09928b270aa19314161b21f565d1a9732c2c5332)
    #28 0xffffb02f7854 in __libc_start_main (/lib/aarch64-linux-gnu/libc.so.6+0x27854) (BuildId: 09928b270aa19314161b21f565d1a9732c2c5332)
    #29 0xaaaabef90bac in _start (/usr/local/bin/ruby+0xbac) (BuildId: f308c93dbc39784787da50772128d0d5a597b346)

Address 0xffffae10003f is located in stack of thread T0 at offset 63 in frame
    #0 0xffff90baf088 in collapse_special /usr/local/bundle/gems/ox-2.14.18/ext/ox/parse.c:1063

  This frame has 2 object(s):
    [32, 40) 'u' (line 1074)
    [64, 80) 'key' (line 1135) <== Memory access at offset 63 underflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow /usr/local/bundle/gems/ox-2.14.18/ext/ox/parse.c:1155:24 in collapse_special
Shadow bytes around the buggy address:
  0xffffae0ffd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0xffffae0ffe00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0xffffae0ffe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0xffffae0fff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0xffffae0fff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0xffffae100000: f1 f1 f1 f1 f8 f2 f2[f2]00 00 f3 f3 00 00 00 00
  0xffffae100080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0xffffae100100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0xffffae100180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0xffffae100200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0xffffae100280: 00 00 00 00 00 00 00 00 00 00 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
  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
==146==ABORTING

Reproducer: crash-765a10b8075fbb3078b1c84f6449ce179280f013.txt

dynamic-stack-buffer-overflow in _ox_err_set_with_location
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 4048373087
INFO: Loaded 1 modules   (2917 inline 8-bit counters): 2917 [0xffff9bce58e0, 0xffff9bce6445), 
INFO: Loaded 1 PC tables (2917 PCs): 2917 [0xffff9bce6448,0xffff9bcf1a98), 
bin/test_harness_ox.rb: Running 1 inputs 1 time(s) each.
Running: crashes/crash-845de250117ca481b34ec7ade578f7065185ea89.txt
=================================================================
==152==ERROR: AddressSanitizer: dynamic-stack-buffer-overflow on address 0xfffff93756e2 at pc 0xffff9bc616d8 bp 0xfffff9373190 sp 0xfffff9373188
READ of size 1 at 0xfffff93756e2 thread T0
    #0 0xffff9bc616d4 in _ox_err_set_with_location /usr/local/bundle/gems/ox-2.14.18/ext/ox/err.c:37:37
    #1 0xffff9bc90f24 in read_text /usr/local/bundle/gems/ox-2.14.18/ext/ox/parse.c:712:20
    #2 0xffff9bc8ba80 in read_element /usr/local/bundle/gems/ox-2.14.18/ext/ox/parse.c:676:17
    #3 0xffff9bc8b680 in read_element /usr/local/bundle/gems/ox-2.14.18/ext/ox/parse.c:656:38
    #4 0xffff9bc85894 in ox_parse /usr/local/bundle/gems/ox-2.14.18/ext/ox/parse.c:207:13
    #5 0xffff9bc7cd28 in to_gen /usr/local/bundle/gems/ox-2.14.18/ext/ox/ox.c:724:11
    #6 0xffffbba16a38 in vm_call_cfunc_with_frame_ /usr/src/ruby/vm_insnhelper.c:3490:12
    #7 0xffffbba16a38 in vm_call_cfunc_with_frame /usr/src/ruby/vm_insnhelper.c:3518:12
    #8 0xffffbba16a38 in vm_call_cfunc_other /usr/src/ruby/vm_insnhelper.c:3544:16
    #9 0xffffbba277ac in vm_sendish /usr/src/ruby/vm_insnhelper.c:5581:15
    #10 0xffffbba277ac in vm_exec_core /usr/src/ruby/insns.def:834:11
    #11 0xffffbba2da28 in rb_vm_exec /usr/src/ruby/vm.c:2486:22
    #12 0xffffbb92a04c in rb_proc_call_kw /usr/src/ruby/proc.c:978:12
    #13 0xffff9be3a1f0 in proc_caller /usr/local/bundle/gems/ruzzy-0.6.0/ext/cruzzy/cruzzy.c:90:20
    #14 0xffffbbd8a32c in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/usr/local/bundle/gems/ruzzy-0.6.0/ext/cruzzy/asan_with_fuzzer.so+0x5a32c) (BuildId: 188a77e6054cdc90dfa3aef17adf0640f0bc7de1)
    #15 0xffffbbd756e8 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) (/usr/local/bundle/gems/ruzzy-0.6.0/ext/cruzzy/asan_with_fuzzer.so+0x456e8) (BuildId: 188a77e6054cdc90dfa3aef17adf0640f0bc7de1)
    #16 0xffffbbd7ab60 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/usr/local/bundle/gems/ruzzy-0.6.0/ext/cruzzy/asan_with_fuzzer.so+0x4ab60) (BuildId: 188a77e6054cdc90dfa3aef17adf0640f0bc7de1)
    #17 0xffff9be39f20 in c_fuzz /usr/local/bundle/gems/ruzzy-0.6.0/ext/cruzzy/cruzzy.c:147:18
    #18 0xffffbba16a38 in vm_call_cfunc_with_frame_ /usr/src/ruby/vm_insnhelper.c:3490:12
    #19 0xffffbba16a38 in vm_call_cfunc_with_frame /usr/src/ruby/vm_insnhelper.c:3518:12
    #20 0xffffbba16a38 in vm_call_cfunc_other /usr/src/ruby/vm_insnhelper.c:3544:16
    #21 0xffffbba277ac in vm_sendish /usr/src/ruby/vm_insnhelper.c:5581:15
    #22 0xffffbba277ac in vm_exec_core /usr/src/ruby/insns.def:834:11
    #23 0xffffbba2dc30 in vm_exec_loop /usr/src/ruby/vm.c:2513:22
    #24 0xffffbba2dc30 in rb_vm_exec /usr/src/ruby/vm.c:2492:18
    #25 0xffffbb84f338 in rb_ec_exec_node /usr/src/ruby/eval.c:287:9
    #26 0xffffbb853078 in ruby_run_node /usr/src/ruby/eval.c:328:30
    #27 0xaaaadc320b28 in rb_main /usr/src/ruby/./main.c:39:12
    #28 0xaaaadc320b28 in main /usr/src/ruby/./main.c:58:12
    #29 0xffffbb3e777c  (/lib/aarch64-linux-gnu/libc.so.6+0x2777c) (BuildId: 09928b270aa19314161b21f565d1a9732c2c5332)
    #30 0xffffbb3e7854 in __libc_start_main (/lib/aarch64-linux-gnu/libc.so.6+0x27854) (BuildId: 09928b270aa19314161b21f565d1a9732c2c5332)
    #31 0xaaaadc320bac in _start (/usr/local/bin/ruby+0xbac) (BuildId: f308c93dbc39784787da50772128d0d5a597b346)

Address 0xfffff93756e2 is located in stack of thread T0
SUMMARY: AddressSanitizer: dynamic-stack-buffer-overflow /usr/local/bundle/gems/ox-2.14.18/ext/ox/err.c:37:37 in _ox_err_set_with_location
Shadow bytes around the buggy address:
  0xfffff9375400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0xfffff9375480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0xfffff9375500: 00 00 00 00 00 00 00 00 00 00 00 00 ca ca ca ca
  0xfffff9375580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0xfffff9375600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0xfffff9375680: 00 00 00 00 00 00 00 00 00 00 00 00[02]cb cb cb
  0xfffff9375700: cb cb cb cb 00 00 00 00 00 00 00 00 00 00 00 00
  0xfffff9375780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0xfffff9375800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0xfffff9375880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0xfffff9375900: 00 00 00 00 00 00 00 00 00 00 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
  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
==152==ABORTING

Reproducer: crash-845de250117ca481b34ec7ade578f7065185ea89.txt

dynamic-stack-buffer-overflow in to_gen
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 266205069
INFO: Loaded 1 modules   (2917 inline 8-bit counters): 2917 [0xffff95cb58e0, 0xffff95cb6445), 
INFO: Loaded 1 PC tables (2917 PCs): 2917 [0xffff95cb6448,0xffff95cc1a98), 
bin/test_harness_ox.rb: Running 1 inputs 1 time(s) each.
Running: crashes/crash-fa1ec0ff629bfbe275c6243bc63d7ee3e88c09c1.txt
=================================================================
==158==ERROR: AddressSanitizer: dynamic-stack-buffer-overflow on address 0xfffff510c860 at pc 0xffffb5e0c984 bp 0xfffff510c7e0 sp 0xfffff510bfd0
WRITE of size 207 at 0xfffff510c860 thread T0
    #0 0xffffb5e0c980 in __asan_memcpy (/usr/local/bundle/gems/ruzzy-0.6.0/ext/cruzzy/asan_with_fuzzer.so+0x10c980) (BuildId: 188a77e6054cdc90dfa3aef17adf0640f0bc7de1)
    #1 0xffff95c4ccc8 in to_gen /usr/local/bundle/gems/ox-2.14.18/ext/ox/ox.c:723:5
    #2 0xffffb59e6758 in vm_call_cfunc_with_frame_ /usr/src/ruby/vm_insnhelper.c:3490:12
    #3 0xffffb59e6758 in vm_call_cfunc_with_frame /usr/src/ruby/vm_insnhelper.c:3518:12
    #4 0xffffb59f77ac in vm_sendish /usr/src/ruby/vm_insnhelper.c:5581:15
    #5 0xffffb59f77ac in vm_exec_core /usr/src/ruby/insns.def:834:11
    #6 0xffffb59fda28 in rb_vm_exec /usr/src/ruby/vm.c:2486:22
    #7 0xffffb58fa04c in rb_proc_call_kw /usr/src/ruby/proc.c:978:12
    #8 0xffff95e1a1f0 in proc_caller /usr/local/bundle/gems/ruzzy-0.6.0/ext/cruzzy/cruzzy.c:90:20
    #9 0xffffb5d5a32c in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/usr/local/bundle/gems/ruzzy-0.6.0/ext/cruzzy/asan_with_fuzzer.so+0x5a32c) (BuildId: 188a77e6054cdc90dfa3aef17adf0640f0bc7de1)
    #10 0xffffb5d5b4d4 in fuzzer::Fuzzer::TryDetectingAMemoryLeak(unsigned char const*, unsigned long, bool) (/usr/local/bundle/gems/ruzzy-0.6.0/ext/cruzzy/asan_with_fuzzer.so+0x5b4d4) (BuildId: 188a77e6054cdc90dfa3aef17adf0640f0bc7de1)
    #11 0xffffb5d45738 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) (/usr/local/bundle/gems/ruzzy-0.6.0/ext/cruzzy/asan_with_fuzzer.so+0x45738) (BuildId: 188a77e6054cdc90dfa3aef17adf0640f0bc7de1)
    #12 0xffffb5d4ab60 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/usr/local/bundle/gems/ruzzy-0.6.0/ext/cruzzy/asan_with_fuzzer.so+0x4ab60) (BuildId: 188a77e6054cdc90dfa3aef17adf0640f0bc7de1)
    #13 0xffff95e19f20 in c_fuzz /usr/local/bundle/gems/ruzzy-0.6.0/ext/cruzzy/cruzzy.c:147:18
    #14 0xffffb59e6a38 in vm_call_cfunc_with_frame_ /usr/src/ruby/vm_insnhelper.c:3490:12
    #15 0xffffb59e6a38 in vm_call_cfunc_with_frame /usr/src/ruby/vm_insnhelper.c:3518:12
    #16 0xffffb59e6a38 in vm_call_cfunc_other /usr/src/ruby/vm_insnhelper.c:3544:16
    #17 0xffffb59f77ac in vm_sendish /usr/src/ruby/vm_insnhelper.c:5581:15
    #18 0xffffb59f77ac in vm_exec_core /usr/src/ruby/insns.def:834:11
    #19 0xffffb59fdc30 in vm_exec_loop /usr/src/ruby/vm.c:2513:22
    #20 0xffffb59fdc30 in rb_vm_exec /usr/src/ruby/vm.c:2492:18
    #21 0xffffb581f338 in rb_ec_exec_node /usr/src/ruby/eval.c:287:9
    #22 0xffffb5823078 in ruby_run_node /usr/src/ruby/eval.c:328:30
    #23 0xaaaac8d00b28 in rb_main /usr/src/ruby/./main.c:39:12
    #24 0xaaaac8d00b28 in main /usr/src/ruby/./main.c:58:12
    #25 0xffffb53b777c  (/lib/aarch64-linux-gnu/libc.so.6+0x2777c) (BuildId: 09928b270aa19314161b21f565d1a9732c2c5332)
    #26 0xffffb53b7854 in __libc_start_main (/lib/aarch64-linux-gnu/libc.so.6+0x27854) (BuildId: 09928b270aa19314161b21f565d1a9732c2c5332)
    #27 0xaaaac8d00bac in _start (/usr/local/bin/ruby+0xbac) (BuildId: f308c93dbc39784787da50772128d0d5a597b346)

Address 0xfffff510c860 is located in stack of thread T0
SUMMARY: AddressSanitizer: dynamic-stack-buffer-overflow (/usr/local/bundle/gems/ruzzy-0.6.0/ext/cruzzy/asan_with_fuzzer.so+0x10c980) (BuildId: 188a77e6054cdc90dfa3aef17adf0640f0bc7de1) in __asan_memcpy
Shadow bytes around the buggy address:
  0xfffff510c580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0xfffff510c600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0xfffff510c680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0xfffff510c700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0xfffff510c780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0xfffff510c800: 00 00 00 00 ca ca ca ca 00 00 00 00[ca]ca ca ca
  0xfffff510c880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0xfffff510c900: 00 07 cb cb cb cb cb cb 00 07 cb cb cb cb cb cb
  0xfffff510c980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0xfffff510ca00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0xfffff510ca80: 00 00 00 00 00 00 00 00 00 00 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
  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
==158==ABORTING

Reproducer: crash-fa1ec0ff629bfbe275c6243bc63d7ee3e88c09c1.txt


Next, Ox.sax_parse. I used the following harness to fuzz it:

require 'ox'

class MyHandler < Ox::Sax

  # Called for the opening of an element
  def start_element(name)

  end

  # Called for the text content of an element
  def text(value)

  end

  # Called for the closing of an element
  def end_element(name)

  end
end

test_one_input = lambda do |data|
  begin
    handler = MyHandler.new
    Ox.sax_parse(handler, StringIO.new(data))
  rescue Ox::ParseError, EncodingError
    # pass
  end
  return 0
end

Fuzzing produced one violation:

stack-buffer-underflow in ox_sax_buf_read
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 2842798979
INFO: Loaded 1 modules   (2917 inline 8-bit counters): 2917 [0xffff8b8e58e0, 0xffff8b8e6445), 
INFO: Loaded 1 PC tables (2917 PCs): 2917 [0xffff8b8e6448,0xffff8b8f1a98), 
bin/test_harness_ox_sax.rb: Running 1 inputs 1 time(s) each.
Running: crashes/crash-08f111b2df6d628235c5e72ecfe464ae1913892d.txt
=================================================================
==170==ERROR: AddressSanitizer: stack-buffer-underflow on address 0xffffa940001f at pc 0xffffaba2cec8 bp 0xfffffd353840 sp 0xfffffd353030
READ of size 9 at 0xffffa940001f thread T0
    #0 0xffffaba2cec4 in __asan_memmove (/usr/local/bundle/gems/ruzzy-0.6.0/ext/cruzzy/asan_with_fuzzer.so+0x10cec4) (BuildId: 188a77e6054cdc90dfa3aef17adf0640f0bc7de1)
    #1 0xffff8b8b0750 in ox_sax_buf_read /usr/local/bundle/gems/ox-2.14.18/ext/ox/sax_buf.c:102:13
    #2 0xffff8b898f40 in buf_get /usr/local/bundle/gems/ox-2.14.18/ext/ox/./sax_buf.h:52:18
    #3 0xffff8b8a0b78 in read_text /usr/local/bundle/gems/ox-2.14.18/ext/ox/sax.c:1041:24
    #4 0xffff8b898414 in parse /usr/local/bundle/gems/ox-2.14.18/ext/ox/sax.c:460:17
    #5 0xffff8b895170 in protect_parse /usr/local/bundle/gems/ox-2.14.18/ext/ox/sax.c:66:5
    #6 0xffffab4411d4 in rb_protect /usr/src/ruby/eval.c:983:9
    #7 0xffff8b8937c4 in ox_sax_parse /usr/local/bundle/gems/ox-2.14.18/ext/ox/sax.c:91:5
    #8 0xffff8b87dce4 in sax_parse /usr/local/bundle/gems/ox-2.14.18/ext/ox/ox.c:1084:5
    #9 0xffffab606a38 in vm_call_cfunc_with_frame_ /usr/src/ruby/vm_insnhelper.c:3490:12
    #10 0xffffab606a38 in vm_call_cfunc_with_frame /usr/src/ruby/vm_insnhelper.c:3518:12
    #11 0xffffab606a38 in vm_call_cfunc_other /usr/src/ruby/vm_insnhelper.c:3544:16
    #12 0xffffab6177ac in vm_sendish /usr/src/ruby/vm_insnhelper.c:5581:15
    #13 0xffffab6177ac in vm_exec_core /usr/src/ruby/insns.def:834:11
    #14 0xffffab61da28 in rb_vm_exec /usr/src/ruby/vm.c:2486:22
    #15 0xffffab51a04c in rb_proc_call_kw /usr/src/ruby/proc.c:978:12
    #16 0xffff8ba3a1f0 in proc_caller /usr/local/bundle/gems/ruzzy-0.6.0/ext/cruzzy/cruzzy.c:90:20
    #17 0xffffab97a32c in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/usr/local/bundle/gems/ruzzy-0.6.0/ext/cruzzy/asan_with_fuzzer.so+0x5a32c) (BuildId: 188a77e6054cdc90dfa3aef17adf0640f0bc7de1)
    #18 0xffffab9656e8 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) (/usr/local/bundle/gems/ruzzy-0.6.0/ext/cruzzy/asan_with_fuzzer.so+0x456e8) (BuildId: 188a77e6054cdc90dfa3aef17adf0640f0bc7de1)
    #19 0xffffab96ab60 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/usr/local/bundle/gems/ruzzy-0.6.0/ext/cruzzy/asan_with_fuzzer.so+0x4ab60) (BuildId: 188a77e6054cdc90dfa3aef17adf0640f0bc7de1)
    #20 0xffff8ba39f20 in c_fuzz /usr/local/bundle/gems/ruzzy-0.6.0/ext/cruzzy/cruzzy.c:147:18
    #21 0xffffab606a38 in vm_call_cfunc_with_frame_ /usr/src/ruby/vm_insnhelper.c:3490:12
    #22 0xffffab606a38 in vm_call_cfunc_with_frame /usr/src/ruby/vm_insnhelper.c:3518:12
    #23 0xffffab606a38 in vm_call_cfunc_other /usr/src/ruby/vm_insnhelper.c:3544:16
    #24 0xffffab6177ac in vm_sendish /usr/src/ruby/vm_insnhelper.c:5581:15
    #25 0xffffab6177ac in vm_exec_core /usr/src/ruby/insns.def:834:11
    #26 0xffffab61dc30 in vm_exec_loop /usr/src/ruby/vm.c:2513:22
    #27 0xffffab61dc30 in rb_vm_exec /usr/src/ruby/vm.c:2492:18
    #28 0xffffab43f338 in rb_ec_exec_node /usr/src/ruby/eval.c:287:9
    #29 0xffffab443078 in ruby_run_node /usr/src/ruby/eval.c:328:30
    #30 0xaaaac7d90b28 in rb_main /usr/src/ruby/./main.c:39:12
    #31 0xaaaac7d90b28 in main /usr/src/ruby/./main.c:58:12
    #32 0xffffaafd777c  (/lib/aarch64-linux-gnu/libc.so.6+0x2777c) (BuildId: 09928b270aa19314161b21f565d1a9732c2c5332)
    #33 0xffffaafd7854 in __libc_start_main (/lib/aarch64-linux-gnu/libc.so.6+0x27854) (BuildId: 09928b270aa19314161b21f565d1a9732c2c5332)
    #34 0xaaaac7d90bac in _start (/usr/local/bin/ruby+0xbac) (BuildId: f308c93dbc39784787da50772128d0d5a597b346)

Address 0xffffa940001f is located in stack of thread T0 at offset 31 in frame
    #0 0xffff8b8935b4 in ox_sax_parse /usr/local/bundle/gems/ox-2.14.18/ext/ox/sax.c:83

  This frame has 2 object(s):
    [32, 7568) 'dr' (line 87) <== Memory access at offset 31 partially underflows this variable
    [7824, 7828) 'line' (line 88)
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-underflow (/usr/local/bundle/gems/ruzzy-0.6.0/ext/cruzzy/asan_with_fuzzer.so+0x10cec4) (BuildId: 188a77e6054cdc90dfa3aef17adf0640f0bc7de1) in __asan_memmove
Shadow bytes around the buggy address:
  0xffffa93ffd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0xffffa93ffe00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0xffffa93ffe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0xffffa93fff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0xffffa93fff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0xffffa9400000: f1 f1 f1[f1]00 00 00 00 00 00 00 00 00 00 00 00
  0xffffa9400080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0xffffa9400100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0xffffa9400180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0xffffa9400200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0xffffa9400280: 00 00 00 00 00 00 00 00 00 00 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
  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
==170==ABORTING

Reproducer: crash-08f111b2df6d628235c5e72ecfe464ae1913892d.txt


Related issues: #195.

@ohler55
Copy link
Owner

ohler55 commented Mar 28, 2024

When I get a chance I'll take a look. Any more information you can get would give me a head start.

@ohler55
Copy link
Owner

ohler55 commented Mar 31, 2024

I tried to get AddressSanitizer setup in the makefile but I was not able to generate a bundle or .so file that could be used for testing. I also note that AddressSanitizer only works with macOS 10.x. I'm running v14.4 and it is not possible for me to revert to an OS that is 15 years old. Of course without AddressSanitizer Ox raises an error as it is supposed to. If you can give me some idea how to recreate the issue on a modern OS I'll see if I can recreate the issue and get it fixed.

@AdvenamTacet
Copy link

@ohler55 you should be able to reproduce the error on Linux. A virtual machine or Docker would probably work.
You can read how to fuzz with AddressSanitizer in the post introducing Ruzzy. The compilation process should remain the same as in the section Compiling Ruby C extensions with libFuzzer.

Additionally, you have the option to fuzz the project in order to reproduce the error.

Here is an example of a harness.:

# frozen_string_literal: true

require 'ruzzy'
require 'ox'

test_one_input = lambda do |data|
  begin
    Ox.parse(data)
  rescue Ox::ParseError, EncodingError
    # pass
  end
  return 0
end

Ruzzy.fuzz(test_one_input)

Works on Linux for me.

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

3 participants