From 2db9d0854239bca9d5c4efde808a1931c4c0ca0e Mon Sep 17 00:00:00 2001 From: Armin Kuster Date: Sat, 4 Nov 2017 11:56:03 -0700 Subject: ruby: Security fix for CVE-2017-14064 affects ruby < 2.4.1 Signed-off-by: Armin Kuster --- .../ruby/ruby/CVE-2017-14064.patch | 353 +++++++++++++++++++++ meta/recipes-devtools/ruby/ruby_2.4.0.bb | 1 + 2 files changed, 354 insertions(+) create mode 100644 meta/recipes-devtools/ruby/ruby/CVE-2017-14064.patch diff --git a/meta/recipes-devtools/ruby/ruby/CVE-2017-14064.patch b/meta/recipes-devtools/ruby/ruby/CVE-2017-14064.patch new file mode 100644 index 0000000000..700d1bc58e --- /dev/null +++ b/meta/recipes-devtools/ruby/ruby/CVE-2017-14064.patch @@ -0,0 +1,353 @@ +From d86d283fcb35d1442a121b92030884523908a331 Mon Sep 17 00:00:00 2001 +From: nagachika +Date: Sat, 22 Apr 2017 07:29:01 +0000 +Subject: [PATCH] merge revision(s) 58323,58324: + + Merge json-2.0.4. + + * https://github.com/flori/json/releases/tag/v2.0.4 + * https://github.com/flori/json/blob/09fabeb03e73ed88dc8ce8f19d76ac59e51dae20/CHANGES.md#2017-03-23-204 + Use `assert_raise` instead of `assert_raises`. + +git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_4@58445 b2dd03c8-39d4-4d8f-98ff-823fe69b080e + +Upstream-Status: Backport +CVE: CVE-2017-14064 + +Signed-off-by: Armin Kuster + +--- + ext/json/fbuffer/fbuffer.h | 3 --- + ext/json/generator/generator.c | 12 +++++----- + ext/json/generator/generator.h | 1 - + ext/json/json.gemspec | Bin 5473 -> 5474 bytes + ext/json/lib/json/version.rb | 2 +- + ext/json/parser/parser.c | 48 +++++++++++++++++++++++---------------- + ext/json/parser/parser.rl | 14 +++++++++--- + test/json/json_encoding_test.rb | 2 ++ + test/json/json_generator_test.rb | 0 + version.h | 2 +- + 10 files changed, 49 insertions(+), 35 deletions(-) + mode change 100755 => 100644 test/json/json_generator_test.rb + +Index: ruby-2.4.0/ext/json/fbuffer/fbuffer.h +=================================================================== +--- ruby-2.4.0.orig/ext/json/fbuffer/fbuffer.h ++++ ruby-2.4.0/ext/json/fbuffer/fbuffer.h +@@ -12,9 +12,6 @@ + #define RFLOAT_VALUE(val) (RFLOAT(val)->value) + #endif + +-#ifndef RARRAY_PTR +-#define RARRAY_PTR(ARRAY) RARRAY(ARRAY)->ptr +-#endif + #ifndef RARRAY_LEN + #define RARRAY_LEN(ARRAY) RARRAY(ARRAY)->len + #endif +Index: ruby-2.4.0/ext/json/generator/generator.c +=================================================================== +--- ruby-2.4.0.orig/ext/json/generator/generator.c ++++ ruby-2.4.0/ext/json/generator/generator.c +@@ -308,7 +308,7 @@ static char *fstrndup(const char *ptr, u + char *result; + if (len <= 0) return NULL; + result = ALLOC_N(char, len); +- memccpy(result, ptr, 0, len); ++ memcpy(result, ptr, len); + return result; + } + +@@ -1062,7 +1062,7 @@ static VALUE cState_indent_set(VALUE sel + } + } else { + if (state->indent) ruby_xfree(state->indent); +- state->indent = strdup(RSTRING_PTR(indent)); ++ state->indent = fstrndup(RSTRING_PTR(indent), len); + state->indent_len = len; + } + return Qnil; +@@ -1100,7 +1100,7 @@ static VALUE cState_space_set(VALUE self + } + } else { + if (state->space) ruby_xfree(state->space); +- state->space = strdup(RSTRING_PTR(space)); ++ state->space = fstrndup(RSTRING_PTR(space), len); + state->space_len = len; + } + return Qnil; +@@ -1136,7 +1136,7 @@ static VALUE cState_space_before_set(VAL + } + } else { + if (state->space_before) ruby_xfree(state->space_before); +- state->space_before = strdup(RSTRING_PTR(space_before)); ++ state->space_before = fstrndup(RSTRING_PTR(space_before), len); + state->space_before_len = len; + } + return Qnil; +@@ -1173,7 +1173,7 @@ static VALUE cState_object_nl_set(VALUE + } + } else { + if (state->object_nl) ruby_xfree(state->object_nl); +- state->object_nl = strdup(RSTRING_PTR(object_nl)); ++ state->object_nl = fstrndup(RSTRING_PTR(object_nl), len); + state->object_nl_len = len; + } + return Qnil; +@@ -1208,7 +1208,7 @@ static VALUE cState_array_nl_set(VALUE s + } + } else { + if (state->array_nl) ruby_xfree(state->array_nl); +- state->array_nl = strdup(RSTRING_PTR(array_nl)); ++ state->array_nl = fstrndup(RSTRING_PTR(array_nl), len); + state->array_nl_len = len; + } + return Qnil; +Index: ruby-2.4.0/ext/json/generator/generator.h +=================================================================== +--- ruby-2.4.0.orig/ext/json/generator/generator.h ++++ ruby-2.4.0/ext/json/generator/generator.h +@@ -1,7 +1,6 @@ + #ifndef _GENERATOR_H_ + #define _GENERATOR_H_ + +-#include + #include + #include + +Index: ruby-2.4.0/ext/json/lib/json/version.rb +=================================================================== +--- ruby-2.4.0.orig/ext/json/lib/json/version.rb ++++ ruby-2.4.0/ext/json/lib/json/version.rb +@@ -1,7 +1,7 @@ + # frozen_string_literal: false + module JSON + # JSON version +- VERSION = '2.0.2' ++ VERSION = '2.0.4' + VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc: + VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc: + VERSION_MINOR = VERSION_ARRAY[1] # :nodoc: +Index: ruby-2.4.0/ext/json/parser/parser.c +=================================================================== +--- ruby-2.4.0.orig/ext/json/parser/parser.c ++++ ruby-2.4.0/ext/json/parser/parser.c +@@ -1435,13 +1435,21 @@ static VALUE json_string_unescape(VALUE + break; + case 'u': + if (pe > stringEnd - 4) { +- return Qnil; ++ rb_enc_raise( ++ EXC_ENCODING eParserError, ++ "%u: incomplete unicode character escape sequence at '%s'", __LINE__, p ++ ); + } else { + UTF32 ch = unescape_unicode((unsigned char *) ++pe); + pe += 3; + if (UNI_SUR_HIGH_START == (ch & 0xFC00)) { + pe++; +- if (pe > stringEnd - 6) return Qnil; ++ if (pe > stringEnd - 6) { ++ rb_enc_raise( ++ EXC_ENCODING eParserError, ++ "%u: incomplete surrogate pair at '%s'", __LINE__, p ++ ); ++ } + if (pe[0] == '\\' && pe[1] == 'u') { + UTF32 sur = unescape_unicode((unsigned char *) pe + 2); + ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16) +@@ -1471,7 +1479,7 @@ static VALUE json_string_unescape(VALUE + } + + +-#line 1475 "parser.c" ++#line 1483 "parser.c" + enum {JSON_string_start = 1}; + enum {JSON_string_first_final = 8}; + enum {JSON_string_error = 0}; +@@ -1479,7 +1487,7 @@ enum {JSON_string_error = 0}; + enum {JSON_string_en_main = 1}; + + +-#line 504 "parser.rl" ++#line 512 "parser.rl" + + + static int +@@ -1501,15 +1509,15 @@ static char *JSON_parse_string(JSON_Pars + + *result = rb_str_buf_new(0); + +-#line 1505 "parser.c" ++#line 1513 "parser.c" + { + cs = JSON_string_start; + } + +-#line 525 "parser.rl" ++#line 533 "parser.rl" + json->memo = p; + +-#line 1513 "parser.c" ++#line 1521 "parser.c" + { + if ( p == pe ) + goto _test_eof; +@@ -1534,7 +1542,7 @@ case 2: + goto st0; + goto st2; + tr2: +-#line 490 "parser.rl" ++#line 498 "parser.rl" + { + *result = json_string_unescape(*result, json->memo + 1, p); + if (NIL_P(*result)) { +@@ -1545,14 +1553,14 @@ tr2: + {p = (( p + 1))-1;} + } + } +-#line 501 "parser.rl" ++#line 509 "parser.rl" + { p--; {p++; cs = 8; goto _out;} } + goto st8; + st8: + if ( ++p == pe ) + goto _test_eof8; + case 8: +-#line 1556 "parser.c" ++#line 1564 "parser.c" + goto st0; + st3: + if ( ++p == pe ) +@@ -1628,7 +1636,7 @@ case 7: + _out: {} + } + +-#line 527 "parser.rl" ++#line 535 "parser.rl" + + if (json->create_additions && RTEST(match_string = json->match_string)) { + VALUE klass; +@@ -1675,7 +1683,7 @@ static VALUE convert_encoding(VALUE sour + } + FORCE_UTF8(source); + } else { +- source = rb_str_conv_enc(source, NULL, rb_utf8_encoding()); ++ source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding()); + } + #endif + return source; +@@ -1808,7 +1816,7 @@ static VALUE cParser_initialize(int argc + } + + +-#line 1812 "parser.c" ++#line 1820 "parser.c" + enum {JSON_start = 1}; + enum {JSON_first_final = 10}; + enum {JSON_error = 0}; +@@ -1816,7 +1824,7 @@ enum {JSON_error = 0}; + enum {JSON_en_main = 1}; + + +-#line 720 "parser.rl" ++#line 728 "parser.rl" + + + /* +@@ -1833,16 +1841,16 @@ static VALUE cParser_parse(VALUE self) + GET_PARSER; + + +-#line 1837 "parser.c" ++#line 1845 "parser.c" + { + cs = JSON_start; + } + +-#line 736 "parser.rl" ++#line 744 "parser.rl" + p = json->source; + pe = p + json->len; + +-#line 1846 "parser.c" ++#line 1854 "parser.c" + { + if ( p == pe ) + goto _test_eof; +@@ -1876,7 +1884,7 @@ st0: + cs = 0; + goto _out; + tr2: +-#line 712 "parser.rl" ++#line 720 "parser.rl" + { + char *np = JSON_parse_value(json, p, pe, &result, 0); + if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;} +@@ -1886,7 +1894,7 @@ st10: + if ( ++p == pe ) + goto _test_eof10; + case 10: +-#line 1890 "parser.c" ++#line 1898 "parser.c" + switch( (*p) ) { + case 13: goto st10; + case 32: goto st10; +@@ -1975,7 +1983,7 @@ case 9: + _out: {} + } + +-#line 739 "parser.rl" ++#line 747 "parser.rl" + + if (cs >= JSON_first_final && p == pe) { + return result; +Index: ruby-2.4.0/ext/json/parser/parser.rl +=================================================================== +--- ruby-2.4.0.orig/ext/json/parser/parser.rl ++++ ruby-2.4.0/ext/json/parser/parser.rl +@@ -446,13 +446,21 @@ static VALUE json_string_unescape(VALUE + break; + case 'u': + if (pe > stringEnd - 4) { +- return Qnil; ++ rb_enc_raise( ++ EXC_ENCODING eParserError, ++ "%u: incomplete unicode character escape sequence at '%s'", __LINE__, p ++ ); + } else { + UTF32 ch = unescape_unicode((unsigned char *) ++pe); + pe += 3; + if (UNI_SUR_HIGH_START == (ch & 0xFC00)) { + pe++; +- if (pe > stringEnd - 6) return Qnil; ++ if (pe > stringEnd - 6) { ++ rb_enc_raise( ++ EXC_ENCODING eParserError, ++ "%u: incomplete surrogate pair at '%s'", __LINE__, p ++ ); ++ } + if (pe[0] == '\\' && pe[1] == 'u') { + UTF32 sur = unescape_unicode((unsigned char *) pe + 2); + ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16) +@@ -570,7 +578,7 @@ static VALUE convert_encoding(VALUE sour + } + FORCE_UTF8(source); + } else { +- source = rb_str_conv_enc(source, NULL, rb_utf8_encoding()); ++ source = rb_str_conv_enc(source, rb_enc_get(source), rb_utf8_encoding()); + } + #endif + return source; +Index: ruby-2.4.0/test/json/json_encoding_test.rb +=================================================================== +--- ruby-2.4.0.orig/test/json/json_encoding_test.rb ++++ ruby-2.4.0/test/json/json_encoding_test.rb +@@ -79,6 +79,8 @@ class JSONEncodingTest < Test::Unit::Tes + json = '["\ud840\udc01"]' + assert_equal json, generate(utf8, :ascii_only => true) + assert_equal utf8, parse(json) ++ assert_raise(JSON::ParserError) { parse('"\u"') } ++ assert_raise(JSON::ParserError) { parse('"\ud800"') } + end + + def test_chars diff --git a/meta/recipes-devtools/ruby/ruby_2.4.0.bb b/meta/recipes-devtools/ruby/ruby_2.4.0.bb index f1bd8289b6..8cc52d6211 100644 --- a/meta/recipes-devtools/ruby/ruby_2.4.0.bb +++ b/meta/recipes-devtools/ruby/ruby_2.4.0.bb @@ -6,6 +6,7 @@ SRC_URI += " \ file://ruby-CVE-2017-9227.patch \ file://ruby-CVE-2017-9228.patch \ file://ruby-CVE-2017-9229.patch \ + file://CVE-2017-14064.patch \ " SRC_URI[md5sum] = "7e9485dcdb86ff52662728de2003e625" -- cgit 1.2.3-korg