From: "mdalessio (Mike Dalessio)" Date: 2021-09-07T15:49:28+00:00 Subject: [ruby-core:105168] [Ruby master Bug#18138] Array#slice! invalid memory access Issue #18138 has been updated by mdalessio (Mike Dalessio). A colleague asked if this bug should have a CVE number, given that any application that might take offsets as untrusted input could be tricked into: - accessing unrelated memory - CWE-125 (https://cwe.mitre.org/data/definitions/125.html) - crashing (Denial of Service) - CWE-248 (https://cwe.mitre.org/data/definitions/248.html) I'm not a security professional, but it does seem to me as though a CVE should be discussed. ---------------------------------------- Bug #18138: Array#slice! invalid memory access https://bugs.ruby-lang.org/issues/18138#change-93573 * Author: mdalessio (Mike Dalessio) * Status: Closed * Priority: Normal * ruby -v: ruby 3.1.0dev (2021-08-28T14:40:37Z master 808ce96494) [x86_64-linux] * Backport: 2.6: DONTNEED, 2.7: DONTNEED, 3.0: DONE ---------------------------------------- As of 4f24255, the array.c functions rb_ary_slice_bang / ary_slice_bang_by_rb_ary_splice allow a length to be passed to rb_ary_new4 that is too long and which leads to an invalid memory access. This bug is present in Ruby v3_0_0, v3_0_1, and v3_0_2. ## Reproduction This ruby snippet will reproduce valgrind memory warnings: ``` ruby (1..5000).to_a.slice!(-2, 5000) ``` The valgrind memory warnings on `master` look like: ``` text ==228628== Invalid read of size 8 ==228628== at 0x48428C0: memmove (vg_replace_strmem.c:1271) ==228628== by 0x356542: ary_memcpy (array.c:316) ==228628== by 0x356542: rb_ary_tmp_new_from_values (array.c:785) ==228628== by 0x356542: rb_ary_new_from_values (array.c:795) ==228628== by 0x356542: ary_slice_bang_by_rb_ary_splice (array.c:4106) ==228628== by 0x35E1DB: rb_ary_slice_bang (array.c:4186) ``` ## Fix The fix I'm suggesting is in pull request https://github.com/ruby/ruby/pull/4787 Saving you a click: ``` text diff --git a/array.c b/array.c index bd323cd..edac216 100644 --- a/array.c +++ b/array.c @@ -4096,7 +4096,7 @@ ary_slice_bang_by_rb_ary_splice(VALUE ary, long pos, long len) else if (orig_len < pos) { return Qnil; } - else if (orig_len < pos + len) { + if (orig_len < pos + len) { len = orig_len - pos; } if (len == 0) { ``` -- https://bugs.ruby-lang.org/ Unsubscribe: