[前][次][番号順一覧][スレッド一覧]

ruby-changes:47895

From: rhe <ko1@a...>
Date: Mon, 25 Sep 2017 01:26:30 +0900 (JST)
Subject: [ruby-changes:47895] rhe:r60013 (trunk): openssl: import e72d960db262

rhe	2017-09-25 01:26:22 +0900 (Mon, 25 Sep 2017)

  New Revision: 60013

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=60013

  Log:
    openssl: import e72d960db262
    
    Sync with master branch of ruby/openssl.git to import changes in
    v2.1.0.beta1..v2.0.6. The commit log since v2.1.0.beta1 which was
    imported by r59734 can be found at:
    
    https://github.com/ruby/openssl/compare/v2.1.0.beta1...e72d960db262
    
    ----------------------------------------------------------------
    Kazuki Yamaguchi (16):
          test/test_pair: fix test_write_nonblock{,_no_exceptions}
          x509name: fix a typo in docs
          test/test_fips: skip if setting FIPS mode fails
          test/test_asn1: fix possible failure in test_utctime
          test/test_ssl: suppress warning in test_alpn_protocol_selection_cancel
          test/test_pair: disable compression
          test/test_ssl: skip tmp_ecdh_callback test for LibreSSL >= 2.6.1
          test/test_ssl: do not run NPN tests for LibreSSL >= 2.6.1
          tool/ruby-openssl-docker: update
          test/test_pair: replace sleep with IO.select
          ssl: prevent SSLSocket#sysread* from leaking uninitialized data
          ossl.c: use struct CRYPTO_dynlock_value for non-dynamic locks
          ossl.c: make legacy locking callbacks reentrant
          test/test_engine: suppress stderr
          test/test_engine: check if RC4 is supported
          Ruby/OpenSSL 2.0.6
    
    SHIBATA Hiroshi (1):
          To use upstream url of github
    
    nobu (1):
          ruby.h: unnormalized Fixnum value

  Modified files:
    trunk/ext/openssl/History.md
    trunk/ext/openssl/openssl.gemspec
    trunk/ext/openssl/ossl.c
    trunk/ext/openssl/ossl_ssl.c
    trunk/ext/openssl/ossl_x509name.c
    trunk/ext/openssl/ruby_missing.h
    trunk/test/openssl/test_engine.rb
    trunk/test/openssl/test_pair.rb
    trunk/test/openssl/test_ssl.rb
Index: test/openssl/test_pair.rb
===================================================================
--- test/openssl/test_pair.rb	(revision 60012)
+++ test/openssl/test_pair.rb	(revision 60013)
@@ -218,7 +218,7 @@ module OpenSSL::TestPairM https://github.com/ruby/ruby/blob/trunk/test/openssl/test_pair.rb#L218
       assert_nothing_raised("[ruby-core:20298]") { ret = s2.read_nonblock(10) }
       assert_equal("def\n", ret)
       s1.close
-      sleep 0.1
+      IO.select([s2])
       assert_raise(EOFError) { s2.read_nonblock(10) }
     }
   end
@@ -234,11 +234,35 @@ module OpenSSL::TestPairM https://github.com/ruby/ruby/blob/trunk/test/openssl/test_pair.rb#L234
       assert_nothing_raised("[ruby-core:20298]") { ret = s2.read_nonblock(10, exception: false) }
       assert_equal("def\n", ret)
       s1.close
-      sleep 0.1
+      IO.select([s2])
       assert_equal(nil, s2.read_nonblock(10, exception: false))
     }
   end
 
