merge revision(s) 56938: [Backport #12988]

Stop reading past the end of `ivptr` array

	If you have code like this:

	```ruby
	class A
  def initialize
    @a = nil
    @b = nil
    @c = nil
    @d = nil
    @e = nil
  end
	end

	x = A.new
	y = x.clone
	100.times { |z| x.instance_variable_set(:"@foo#{z}", nil) }
	puts y.inspect
	```

	`x` and `y` will share `iv_index_tbl` hashes.  However, the size of the
	hash will grow larger than the number if entries in `ivptr` in `y`.
	Before this commit, `rb_ivar_count` would use the size of the hash to
	determine how far to read in to the array, but this means that it could
	read past the end of the array and cause the program to segv

	[ruby-core:78403]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_2@57214 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
usa 2016-12-27 10:35:50 +00:00
parent 244885b637
commit 3aed194ac3
3 changed files with 7 additions and 2 deletions

View file

@ -1,3 +1,8 @@
Tue Dec 27 19:34:47 2016 Aaron Patterson <tenderlove@ruby-lang.org>
* variable.c (rb_ivar_count): stop reading past the end of ivptr array.
[Bug #12988]
Tue Dec 27 19:32:03 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
* thread.c (rb_thread_s_abort_exc, rb_thread_s_abort_exc_set):

View file

@ -1322,7 +1322,7 @@ rb_ivar_count(VALUE obj)
switch (BUILTIN_TYPE(obj)) {
case T_OBJECT:
if ((tbl = ROBJECT_IV_INDEX_TBL(obj)) != 0) {
st_index_t i, count, num = tbl->num_entries;
st_index_t i, count, num = ROBJECT_NUMIV(obj);
const VALUE *const ivptr = ROBJECT_IVPTR(obj);
for (i = count = 0; i < num; ++i) {
if (ivptr[i] != Qundef) {

View file

@ -1,6 +1,6 @@
#define RUBY_VERSION "2.2.7"
#define RUBY_RELEASE_DATE "2016-12-27"
#define RUBY_PATCHLEVEL 404
#define RUBY_PATCHLEVEL 405
#define RUBY_RELEASE_YEAR 2016
#define RUBY_RELEASE_MONTH 12