diff options
Diffstat (limited to 'meta/recipes-devtools/ruby/ruby/CVE-2017-14033.patch')
-rw-r--r-- | meta/recipes-devtools/ruby/ruby/CVE-2017-14033.patch | 89 |
1 files changed, 89 insertions, 0 deletions
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 @@ | |||
1 | From 1648afef33c1d97fb203c82291b8a61269e85d3b Mon Sep 17 00:00:00 2001 | ||
2 | From: Kazuki Yamaguchi <k@rhe.jp> | ||
3 | Date: Mon, 19 Sep 2016 15:38:44 +0900 | ||
4 | Subject: [PATCH] asn1: fix out-of-bounds read in decoding constructed objects | ||
5 | |||
6 | OpenSSL::ASN1.{decode,decode_all,traverse} have a bug of out-of-bounds | ||
7 | read. int_ossl_asn1_decode0_cons() does not give the correct available | ||
8 | length to ossl_asn1_decode() when decoding the inner components of a | ||
9 | constructed object. This can cause out-of-bounds read if a crafted input | ||
10 | given. | ||
11 | |||
12 | Reference: https://hackerone.com/reports/170316 | ||
13 | |||
14 | Upstream-Status: Backport | ||
15 | CVE: CVE-2017-14033 | ||
16 | |||
17 | Signed-off-by: Rajkumar Veer<rveer@mvista.com> | ||
18 | --- | ||
19 | ext/openssl/ossl_asn1.c | 13 ++++++------- | ||
20 | test/test_asn1.rb | 23 +++++++++++++++++++++++ | ||
21 | 2 files changed, 29 insertions(+), 7 deletions(-) | ||
22 | --- a/ext/openssl/ossl_asn1.c | ||
23 | +++ b/ext/openssl/ossl_asn1.c | ||
24 | @@ -871,19 +871,18 @@ | ||
25 | { | ||
26 | VALUE value, asn1data, ary; | ||
27 | int infinite; | ||
28 | - long off = *offset; | ||
29 | + long available_len, off = *offset; | ||
30 | |||
31 | infinite = (j == 0x21); | ||
32 | ary = rb_ary_new(); | ||
33 | |||
34 | - while (length > 0 || infinite) { | ||
35 | + available_len = infinite ? max_len : length; | ||
36 | + while (available_len > 0 ) { | ||
37 | long inner_read = 0; | ||
38 | - value = ossl_asn1_decode0(pp, max_len, &off, depth + 1, yield, &inner_read); | ||
39 | + value = ossl_asn1_decode0(pp, available_len, &off, depth + 1, yield, &inner_read); | ||
40 | *num_read += inner_read; | ||
41 | - max_len -= inner_read; | ||
42 | + available_len -= inner_read; | ||
43 | rb_ary_push(ary, value); | ||
44 | - if (length > 0) | ||
45 | - length -= inner_read; | ||
46 | |||
47 | if (infinite && | ||
48 | NUM2INT(ossl_asn1_get_tag(value)) == V_ASN1_EOC && | ||
49 | @@ -974,7 +973,7 @@ | ||
50 | if(j & V_ASN1_CONSTRUCTED) { | ||
51 | *pp += hlen; | ||
52 | off += hlen; | ||
53 | - asn1data = int_ossl_asn1_decode0_cons(pp, length, len, &off, depth, yield, j, tag, tag_class, &inner_read); | ||
54 | + asn1data = int_ossl_asn1_decode0_cons(pp, length - hlen, len, &off, depth, yield, j, tag, tag_class, &inner_read); | ||
55 | inner_read += hlen; | ||
56 | } | ||
57 | else { | ||
58 | --- a/test/openssl/test_asn1.rb | ||
59 | +++ b/test/openssl/test_asn1.rb | ||
60 | @@ -595,6 +595,29 @@ | ||
61 | assert_equal(false, asn1.value[3].infinite_length) | ||
62 | end | ||
63 | |||
64 | + def test_decode_constructed_overread | ||
65 | + test = %w{ 31 06 31 02 30 02 05 00 } | ||
66 | + # ^ <- invalid | ||
67 | + raw = [test.join].pack("H*") | ||
68 | + ret = [] | ||
69 | + assert_raise(OpenSSL::ASN1::ASN1Error) { | ||
70 | + OpenSSL::ASN1.traverse(raw) { |x| ret << x } | ||
71 | + } | ||
72 | + assert_equal 2, ret.size | ||
73 | + assert_equal 17, ret[0][6] | ||
74 | + assert_equal 17, ret[1][6] | ||
75 | + | ||
76 | + test = %w{ 31 80 30 03 00 00 } | ||
77 | + # ^ <- invalid | ||
78 | + raw = [test.join].pack("H*") | ||
79 | + ret = [] | ||
80 | + assert_raise(OpenSSL::ASN1::ASN1Error) { | ||
81 | + OpenSSL::ASN1.traverse(raw) { |x| ret << x } | ||
82 | + } | ||
83 | + assert_equal 1, ret.size | ||
84 | + assert_equal 17, ret[0][6] | ||
85 | + end | ||
86 | + | ||
87 | private | ||
88 | |||
89 | def assert_universal(tag, asn1) | ||