+  def test_read_with_outbuf
+    ssl_pair { |s1, s2|
+      s1.write("abc\n")
+      buf = ""
+      ret = s2.read(2, buf)
+      assert_same ret, buf
+      assert_equal "ab", ret
+
+      buf = "garbage"
+      ret = s2.read(2, buf)
+      assert_same ret, buf
+      assert_equal "c\n", ret
+
+      buf = "garbage"
+      assert_equal :wait_readable, s2.read_nonblock(100, buf, exception: false)
+      assert_equal "", buf
+
+      s1.close
+      buf = "garbage"
+      assert_equal nil, s2.read(100, buf)
+      assert_equal "", buf
+    }
+  end
+
   def test_write_nonblock
     ssl_pair {|s1, s2|
       assert_equal 3, s1.write_nonblock("foo")
Index: test/openssl/test_ssl.rb
===================================================================
--- test/openssl/test_ssl.rb	(revision 60012)
+++ test/openssl/test_ssl.rb	(revision 60013)
@@ -1042,6 +1042,7 @@ end https://github.com/ruby/ruby/blob/trunk/test/openssl/test_ssl.rb#L1042
     pend "TLS 1.2 is not supported" unless tls12_supported?
     pend "NPN is not supported" unless \
       OpenSSL::SSL::SSLContext.method_defined?(:npn_select_cb)
+    pend "LibreSSL 2.6 has broken NPN functions" if libressl?(2, 6, 1)
 
     advertised = ["http/1.1", "spdy/2"]
     ctx_proc = proc { |ctx| ctx.npn_protocols = advertised }
@@ -1062,6 +1063,7 @@ end https://github.com/ruby/ruby/blob/trunk/test/openssl/test_ssl.rb#L1063
     pend "TLS 1.2 is not supported" unless tls12_supported?
     pend "NPN is not supported" unless \
       OpenSSL::SSL::SSLContext.method_defined?(:npn_select_cb)
+    pend "LibreSSL 2.6 has broken NPN functions" if libressl?(2, 6, 1)
 
     advertised = Object.new
     def advertised.each
@@ -1086,6 +1088,7 @@ end https://github.com/ruby/ruby/blob/trunk/test/openssl/test_ssl.rb#L1088
     pend "TLS 1.2 is not supported" unless tls12_supported?
     pend "NPN is not supported" unless \
       OpenSSL::SSL::SSLContext.method_defined?(:npn_select_cb)
+    pend "LibreSSL 2.6 has broken NPN functions" if libressl?(2, 6, 1)
 
     ctx_proc = Proc.new { |ctx| ctx.npn_protocols = ["http/1.1"] }
     start_server_version(:TLSv1_2, ctx_proc) { |port|
@@ -1099,6 +1102,7 @@ end https://github.com/ruby/ruby/blob/trunk/test/openssl/test_ssl.rb#L1102
     pend "TLS 1.2 is not supported" unless tls12_supported?
     pend "NPN is not supported" unless \
       OpenSSL::SSL::SSLContext.method_defined?(:npn_select_cb)
+    pend "LibreSSL 2.6 has broken NPN functions" if libressl?(2, 6, 1)
 
     ctx_proc = Proc.new { |ctx| ctx.npn_protocols = ["a" * 256] }
     start_server_version(:TLSv1_2, ctx_proc) { |port|
@@ -1112,6 +1116,7 @@ end https://github.com/ruby/ruby/blob/trunk/test/openssl/test_ssl.rb#L1116
     pend "TLS 1.2 is not supported" unless tls12_supported?
     pend "NPN is not supported" unless \
       OpenSSL::SSL::SSLContext.method_defined?(:npn_select_cb)
+    pend "LibreSSL 2.6 has broken NPN functions" if libressl?(2, 6, 1)
 
     ctx_proc = Proc.new { |ctx| ctx.npn_protocols = ["http/1.1"] }
     start_server_version(:TLSv1_2, ctx_proc) { |port|
@@ -1242,6 +1247,8 @@ end https://github.com/ruby/ruby/blob/trunk/test/openssl/test_ssl.rb#L1247
     pend "EC is disabled" unless defined?(OpenSSL::PKey::EC)
     pend "tmp_ecdh_callback is not supported" unless \
       OpenSSL::SSL::SSLContext.method_defined?(:tmp_ecdh_callback)
+    pend "LibreSSL 2.6 has broken SSL_CTX_set_tmp_ecdh_callback()" \
+      if libressl?(2, 6, 1)
 
     EnvUtil.suppress_warning do # tmp_ecdh_callback is deprecated (2016-05)
       called = false
Index: test/openssl/test_engine.rb
===================================================================
--- test/openssl/test_engine.rb	(revision 60012)
+++ test/openssl/test_engine.rb	(revision 60013)
@@ -52,32 +52,28 @@ class OpenSSL::TestEngine < OpenSSL::Tes https://github.com/ruby/ruby/blob/trunk/test/openssl/test_engine.rb#L52
   end
 
   def test_openssl_engine_cipher_rc4
-    with_openssl <<-'end;'
-      begin
-        engine = get_engine
-        algo = "RC4" #AES is not supported by openssl Engine (<=1.0.0e)
-        data = "a" * 1000
-        key = OpenSSL::Random.random_bytes(16)
-        # suppress message from openssl Engine's RC4 cipher [ruby-core:41026]
-        err_back = $stderr.dup
-        $stderr.reopen(IO::NULL)
-        encrypted = crypt_data(data, key, :encrypt) { engine.cipher(algo) }
-        decrypted = crypt_data(encrypted, key, :decrypt) { OpenSSL::Cipher.new(algo) }
-        assert_equal(data, decrypted)
-      ensure
-        if err_back
-          $stderr.reopen(err_back)
-          err_back.close
-        end
-      end
+    begin
+      OpenSSL::Cipher.new("rc4")
+    rescue OpenSSL::Cipher::CipherError
+      pend "RC4 is not supported"
+    end
+
+    with_openssl(<<-'end;', ignore_stderr: true)
+      engine = get_engine
+      algo = "RC4"
+      data = "a" * 1000
+      key = OpenSSL::Random.random_bytes(16)
+      encrypted = crypt_data(data, key, :encrypt) { engine.cipher(algo) }
+      decrypted = crypt_data(encrypted, key, :decrypt) { OpenSSL::Cipher.new(algo) }
+      assert_equal(data, decrypted)
     end;
   end
 
   private
 
   # this is required because OpenSSL::Engine methods change global state
-  def with_openssl(code)
-    assert_separately([{ "OSSL_MDEBUG" => nil }, "-ropenssl"], <<~"end;")
+  def with_openssl(code, **opts)
+    assert_separately([{ "OSSL_MDEBUG" => nil }, "-ropenssl"], <<~"end;", **opts)
       require #{__FILE__.dump}
       include OpenSSL::TestEngine::Utils
       #{code}
Index: ext/openssl/History.md
===================================================================
--- ext/openssl/History.md	(revision 60012)
+++ ext/openssl/History.md	(revision 60013)
@@ -29,6 +29,26 @@ Notable changes https://github.com/ruby/ruby/blob/trunk/ext/openssl/History.md#L29
   [[GitHub #143]](https://github.com/ruby/openssl/pull/143)
 
 
+Version 2.0.6
+=============
+
+Bug fixes
+---------
+
+* The session_remove_cb set to an OpenSSL::SSL::SSLContext is no longer called
+  during GC.
+* A possible deadlock in OpenSSL::SSL::SSLSocket#sysread is fixed.
+  [[GitHub #139]](https://github.com/ruby/openssl/pull/139)
+* OpenSSL::BN#hash could return an unnormalized fixnum value on Windows.
+  [[Bug #13877]](https://bugs.ruby-lang.org/issues/13877)
+* OpenSSL::SSL::SSLSocket#sysread and #sysread_nonblock set the length of the
+  destination buffer String to 0 on error.
+  [[GitHub #153]](https://github.com/ruby/openssl/pull/153)
+* Possible deadlock is fixed. This happened only when built with older versions
+  of OpenSSL (before 1.1.0) or LibreSSL.
+  [[GitHub #155]](https://github.com/ruby/openssl/pull/155)
+
+
 Version 2.0.5
 =============
 
Index: ext/openssl/ossl_ssl.c
===================================================================
--- ext/openssl/ossl_ssl.c	(revision 60012)
+++ ext/openssl/ossl_ssl.c	(revision 60013)
@@ -1694,20 +1694,26 @@ ossl_ssl_read_internal(int argc, VALUE * https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_ssl.c#L1694
     }
 
     ilen = NUM2INT(len);
-    if(NIL_P(str)) str = rb_str_new(0, ilen);
-    else{
-        StringValue(str);
-        rb_str_modify(str);
-        rb_str_resize(str, ilen);
+    if (NIL_P(str))
+	str = rb_str_new(0, ilen);
+    else {
+	StringValue(str);
+	if (RSTRING_LEN(str) >= ilen)
+	    rb_str_modify(str);
+	else
+	    rb_str_modify_expand(str, ilen - RSTRING_LEN(str));
     }
-    if(ilen == 0) return str;
+    OBJ_TAINT(str);
+    rb_str_set_len(str, 0);
+    if (ilen == 0)
+	return str;
 
     GetSSL(self, ssl);
     io = rb_attr_get(self, id_i_io);
     GetOpenFile(io, fptr);
     if (ssl_started(ssl)) {
 	for (;;){
-	    nread = SSL_read(ssl, RSTRING_PTR(str), RSTRING_LENINT(str));
+	    nread = SSL_read(ssl, RSTRING_PTR(str), ilen);
 	    switch(ssl_get_error(ssl, nread)){
 	    case SSL_ERROR_NONE:
 		goto end;
@@ -1757,8 +1763,6 @@ ossl_ssl_read_internal(int argc, VALUE * https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_ssl.c#L1763
 
   end:
     rb_str_set_len(str, nread);
-    OBJ_TAINT(str);
-
     return str;
 }
 
Index: ext/openssl/ruby_missing.h
===================================================================
--- ext/openssl/ruby_missing.h	(revision 60012)
+++ ext/openssl/ruby_missing.h	(revision 60013)
@@ -10,9 +10,15 @@ https://github.com/ruby/ruby/blob/trunk/ext/openssl/ruby_missing.h#L10
 #if !defined(_OSSL_RUBY_MISSING_H_)
 #define _OSSL_RUBY_MISSING_H_
 
+/* Ruby 2.4 */
 #ifndef RB_INTEGER_TYPE_P
-/* for Ruby 2.3 compatibility */
-#define RB_INTEGER_TYPE_P(obj) (RB_FIXNUM_P(obj) || RB_TYPE_P(obj, T_BIGNUM))
+# define RB_INTEGER_TYPE_P(obj) (RB_FIXNUM_P(obj) || RB_TYPE_P(obj, T_BIGNUM))
+#endif
+
+/* Ruby 2.5 */
+#ifndef ST2FIX
+# define RB_ST2FIX(h) LONG2FIX((long)(h))
+# define ST2FIX(h) RB_ST2FIX(h)
 #endif
 
 #endif /* _OSSL_RUBY_MISSING_H_ */
Index: ext/openssl/ossl.c
===================================================================
--- ext/openssl/ossl.c	(revision 60012)
+++ ext/openssl/ossl.c	(revision 60013)
@@ -517,40 +517,53 @@ print_mem_leaks(VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl.c#L517
 /**
  * Stores locks needed for OpenSSL thread safety
  */
-static rb_nativethread_lock_t *ossl_locks;
+struct CRYPTO_dynlock_value {
+    rb_nativethread_lock_t lock;
+    rb_nativethread_id_t owner;
+    size_t count;
+};
 
 static void
-ossl_lock_unlock(int mode, rb_nativethread_lock_t *lock)
+ossl_lock_init(struct CRYPTO_dynlock_value *l)
 {
-    if (mode & CRYPTO_LOCK) {
-	rb_nativethread_lock_lock(lock);
-    } else {
-	rb_nativethread_lock_unlock(lock);
-    }
+    rb_nativethread_lock_initialize(&l->lock);
+    l->count = 0;
 }
 
 static void
-ossl_lock_callback(int mode, int type, const char *file, int line)
+ossl_lock_unlock(int mode, struct CRYPTO_dynlock_value *l)
 {
-    ossl_lock_unlock(mode, &ossl_locks[type]);
+    if (mode & CRYPTO_LOCK) {
+	/* TODO: rb_nativethread_id_t is not necessarily compared with ==. */
+	rb_nativethread_id_t tid = rb_nativethread_self();
+	if (l->count && l->owner == tid) {
+	    l->count++;
+	    return;
+	}
+	rb_nativethread_lock_lock(&l->lock);
+	l->owner = tid;
+	l->count = 1;
+    } else {
+	if (!--l->count)
+	    rb_nativethread_lock_unlock(&l->lock);
+    }
 }
 
-struct CRYPTO_dynlock_value {
-    rb_nativethread_lock_t lock;
-};
-
 static struct CRYPTO_dynlock_value *
 ossl_dyn_create_callback(const char *file, int line)
 {
-    struct CRYPTO_dynlock_value *dynlock = (struct CRYPTO_dynlock_value *)OPENSSL_malloc((int)sizeof(struct CRYPTO_dynlock_value));
-    rb_nativethread_lock_initialize(&dynlock->lock);
+    /* Do not use xmalloc() here, since it may raise NoMemoryError */
+    struct CRYPTO_dynlock_value *dynlock =
+	OPENSSL_malloc(sizeof(struct CRYPTO_dynlock_value));
+    if (dynlock)
+	ossl_lock_init(dynlock);
     return dynlock;
 }
 
 static void
 ossl_dyn_lock_callback(int mode, struct CRYPTO_dynlock_value *l, const char *file, int line)
 {
-    ossl_lock_unlock(mode, &l->lock);
+    ossl_lock_unlock(mode, l);
 }
 
 static void
@@ -566,21 +579,22 @@ static void ossl_threadid_func(CRYPTO_TH https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl.c#L579
     CRYPTO_THREADID_set_pointer(id, (void *)rb_nativethread_self());
 }
 
+static struct CRYPTO_dynlock_value *ossl_locks;
+
+static void
+ossl_lock_callback(int mode, int type, const char *file, int line)
+{
+    ossl_lock_unlock(mode, &ossl_locks[type]);
+}
+
 static void Init_ossl_locks(void)
 {
     int i;
     int num_locks = CRYPTO_num_locks();
 
-    if ((unsigned)num_locks >= INT_MAX / (int)sizeof(VALUE)) {
-	rb_raise(rb_eRuntimeError, "CRYPTO_num_locks() is too big: %d", num_locks);
-    }
-    ossl_locks = (rb_nativethread_lock_t *) OPENSSL_malloc(num_locks * (int)sizeof(rb_nativethread_lock_t));
-    if (!ossl_locks) {
-	rb_raise(rb_eNoMemError, "CRYPTO_num_locks() is too big: %d", num_locks);
-    }
-    for (i = 0; i < num_locks; i++) {
-	rb_nativethread_lock_initialize(&ossl_locks[i]);
-    }
+    ossl_locks = ALLOC_N(struct CRYPTO_dynlock_value, num_locks);
+    for (i = 0; i < num_locks; i++)
+	ossl_lock_init(&ossl_locks[i]);
 
     CRYPTO_THREADID_set_callback(ossl_threadid_func);
     CRYPTO_set_locking_callback(ossl_lock_callback);
Index: ext/openssl/openssl.gemspec
===================================================================
--- ext/openssl/openssl.gemspec	(revision 60012)
+++ ext/openssl/openssl.gemspec	(revision 60013)
@@ -10,11 +10,11 @@ Gem::Specification.new do |s| https://github.com/ruby/ruby/blob/trunk/ext/openssl/openssl.gemspec#L10
   s.metadata = { "msys2_mingw_dependencies" => "openssl" } if s.respond_to? :metadata=
   s.require_paths = ["lib".freeze]
   s.authors = ["Martin Bosslet".freeze, "SHIBATA Hiroshi".freeze, "Zachary Scott".freeze, "Kazuki Yamaguchi".freeze]
-  s.date = "2017-09-03"
+  s.date = "2017-09-24"
   s.description = "It wraps the OpenSSL library.".freeze
   s.email = ["ruby-core@r...".freeze]
   s.extensions = ["ext/openssl/extconf.rb".freeze]
-  s.extra_rdoc_files = ["CONTRIBUTING.md".freeze, "README.md".freeze, "History.md".freeze]
+  s.extra_rdoc_files = ["CONTRIBUTING.md".freeze, "History.md".freeze, "README.md".freeze]
   s.files = ["BSDL".freeze, "CONTRIBUTING.md".freeze, "History.md".freeze, "LICENSE.txt".freeze, "README.md".freeze, "ext/openssl/deprecation.rb".freeze, "ext/openssl/extconf.rb".freeze, "ext/openssl/openssl_missing.c".freeze, "ext/openssl/openssl_missing.h".freeze, "ext/openssl/ossl.c".freeze, "ext/openssl/ossl.h".freeze, "ext/openssl/ossl_asn1.c".freeze, "ext/openssl/ossl_asn1.h".freeze, "ext/openssl/ossl_bio.c".freeze, "ext/openssl/ossl_bio.h".freeze, "ext/openssl/ossl_bn.c".freeze, "ext/openssl/ossl_bn.h".freeze, "ext/openssl/ossl_cipher.c".freeze, "ext/openssl/ossl_cipher.h".freeze, "ext/openssl/ossl_config.c".freeze, "ext/openssl/ossl_config.h".freeze, "ext/openssl/ossl_digest.c".freeze, "ext/openssl/ossl_digest.h".freeze, "ext/openssl/ossl_engine.c".freeze, "ext/openssl/ossl_engine.h".freeze, "ext/openssl/ossl_hmac.c".freeze, "ext/openssl/ossl_hmac.h".freeze, "ext/openssl/ossl_kdf.c".freeze, "ext/openssl/ossl_kdf.h".freeze, "ext/openssl/ossl_ns_spki.c".freeze, "ext/openssl/os
 sl_ns_spki.h".freeze, "ext/openssl/ossl_ocsp.c".freeze, "ext/openssl/ossl_ocsp.h".freeze, "ext/openssl/ossl_pkcs12.c".freeze, "ext/openssl/ossl_pkcs12.h".freeze, "ext/openssl/ossl_pkcs7.c".freeze, "ext/openssl/ossl_pkcs7.h".freeze, "ext/openssl/ossl_pkey.c".freeze, "ext/openssl/ossl_pkey.h".freeze, "ext/openssl/ossl_pkey_dh.c".freeze, "ext/openssl/ossl_pkey_dsa.c".freeze, "ext/openssl/ossl_pkey_ec.c".freeze, "ext/openssl/ossl_pkey_rsa.c".freeze, "ext/openssl/ossl_rand.c".freeze, "ext/openssl/ossl_rand.h".freeze, "ext/openssl/ossl_ssl.c".freeze, "ext/openssl/ossl_ssl.h".freeze, "ext/openssl/ossl_ssl_session.c".freeze, "ext/openssl/ossl_version.h".freeze, "ext/openssl/ossl_x509.c".freeze, "ext/openssl/ossl_x509.h".freeze, "ext/openssl/ossl_x509attr.c".freeze, "ext/openssl/ossl_x509cert.c".freeze, "ext/openssl/ossl_x509crl.c".freeze, "ext/openssl/ossl_x509ext.c".freeze, "ext/openssl/ossl_x509name.c".freeze, "ext/openssl/ossl_x509req.c".freeze, "ext/openssl/ossl_x509revoked.c".freeze, "
 ext/openssl/ossl_x509store.c".freeze, "ext/openssl/ruby_missing.h".freeze, "lib/openssl.rb".freeze, "lib/openssl/bn.rb".freeze, "lib/openssl/buffering.rb".freeze, "lib/openssl/cipher.rb".freeze, "lib/openssl/config.rb".freeze, "lib/openssl/digest.rb".freeze, "lib/openssl/pkcs5.rb".freeze, "lib/openssl/pkey.rb".freeze, "lib/openssl/ssl.rb".freeze, "lib/openssl/x509.rb".freeze]
   s.homepage = "https://github.com/ruby/openssl".freeze
   s.licenses = ["Ruby".freeze]
Index: ext/openssl/ossl_x509name.c
===================================================================
--- ext/openssl/ossl_x509name.c	(revision 60012)
+++ ext/openssl/ossl_x509name.c	(revision 60013)
@@ -305,7 +305,7 @@ ossl_x509name_to_s(int argc, VALUE *argv https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_x509name.c#L305
 }
 
 /*
- * call-seq;
+ * call-seq:
  *    name.to_utf8 -> string
  *
  * Returns an UTF-8 representation of the distinguished name, as specified

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]