Forum: Ruby-core Re: Ruby 1.9.0/1.8.7/1.8.6/1.8.5 new releases (Security Fix)

4feed660d3728526797edeb4f0467384?d=identicon&s=25 Bill Kelly (Guest)
on 2008-06-23 08:03
(Received via mailing list)
Hi,

I've been following a blog[1] about the security patches, and
updating ruby on my servers.

Updated to latest subversion ruby_1_8_6 branch, revision 17546.
(patchlevel 231)

However, still getting a seg fault on:

ruby -ve 'str = "A"*(2**16) ; loop{ str << str ; puts str.size }'
ruby 1.8.6 (2008-06-22 patchlevel 231) [i686-linux]
131072
262144
-e:1: [BUG] Segmentation fault


(If I should be posting this to a bug tracker rather than to
ruby-core, I'll be happy to, please let me know, thanks.)


[1]
http://www.matasano.com/log/1070/updates-on-drew-y...


Regards,

Bill
3bb23e7770680ea44a2d79e6d10daaed?d=identicon&s=25 M. Edward (Ed) Borasky (Guest)
on 2008-06-23 08:33
(Received via mailing list)
Bill Kelly wrote:
> ruby -ve 'str = "A"*(2**16) ; loop{ str << str ; puts str.size }'
> [1]
>
Can you run this with "gdb?"
4feed660d3728526797edeb4f0467384?d=identicon&s=25 Bill Kelly (Guest)
on 2008-06-23 08:53
(Received via mailing list)
From: "M. Edward (Ed) Borasky" <znmeb@cesmail.net>
>> 262144
>> -e:1: [BUG] Segmentation fault
>
> Can you run this with "gdb?"

I'm a gdb newbie, but it's high time I learned.

Here's a backtrace:

(gdb) bt
#0  0x4bc3583b in raise () from /lib/tls/libc.so.6
#1  0x4bc36fa2 in abort () from /lib/tls/libc.so.6
#2  0x4bdb9a61 in rb_bug (fmt=0x0) at error.c:214
#3  0x4be231d2 in sigsegv (sig=11) at signal.c:628
#4  <signal handler called>
#5  0x4bc8707f in memcpy () from /lib/tls/libc.so.6
#6  0x4be277e1 in str_buf_cat (str=1267367944, ptr=0x20000 <Address
0x20000 out of bounds>, len=131072) at string.c:720
#7  0x4be27a08 in rb_str_buf_append (str=1270813180, str2=1270813180) at
string.c:781
#8  0x4be27aac in rb_str_append (str=1270813180, str2=1270813180) at
string.c:802
#9  0x4be27b76 in rb_str_concat (str1=32768, str2=131072) at
string.c:837
#10 0x4bdd594b in call_cfunc (func=0x4be27b40 <rb_str_concat>,
recv=1270813180, len=131072, argc=32768, argv=0x5b07580c)
    at eval.c:5700
#11 0x4bdc7970 in rb_call0 (klass=1270913000, recv=1270813180, id=334,
oid=131072, argc=1, argv=0x5b07580c, body=0x4bc09040,
    flags=0) at eval.c:5859
#12 0x4bdc84d6 in rb_call (klass=1270913000, recv=1270813180, mid=334,
argc=1, argv=0x5b07580c, scope=0, self=1270917540)
    at eval.c:6106
#13 0x4bdc27e7 in rb_eval (self=1270917540, n=0x20000) at ruby.h:679
#14 0x4bdc5a28 in rb_yield_0 (val=6, self=1270917540, klass=0, flags=0,
avalue=0) at eval.c:5033
#15 0x4bdc61d4 in rb_f_loop () at eval.c:5179
#16 0x4bdd596e in call_cfunc (func=0x4bdc6190 <rb_f_loop>,
recv=1270917540, len=131072, argc=32768, argv=0x0) at eval.c:5706
#17 0x4bdc7970 in rb_call0 (klass=1270922400, recv=1270917540, id=3953,
oid=131072, argc=0, argv=0x0, body=0x4bc0a0e4, flags=2)
    at eval.c:5859
#18 0x4bdc84d6 in rb_call (klass=1270922400, recv=1270917540, mid=3953,
argc=0, argv=0x0, scope=1, self=1270917540) at eval.c:6106
#19 0x4bdc27e7 in rb_eval (self=1270917540, n=0x20000) at ruby.h:679
#20 0x4bdc1b56 in rb_eval (self=1270917540, n=0x20000) at eval.c:3215
#21 0x4bdbe6fc in ruby_exec_internal () at eval.c:1641
#22 0x4bdbe754 in ruby_exec () at eval.c:1661
#23 0x4bdbe791 in ruby_run () at eval.c:1671
#24 0x0804872e in main (argc=131072, argv=0x20000, envp=0x5b077134) at
main.c:48

