[前][次][番号順一覧][スレッド一覧]

ruby-changes:44180

From: rhe <ko1@a...>
Date: Mon, 26 Sep 2016 16:25:00 +0900 (JST)
Subject: [ruby-changes:44180] rhe:r56253 (trunk): stringio.c: fix signed integer overflow

rhe	2016-09-26 16:24:55 +0900 (Mon, 26 Sep 2016)

  New Revision: 56253

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=56253

  Log:
    stringio.c: fix signed integer overflow
    
    * ext/stringio/stringio.c (strio_seek): Avoid signed integer overflow.
      It's not harmful in practice here, but is still undefined behavior.
    
    * ext/stringio/stringio.c (strio_extend): Check that the new length does
      not exceed LONG_MAX. This fixes the invalid write on the overflow.
    
    * test/stringio/test_stringio.rb (test_write_integer_overflow): Add a
      test case for the above fix in strio_extend().

  Modified files:
    trunk/ChangeLog
    trunk/ext/stringio/stringio.c
    trunk/test/stringio/test_stringio.rb
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 56252)
+++ ChangeLog	(revision 56253)
@@ -1,3 +1,14 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Mon Sep 26 16:23:49 2016  Kazuki Yamaguchi  <k@r...>
+
+	* ext/stringio/stringio.c (strio_seek): Avoid signed integer overflow.
+	  It's not harmful in practice here, but is still undefined behavior.
+
+	* ext/stringio/stringio.c (strio_extend): Check that the new length does
+	  not exceed LONG_MAX. This fixes the invalid write on the overflow.
+
+	* test/stringio/test_stringio.rb (test_write_integer_overflow): Add a
+	  test case for the above fix in strio_extend().
+
 Mon Sep 26 15:43:34 2016  Kazuki Yamaguchi  <k@r...>
 
 	* eval_intern.h (TH_PUSH_TAG): Initialize struct rb_vm_tag::tag with
Index: test/stringio/test_stringio.rb
===================================================================
--- test/stringio/test_stringio.rb	(revision 56252)
+++ test/stringio/test_stringio.rb	(revision 56253)
@@ -160,6 +160,15 @@ class TestStringIO < Test::Unit::TestCas https://github.com/ruby/ruby/blob/trunk/test/stringio/test_stringio.rb#L160
     assert_equal(Encoding::UTF_8, s.encoding, "honor the original encoding over ASCII-8BIT")
   end
 
+  def test_write_integer_overflow
+    long_max = (1 << (RbConfig::SIZEOF["long"] * 8 - 1)) - 1
+    f = StringIO.new
+    f.pos = long_max
+    assert_raise(ArgumentError) {
+      f.write("pos + len overflows")
+    }
+  end
+
   def test_set_encoding
     bug10285 = '[ruby-core:65240] [Bug #10285]'
     f = StringIO.new()
Index: ext/stringio/stringio.c
===================================================================
--- ext/stringio/stringio.c	(revision 56252)
+++ ext/stringio/stringio.c	(revision 56253)
@@ -610,29 +610,30 @@ strio_seek(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/ext/stringio/stringio.c#L610
 {
     VALUE whence;
     struct StringIO *ptr = StringIO(self);
-    long offset;
+    long amount, offset;
 
     rb_scan_args(argc, argv, "11", NULL, &whence);
-    offset = NUM2LONG(argv[0]);
+    amount = NUM2LONG(argv[0]);
     if (CLOSED(self)) {
 	rb_raise(rb_eIOError, "closed stream");
     }
     switch (NIL_P(whence) ? 0 : NUM2LONG(whence)) {
       case 0:
+	offset = 0;
 	break;
       case 1:
-	offset += ptr->pos;
+	offset = ptr->pos;
 	break;
       case 2:
-	offset += RSTRING_LEN(ptr->string);
+	offset = RSTRING_LEN(ptr->string);
 	break;
       default:
 	error_inval("invalid whence");
     }
-    if (offset < 0) {
+    if (amount > LONG_MAX - offset || amount + offset < 0) {
 	error_inval(0);
     }
-    ptr->pos = offset;
+    ptr->pos = amount + offset;
     return INT2FIX(0);
 }
 
@@ -734,6 +735,9 @@ strio_extend(struct StringIO *ptr, long https://github.com/ruby/ruby/blob/trunk/ext/stringio/stringio.c#L735
 {
     long olen;
 
+    if (len > LONG_MAX - pos)
+	rb_raise(rb_eArgError, "string size too big");
+
     check_modifiable(ptr);
     olen = RSTRING_LEN(ptr->string);
     if (pos + len > olen) {

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]