From d10e1484033874309423fdd16e01a7cce66cec57 Mon Sep 17 00:00:00 2001 From: Rajkumar Veer Date: Sat, 4 Nov 2017 10:43:01 -0700 Subject: ruby: Security fix for CVE-2017-14033 affects ruby before 2.2.8, 2.3.x before 2.3.5, and 2.4.x through 2.4.1 Signed-off-by: Rajkumar Veer Signed-off-by: Armin Kuster (cherry picked from commit 6033983453ff7b39d9d0d0a64353611128e26fae) Signed-off-by: Armin Kuster --- .../ruby/ruby/CVE-2017-14033.patch | 89 ++++++++++++++++++++++ meta/recipes-devtools/ruby/ruby_2.2.5.bb | 1 + 2 files changed, 90 insertions(+) create mode 100644 meta/recipes-devtools/ruby/ruby/CVE-2017-14033.patch diff --git a/meta/recipes-devtools/ruby/ruby/CVE-2017-14033.patch b/meta/recipes-devtools/ruby/ruby/CVE-2017-14033.patch new file mode 100644 index 0000000000..cbcd18c788 --- /dev/null +++ b/meta/recipes-devtools/ruby/ruby/CVE-2017-14033.patch @@ -0,0 +1,89 @@ +From 1648afef33c1d97fb203c82291b8a61269e85d3b Mon Sep 17 00:00:00 2001 +From: Kazuki Yamaguchi +Date: Mon, 19 Sep 2016 15:38:44 +0900 +Subject: [PATCH] asn1: fix out-of-bounds read in decoding constructed objects + +OpenSSL::ASN1.{decode,decode_all,traverse} have a bug of out-of-bounds +read. int_ossl_asn1_decode0_cons() does not give the correct available +length to ossl_asn1_decode() when decoding the inner components of a +constructed object. This can cause out-of-bounds read if a crafted input +given. + +Reference: https://hackerone.com/reports/170316 + +Upstream-Status: Backport +CVE: CVE-2017-14033 + +Signed-off-by: Rajkumar Veer +--- + ext/openssl/ossl_asn1.c | 13 ++++++------- + test/test_asn1.rb | 23 +++++++++++++++++++++++ + 2 files changed, 29 insertions(+), 7 deletions(-) +--- a/ext/openssl/ossl_asn1.c ++++ b/ext/openssl/ossl_asn1.c +@@ -871,19 +871,18 @@ + { + VALUE value, asn1data, ary; + int infinite; +- long off = *offset; ++ long available_len, off = *offset; + + infinite = (j == 0x21); + ary = rb_ary_new(); + +- while (length > 0 || infinite) { ++ available_len = infinite ? max_len : length; ++ while (available_len > 0 ) { + long inner_read = 0; +- value = ossl_asn1_decode0(pp, max_len, &off, depth + 1, yield, &inner_read); ++ value = ossl_asn1_decode0(pp, available_len, &off, depth + 1, yield, &inner_read); + *num_read += inner_read; +- max_len -= inner_read; ++ available_len -= inner_read; + rb_ary_push(ary, value); +- if (length > 0) +- length -= inner_read; + + if (infinite && + NUM2INT(ossl_asn1_get_tag(value)) == V_ASN1_EOC && +@@ -974,7 +973,7 @@ + if(j & V_ASN1_CONSTRUCTED) { + *pp += hlen; + off += hlen; +- asn1data = int_ossl_asn1_decode0_cons(pp, length, len, &off, depth, yield, j, tag, tag_class, &inner_read); ++ asn1data = int_ossl_asn1_decode0_cons(pp, length - hlen, len, &off, depth, yield, j, tag, tag_class, &inner_read); + inner_read += hlen; + } + else { +--- a/test/openssl/test_asn1.rb ++++ b/test/openssl/test_asn1.rb +@@ -595,6 +595,29 @@ + assert_equal(false, asn1.value[3].infinite_length) + end + ++ def test_decode_constructed_overread ++ test = %w{ 31 06 31 02 30 02 05 00 } ++ # ^ <- invalid ++ raw = [test.join].pack("H*") ++ ret = [] ++ assert_raise(OpenSSL::ASN1::ASN1Error) { ++ OpenSSL::ASN1.traverse(raw) { |x| ret << x } ++ } ++ assert_equal 2, ret.size ++ assert_equal 17, ret[0][6] ++ assert_equal 17, ret[1][6] ++ ++ test = %w{ 31 80 30 03 00 00 } ++ # ^ <- invalid ++ raw = [test.join].pack("H*") ++ ret = [] ++ assert_raise(OpenSSL::ASN1::ASN1Error) { ++ OpenSSL::ASN1.traverse(raw) { |x| ret << x } ++ } ++ assert_equal 1, ret.size ++ assert_equal 17, ret[0][6] ++ end ++ + private + + def assert_universal(tag, asn1) diff --git a/meta/recipes-devtools/ruby/ruby_2.2.5.bb b/meta/recipes-devtools/ruby/ruby_2.2.5.bb index 6bb68ef4fd..352854e5d5 100644 --- a/meta/recipes-devtools/ruby/ruby_2.2.5.bb +++ b/meta/recipes-devtools/ruby/ruby_2.2.5.bb @@ -9,6 +9,7 @@ SRC_URI += "file://prevent-gc.patch \ file://CVE-2017-9228.patch \ file://CVE-2017-9226.patch \ file://CVE-2017-9229.patch \ + file://CVE-2017-14033.patch \ " # it's unknown to configure script, but then passed to extconf.rb -- cgit 1.2.3-korg