..apparently rb_str_buf_append doesn't like appending the same
string to itself? (?)

If more info would be useful, please let me know.


Regards,

Bill
9ab183bb240ffd3a3966d5a615b4bdeb?d=identicon&s=25 Phil Ross (psross)
on 2008-06-24 00:18
(Received via mailing list)
Bill Kelly wrote:
> Updated to latest subversion ruby_1_8_6 branch, revision 17546.
> (patchlevel 231)
>
> However, still getting a seg fault on:
>
> ruby -ve 'str = "A"*(2**16) ; loop{ str << str ; puts str.size }'
> ruby 1.8.6 (2008-06-22 patchlevel 231) [i686-linux]
> 131072
> 262144
> -e:1: [BUG] Segmentation fault

It looks like this issue has been fixed in revision 17530 in the
ruby_1_8 branch, but the change hasn't been merged into ruby_1_8_6.
4feed660d3728526797edeb4f0467384?d=identicon&s=25 Bill Kelly (Guest)
on 2008-06-30 10:33
(Received via mailing list)
From: "Bill Kelly" <billk@cts.com>
> -e:1: [BUG] Segmentation fault
Note, still getting this seg fault as of svn revision 17730
on 1_8_6 branch:

$ ruby -ve 'str = "A"*(2**16) ; loop{ str << str ; puts str.size }'
ruby 1.8.6 (2008-06-29 patchlevel 255) [i686-linux]
131072
-e:1: [BUG] Segmentation fault


(gdb) bt
#0  0x530a083b in raise () from /lib/tls/libc.so.6
#1  0x530a1fa2 in abort () from /lib/tls/libc.so.6
#2  0x53224a71 in rb_bug (fmt=0x0) at error.c:214
#3  0x5328e132 in sigsegv (sig=11) at signal.c:629
#4  <signal handler called>
#5  0x530f207f in memcpy () from /lib/tls/libc.so.6
#6  0x53292741 in str_buf_cat (str=1389441032, ptr=0x20000 <Address
0x20000 out of bounds>, len=131072) at string.c:720
#7  0x53292968 in rb_str_buf_append (str=1392884200, str2=1392884200) at
string.c:781
#8  0x53292a0c in rb_str_append (str=1392884200, str2=1392884200) at
string.c:802
#9  0x53292ad6 in rb_str_concat (str1=32768, str2=131072) at
string.c:837
#10 0x5324090b in call_cfunc (func=0x53292aa0 <rb_str_concat>,
recv=1392884200, len=131072, argc=32768, argv=0x5f0bec4c)
    at eval.c:5706
#11 0x53232930 in rb_call0 (klass=1392986080, recv=1392884200, id=334,
oid=131072, argc=1, argv=0x5f0bec4c, body=0x53074038,
    flags=0) at eval.c:5864
#12 0x53233496 in rb_call (klass=1392986080, recv=1392884200, mid=334,
argc=1, argv=0x5f0bec4c, scope=0, self=1392990620)
    at eval.c:6111
#13 0x5322d7e7 in rb_eval (self=1392990620, n=0x20000) at ruby.h:679
#14 0x532309f5 in rb_yield_0 (val=6, self=1392990620, klass=0, flags=0,
avalue=0) at eval.c:5039
#15 0x532311a4 in rb_f_loop () at eval.c:5185
#16 0x5324092e in call_cfunc (func=0x53231160 <rb_f_loop>,
recv=1392990620, len=131072, argc=32768, argv=0x0) at eval.c:5712
#17 0x53232930 in rb_call0 (klass=1392995480, recv=1392990620, id=3953,
oid=131072, argc=0, argv=0x0, body=0x530750dc, flags=2)
    at eval.c:5864
#18 0x53233496 in rb_call (klass=1392995480, recv=1392990620, mid=3953,
argc=0, argv=0x0, scope=1, self=1392990620) at eval.c:6111
#19 0x5322d7e7 in rb_eval (self=1392990620, n=0x20000) at ruby.h:679
#20 0x5322cb56 in rb_eval (self=1392990620, n=0x20000) at eval.c:3220
#21 0x532296fc in ruby_exec_internal () at eval.c:1643
#22 0x53229754 in ruby_exec () at eval.c:1663
#23 0x53229791 in ruby_run () at eval.c:1673
#24 0x0804872e in main (argc=131072, argv=0x20000, envp=0x5f0c0564) at
main.c:48



Regards,

