-
Notifications
You must be signed in to change notification settings - Fork 821
Closed
Description
Description: Pointer underflow when start is negative: __fill_exec does not validate start<0, so ptr = ARY_PTR(ary)+start underflows, and ptr[i] writes before the array bounds (lines 945–947).
Trigger conditions: Call Array#__fill_exec with a negative start and positive length in Ruby code passed to mrb_load_string.
Harness name: mruby_fuzzer
Crashing input:
a = Array.new(20,0)
a.__fill_exec(-30,10,nil)
Crash output:
+ FUZZER=mruby_fuzzer
+ shift
+ '[' '!' -v TESTCASE ']'
+ TESTCASE=/testcase
+ '[' '!' -f /testcase ']'
+ export RUN_FUZZER_MODE=interactive
+ RUN_FUZZER_MODE=interactive
+ export FUZZING_ENGINE=libfuzzer
+ FUZZING_ENGINE=libfuzzer
+ export SKIP_SEED_CORPUS=1
+ SKIP_SEED_CORPUS=1
+ run_fuzzer mruby_fuzzer /testcase
sysctl: setting key "vm.mmap_rnd_bits", ignoring: Read-only file system
Dictionary: 102 entries
/out/mruby_fuzzer: Running 1 inputs 1 time(s) each.
Running: /testcase
AddressSanitizer:DEADLYSIGNAL
=================================================================
==43==ERROR: AddressSanitizer: SEGV on unknown address 0x510fffffff50 (pc 0x7f377e9bac1a bp 0x7fff8f12ceb0 sp 0x7fff8f12c668 T0)
==43==The signal is caused by a WRITE memory access.
SCARINESS: 30 (wild-addr-write)
Stack Frame #0 /build/glibc-B3wQXB/glibc-2.31/string/../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:314
Stack Frame #1 in __asan_memcpy /src/llvm-project/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:63:3
Stack Frame #2 in ary_fill_exec array.c
Stack Frame #3 in mrb_vm_exec (/out/mruby_fuzzer+0x2e9297)
Stack Frame #4 in mrb_vm_run (/out/mruby_fuzzer+0x2d18e2)
Stack Frame #5 in mrb_top_run (/out/mruby_fuzzer+0x32d589)
Stack Frame #6 in mrb_load_exec (/out/mruby_fuzzer+0x3c61c5)
Stack Frame #7 in mrb_load_nstring_cxt (/out/mruby_fuzzer+0x3c712c)
Stack Frame #8 in mrb_load_string_cxt (/out/mruby_fuzzer+0x3c7260)
Stack Frame #9 in mrb_load_string (/out/mruby_fuzzer+0x3c72d8)
Stack Frame #10 in LLVMFuzzerTestOneInput (/out/mruby_fuzzer+0x2a7c5b)
Stack Frame #11 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:614:13
Stack Frame #12 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:327:6
Stack Frame #13 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:862:9
Stack Frame #14 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
Stack Frame #15 in __libc_start_main /build/glibc-B3wQXB/glibc-2.31/csu/../csu/libc-start.c:308:16
Stack Frame #16 in _start (/out/mruby_fuzzer+0x13fb0d)
DEDUP_TOKEN: __asan_memcpy--ary_fill_exec--mrb_vm_exec--mrb_vm_run
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /build/glibc-B3wQXB/glibc-2.31/string/../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:314
==43==ABORTING
/out/mruby_fuzzer -rss_limit_mb=2560 -timeout=25 /testcase -dict=mruby.dict -only_ascii=1 < /dev/null
Patch:
--- a/mrbgems/mruby-array-ext/src/array.c
+++ b/mrbgems/mruby-array-ext/src/array.c
@@ -929,6 +929,13 @@
struct RArray *ary = mrb_ary_ptr(self);
mrb_int ary_len = ARY_LEN(ary);
+ /* Normalize negative start index */
+ if (start < 0) start += ary_len;
+ if (start < 0) start = 0;
+
+ /* Ensure length is non-negative */
+ if (length < 0) length = 0;
+
/* Extend array if necessary */
if (start + length > ary_len) {
mrb_ary_resize(mrb, self, start + length);
Metadata
Metadata
Assignees
Labels
No labels