diff options
author | Kazuki Yamaguchi <k@rhe.jp> | 2016-11-07 11:11:24 +0900 |
---|---|---|
committer | Kazuki Yamaguchi <k@rhe.jp> | 2016-11-07 11:11:24 +0900 |
commit | c86e2aa39760dc1f9c93ff63084d12d1a950a306 (patch) | |
tree | 0c596c7c52764151e59887e89caae96ed2a383a6 /ext/openssl/ossl_asn1.c | |
parent | db01120382fb7d4ebb3e2a7fe6b407c065e69e3c (diff) | |
parent | 1648afef33c1d97fb203c82291b8a61269e85d3b (diff) | |
download | ruby-openssl-c86e2aa39760dc1f9c93ff63084d12d1a950a306.tar.gz |
Merge branch 'topic/asn1-fix-oob-read-constructed'
* topic/asn1-fix-oob-read-constructed:
asn1: fix out-of-bounds read in decoding constructed objects
Diffstat (limited to 'ext/openssl/ossl_asn1.c')
-rw-r--r-- | ext/openssl/ossl_asn1.c | 13 |
1 files changed, 6 insertions, 7 deletions
diff --git a/ext/openssl/ossl_asn1.c b/ext/openssl/ossl_asn1.c index 892b76e7..9d759c1e 100644 --- a/ext/openssl/ossl_asn1.c +++ b/ext/openssl/ossl_asn1.c @@ -823,19 +823,18 @@ int_ossl_asn1_decode0_cons(unsigned char **pp, long max_len, long length, { 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 && @@ -926,7 +925,7 @@ ossl_asn1_decode0(unsigned char **pp, long length, long *offset, int depth, 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 { |