Bill
9d2f78236e45a335301ba1195026105d?d=identicon&s=25 Urabe Shyouhei (Guest)
on 2008-06-30 11:00
(Received via mailing list)
Bill Kelly wrote:
>> 131072
>> 262144
>> -e:1: [BUG] Segmentation fault
>
> Note, still getting this seg fault as of svn revision 17730
> on 1_8_6 branch:
>
> $ ruby -ve 'str = "A"*(2**16) ; loop{ str << str ; puts str.size }'
> ruby 1.8.6 (2008-06-29 patchlevel 255) [i686-linux]
> 131072
> -e:1: [BUG] Segmentation fault
Sorry, cannot reproduce on my machine.  Does anyone have more info?

% ./miniruby -ve 'str = "A"*(2**16) ; loop{ str << str ; puts str.size
}'
ruby 1.8.6 (2008-06-29 patchlevel 255) [x86_64-linux]
131072
262144
524288
1048576
2097152
4194304
8388608
16777216
33554432
67108864
134217728
268435456
-e:1:in `<<': failed to allocate memory (NoMemoryError)
        from -e:1
        from -e:1:in `loop'
        from -e:1
zsh: exit 1     ./miniruby -ve 'str = "A"*(2**16) ; loop{ str << str ;
puts str.size }'
4feed660d3728526797edeb4f0467384?d=identicon&s=25 Bill Kelly (Guest)
on 2008-06-30 12:34
(Received via mailing list)
From: "Urabe Shyouhei" <shyouhei@ruby-lang.org>
> Sorry, cannot reproduce on my machine.  Does anyone have more info?
Hmm.. odd.

The above was on debian sarge, i686 arch. . .

I can also reproduce it on debian etch, x86_64 arch:

$ ./miniruby -ve 'str = "A"*(2**16) ; loop{ str << str ; puts str.size
}'
ruby 1.8.6 (2008-06-29 patchlevel 255) [x86_64-linux]
131072
262144
524288
1048576
2097152
4194304
-e:1: [BUG] Segmentation fault
ruby 1.8.6 (2008-06-29) [x86_64-linux]


As well as win32, using visual studio.net 2003:

$ .\miniruby.exe -ve "str = 'A'*(2**16) ; loop{ str << str ; puts
str.size }"
ruby 1.8.6 (2008-06-29 patchlevel 255) [i386-mswin32_71]
-e:1: [BUG] Segmentation fault


Am I checking out from the correct branch?  I am using:

svn co http://svn.ruby-lang.org/repos/ruby/branches/ruby_1_8_6

Checked out revision 17730.


Here is some info about where the seg fault occurs:

0 miniruby.exe!str_buf_cat()  Line 720 + 0x17
1 miniruby.exe!rb_str_buf_append(unsigned long str=10552920, unsigned
long str2=10552920)  Line 781 + 0x17
2 miniruby.exe!rb_str_append(unsigned long str=10552920, unsigned long
str2=10552920)  Line 802 + 0xd
3 miniruby.exe!rb_str_concat(unsigned long str1=10552920, unsigned long
str2=10552920)  Line 837 + 0xd


  static VALUE
  str_buf_cat(str, ptr, len)
      VALUE str;
      const char *ptr;
      long len;
  {

  // ...

      memcpy(RSTRING(str)->ptr + RSTRING(str)->len, ptr, len);
  00453189  mov         ecx,dword ptr [len]            // [ebp+10h]
  0045318C  mov         esi,dword ptr [ptr]            // [ebp+0Ch]
  0045318F  mov         edx,dword ptr [str]            // [ebp+8]
  00453192  mov         edi,dword ptr [edx+0Ch]
  00453195  mov         eax,dword ptr [str]            // [ebp+8]
  00453198  add         edi,dword ptr [eax+8]
  0045319B  mov         edx,ecx
  0045319D  shr         ecx,2
* 004531A0  rep movs    dword ptr [edi],dword ptr [esi]  // crash here
  004531A2  mov         ecx,edx
  004531A4  and         ecx,3
  004531A7  rep movs    byte ptr [edi],byte ptr [esi]

EAX = 00A10658 EBX = 7FFD5000 ECX = 00003E64 EDX = 00010000 ESI =
00A42000
EDI = 00A62010 EIP = 004531A0 ESP = 0012E528 EBP = 0012E540 EFL =
00010206
CS = 001B DS = 0023 ES = 0023 SS = 0023 FS = 003B GS = 0000
OV = 0 UP = 0 EI = 1 PL = 0 ZR = 0 AC = 0 PE = 1 CY = 0

ecx is 0x3e64, so I guess it copied about (0x4000 - 0x3e64)<<2 == 1648
bytes before dying.

Variables like total and capa seem pretty reasonable:

  str     10552920        unsigned long
  ptr     0x00a41990      const char *
  len     65536   long
  total   131072  long
  capa    131074  long

Strangely, the first eight bytes at [ptr] seem like junk?

0x00A41990  08 10 a5 00 78 01 98 00 41 41 41 41 41 41 41 41
..¥.x.?.AAAAAAAA
0x00A419A0  41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
AAAAAAAAAAAAAAAA
0x00A419B0  41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
AAAAAAAAAAAAAAAA
0x00A419C0  41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
AAAAAAAAAAAAAAAA


Regards,

Bill
956f185be9eac1760a2a54e287c4c844?d=identicon&s=25 ts (Guest)
on 2008-06-30 13:04
(Received via mailing list)
Bill Kelly wrote:
>   static VALUE
>   str_buf_cat(str, ptr, len)
>       VALUE str;
>       const char *ptr;
>       long len;
>   {
>
>   // ...
>
>       memcpy(RSTRING(str)->ptr + RSTRING(str)->len, ptr, len);

 best to see it like this

    if (capa <= total) {
        while (total > capa) {
            if (capa + 1 >= LONG_MAX / 2) {
                capa = total;
                break;
            }
            capa = (capa + 1) * 2;
        }
        RESIZE_CAPA(str, capa);
    }
    memcpy(RSTRING(str)->ptr + RSTRING(str)->len, ptr, len);



 before RESIZE_CAPA() it has RSTRING(str)->ptr == ptr
 and apparently realloc(RSTRING(str)->ptr) (in RESIZE_CAPA)
 make ptr invalid



Guy Decoux
9d2f78236e45a335301ba1195026105d?d=identicon&s=25 Urabe Shyouhei (Guest)
on 2008-06-30 13:39
(Received via mailing list)
Thank you Guy, this helped me a lot.  I think I've backported what's
needed from ruby_1_8. Please try again.
956f185be9eac1760a2a54e287c4c844?d=identicon&s=25 ts (Guest)
on 2008-06-30 13:44
(Received via mailing list)
Urabe Shyouhei wrote:
> Thank you Guy, this helped me a lot.  I think I've backported what's
> needed from ruby_1_8. Please try again.

 it seems to work for me

vgs% ./miniruby -ve 'str = "A"*(2**16) ; loop{ str << str ; puts
str.size }'
ruby 1.8.6 (2008-06-30 patchlevel 256) [i686-linux]
131072
262144
524288
1048576
2097152
4194304
8388608
16777216
33554432
67108864
134217728
268435456
536870912
1073741824
-e:1:in `<<': string sizes too big (ArgumentError)
  from -e:1
  from -e:1:in `loop'
  from -e:1
vgs%

 previously it crashed after 131072


Guy Decoux
4feed660d3728526797edeb4f0467384?d=identicon&s=25 Bill Kelly (Guest)
on 2008-06-30 13:56
(Received via mailing list)
From: "ts" <decoux@moulon.inra.fr>
>>  before RESIZE_CAPA() it has RSTRING(str)->ptr == ptr
>>  and apparently realloc(RSTRING(str)->ptr) (in RESIZE_CAPA)
>>  make ptr invalid

Ah... so obvious, now.  :D


From: "Urabe Shyouhei" <shyouhei@ruby-lang.org>
>
> Thank you Guy, this helped me a lot.  I think I've backported what's
> needed from ruby_1_8. Please try again.

Tried on:

ruby 1.8.6 (2008-06-30 patchlevel 256) [i686-linux]
ruby 1.8.6 (2008-06-30 patchlevel 256) [x86_64-linux]
ruby 1.8.6 (2008-06-30 patchlevel 256) [i386-mswin32_71]

...all good.


Thanks !!

Bill
97550977337c9f0a0e1a9553e55bfaa0?d=identicon&s=25 Jano Svitok (Guest)
on 2008-07-01 01:36
(Received via mailing list)
On Mon, Jun 30, 2008 at 13:53, Bill Kelly <billk@cts.com> wrote:
> Tried on:
>
> ruby 1.8.6 (2008-06-30 patchlevel 256) [i686-linux]
> ruby 1.8.6 (2008-06-30 patchlevel 256) [x86_64-linux]
> ruby 1.8.6 (2008-06-30 patchlevel 256) [i386-mswin32_71]
>
> ...all good.

I guess the vulnerability announcement should be updated with links to
a working patchlevel...

http://www.ruby-lang.org/en/news/2008/06/20/arbitr...
This topic is locked and can not be replied to.