ruby-changes:50768
From: usa <ko1@a...>
Date: Wed, 28 Mar 2018 15:49:51 +0900 (JST)
Subject: [ruby-changes:50768] usa:r62951 (ruby_2_3): backport some changes from openssl gem v2.0.6 and v2.0.7.
usa 2018-03-28 15:49:42 +0900 (Wed, 28 Mar 2018) New Revision: 62951 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=62951 Log: backport some changes from openssl gem v2.0.6 and v2.0.7. [Backport #13935] Modified files: branches/ruby_2_3/ChangeLog branches/ruby_2_3/ext/openssl/ossl.c branches/ruby_2_3/ext/openssl/ossl_cipher.c branches/ruby_2_3/ext/openssl/ossl_ssl.c branches/ruby_2_3/test/openssl/test_cipher.rb branches/ruby_2_3/test/openssl/test_pair.rb branches/ruby_2_3/version.h Index: ruby_2_3/test/openssl/test_cipher.rb =================================================================== --- ruby_2_3/test/openssl/test_cipher.rb (revision 62950) +++ ruby_2_3/test/openssl/test_cipher.rb (revision 62951) @@ -253,6 +253,13 @@ class OpenSSL::TestCipher < Test::Unit:: https://github.com/ruby/ruby/blob/trunk/ruby_2_3/test/openssl/test_cipher.rb#L253 assert_equal tag1, tag2 end if has_cipher?("aes-128-gcm") + def test_non_aead_cipher_set_auth_data + assert_raise(OpenSSL::Cipher::CipherError) { + cipher = OpenSSL::Cipher.new("aes-128-cfb").encrypt + cipher.auth_data = "123" + } + end + end private Index: ruby_2_3/test/openssl/test_pair.rb =================================================================== --- ruby_2_3/test/openssl/test_pair.rb (revision 62950) +++ ruby_2_3/test/openssl/test_pair.rb (revision 62951) @@ -213,6 +213,27 @@ module OpenSSL::TestPairM https://github.com/ruby/ruby/blob/trunk/ruby_2_3/test/openssl/test_pair.rb#L213 } 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 write_nonblock(socket, meth, str) ret = socket.send(meth, str) ret.is_a?(Symbol) ? 0 : ret Index: ruby_2_3/ChangeLog =================================================================== --- ruby_2_3/ChangeLog (revision 62950) +++ ruby_2_3/ChangeLog (revision 62951) @@ -1,4 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_3/ChangeLog#L1 -Thu Mar 28 15:24:15 2018 Nobuyoshi Nakada <nobu@r...> +Wed Mar 28 15:48:30 2018 Kazuki Yamaguchi <k@r...> + + backport some changes from openssl gem v2.0.6 and v2.0.7. + [Backport #13935] + +Wed Mar 28 15:24:15 2018 Nobuyoshi Nakada <nobu@r...> Fix setting method visibility on method wrapped with prepend @@ -8,7 +13,7 @@ Thu Mar 28 15:24:15 2018 Nobuyoshi Naka https://github.com/ruby/ruby/blob/trunk/ruby_2_3/ChangeLog#L13 From: Dylan Thacker-Smith Dylan.Smith@s... -Thu Mar 28 15:02:43 2018 Nobuyoshi Nakada <nobu@r...> +Wed Mar 28 15:02:43 2018 Nobuyoshi Nakada <nobu@r...> resolv.rb: close socket @@ -27,14 +32,14 @@ Thu Mar 28 15:02:43 2018 Nobuyoshi Naka https://github.com/ruby/ruby/blob/trunk/ruby_2_3/ChangeLog#L32 From: quixoten (Devin Christensen) quixoten@g... -Thu Mar 28 14:59:27 2018 Nobuyoshi Nakada <nobu@r...> +Wed Mar 28 14:59:27 2018 Nobuyoshi Nakada <nobu@r...> socket.c: null byte at Socket.getnameinfo * ext/socket/socket.c (sock_s_getnameinfo): check null byte. patched by tommy (Masahiro Tomita) in . [Bug #13994] -Thu Mar 28 14:53:57 2018 Nobuyoshi Nakada <nobu@r...> +Wed Mar 28 14:53:57 2018 Nobuyoshi Nakada <nobu@r...> date_core.c: defensive code @@ -43,14 +48,14 @@ Thu Mar 28 14:53:57 2018 Nobuyoshi Naka https://github.com/ruby/ruby/blob/trunk/ruby_2_3/ChangeLog#L48 * ext/date/date_core.c (d_lite_step): deal with the comparison result more defensively. [Bug #14549] -Thu Mar 28 14:50:52 2018 Nobuyoshi Nakada <nobu@r...> +Wed Mar 28 14:50:52 2018 Nobuyoshi Nakada <nobu@r...> string.c: clear substring code range * string.c (str_substr): substring of broken code range string may be valid or broken. patch by tommy (Masahiro Tomita) at [Bug #14388]. -Thu Mar 28 14:48:13 2018 Nobuyoshi Nakada <nobu@r...> +Wed Mar 28 14:48:13 2018 Nobuyoshi Nakada <nobu@r...> win32.c: memcpy instead of strlcpy @@ -59,7 +64,7 @@ Thu Mar 28 14:48:13 2018 Nobuyoshi Naka https://github.com/ruby/ruby/blob/trunk/ruby_2_3/ChangeLog#L64 * win32/win32.c (w32_cmdvector): ditto, with NUL-terminating. -Mon Mar 28 14:45:02 2018 Koichi Sasada <ko1@a...> +Wed Mar 28 14:45:02 2018 Koichi Sasada <ko1@a...> check array for zsuper. [Bug #14279] @@ -68,7 +73,7 @@ Mon Mar 28 14:45:02 2018 Koichi Sasada https://github.com/ruby/ruby/blob/trunk/ruby_2_3/ChangeLog#L73 * test/ruby/test_super.rb: add a test for this bug. -Sun Mar 28 14:40:25 2018 Eric Wong <normalperson@y...> +Wed Mar 28 14:40:25 2018 Eric Wong <normalperson@y...> net/ftp: fix FrozenError in BufferedSocket @@ -82,7 +87,7 @@ Sun Mar 28 14:40:25 2018 Eric Wong <no https://github.com/ruby/ruby/blob/trunk/ruby_2_3/ChangeLog#L87 * test/net/ftp/test_buffered_socket.rb (test_read_nil): new test [Bug #14323] -Thu Mar 28 14:29:26 2018 Nobuyoshi Nakada <nobu@r...> +Wed Mar 28 14:29:26 2018 Nobuyoshi Nakada <nobu@r...> clean autogenerated files @@ -96,7 +101,7 @@ Thu Mar 28 14:29:26 2018 Nobuyoshi Naka https://github.com/ruby/ruby/blob/trunk/ruby_2_3/ChangeLog#L101 Ignore enc/jis/props.h -Thu Mar 28 14:14:25 2018 URABE Shyouhei <shyouhei@r...> +Wed Mar 28 14:14:25 2018 URABE Shyouhei <shyouhei@r...> fix SEGV touching uninitialized memory This function can be called from boot_defclass(). @@ -119,7 +124,7 @@ Thu Mar 28 14:14:25 2018 URABE Shyouhei https://github.com/ruby/ruby/blob/trunk/ruby_2_3/ChangeLog#L124 gc_writebarrier_incremental is called before or in middle of object initialization. Can casue SEGV. -Thu Mar 28 13:56:17 2018 NARUSE, Yui <naruse@r...> +Wed Mar 28 13:56:17 2018 NARUSE, Yui <naruse@r...> raise error if value contains CR/LF in iniheader of initialize_http_header @@ -127,21 +132,21 @@ Thu Mar 28 13:56:17 2018 NARUSE, Yui < https://github.com/ruby/ruby/blob/trunk/ruby_2_3/ChangeLog#L132 like r59693, initialize_http_header also should raise error. [Bug #14208] -Thu Mar 28 13:48:35 2018 Nobuyoshi Nakada <nobu@r...> +Wed Mar 28 13:48:35 2018 Nobuyoshi Nakada <nobu@r...> parse.y: end of script at newline * parse.y (parser_yylex): deal with end of script chars just after ignored newline as other places. [Bug #14206] -Thu Mar 28 13:42:55 2018 Kazuhiro NISHIYAMA <zn@m...> +Wed Mar 28 13:42:55 2018 Kazuhiro NISHIYAMA <zn@m...> [DOC] IO.new accepts external_encoding Revert part of r61278 [Bug #13655] [ci skip] -Thu Mar 28 13:42:55 2018 NARUSE, Yui <naruse@r...> +Wed Mar 28 13:42:55 2018 NARUSE, Yui <naruse@r...> IO.new doesn't receive "-" as external_encoding [Bug #13655] Index: ruby_2_3/ext/openssl/ossl_cipher.c =================================================================== --- ruby_2_3/ext/openssl/ossl_cipher.c (revision 62950) +++ ruby_2_3/ext/openssl/ossl_cipher.c (revision 62951) @@ -560,6 +560,8 @@ ossl_cipher_set_auth_data(VALUE self, VA https://github.com/ruby/ruby/blob/trunk/ruby_2_3/ext/openssl/ossl_cipher.c#L560 in_len = RSTRING_LEN(data); GetCipher(self, ctx); + if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER)) + ossl_raise(eCipherError, "AEAD not supported by this cipher"); if (!ossl_cipher_update_long(ctx, NULL, &out_len, in, in_len)) ossl_raise(eCipherError, "couldn't set additional authenticated data"); Index: ruby_2_3/ext/openssl/ossl_ssl.c =================================================================== --- ruby_2_3/ext/openssl/ossl_ssl.c (revision 62950) +++ ruby_2_3/ext/openssl/ossl_ssl.c (revision 62951) @@ -427,6 +427,13 @@ ossl_sslctx_session_remove_cb(SSL_CTX *c https://github.com/ruby/ruby/blob/trunk/ruby_2_3/ext/openssl/ossl_ssl.c#L427 void *ptr; int state = 0; + /* + * This callback is also called for all sessions in the internal store + * when SSL_CTX_free() is called. + */ + if (rb_during_gc()) + return; + OSSL_Debug("SSL SESSION remove callback entered"); if ((ptr = SSL_CTX_get_ex_data(ctx, ossl_ssl_ex_ptr_idx)) == NULL) @@ -1427,21 +1434,25 @@ ossl_ssl_read_internal(int argc, VALUE * https://github.com/ruby/ruby/blob/trunk/ruby_2_3/ext/openssl/ossl_ssl.c#L1434 } 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); GetOpenFile(ossl_ssl_get_io(self), fptr); if (ssl) { - if(!nonblock && SSL_pending(ssl) <= 0) - rb_thread_wait_fd(FPTR_TO_FD(fptr)); 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; @@ -1481,8 +1492,6 @@ ossl_ssl_read_internal(int argc, VALUE * https://github.com/ruby/ruby/blob/trunk/ruby_2_3/ext/openssl/ossl_ssl.c#L1492 end: rb_str_set_len(str, nread); - OBJ_TAINT(str); - return str; } Index: ruby_2_3/ext/openssl/ossl.c =================================================================== --- ruby_2_3/ext/openssl/ossl.c (revision 62950) +++ ruby_2_3/ext/openssl/ossl.c (revision 62951) @@ -468,32 +468,46 @@ ossl_fips_mode_set(VALUE self, VALUE ena https://github.com/ruby/ruby/blob/trunk/ruby_2_3/ext/openssl/ossl.c#L468 * Stores locks needed for OpenSSL thread safety */ #include "ruby/thread_native.h" -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)); + /* 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); rb_nativethread_lock_initialize(&dynlock->lock); return dynlock; } @@ -501,7 +515,7 @@ ossl_dyn_create_callback(const char *fil https://github.com/ruby/ruby/blob/trunk/ruby_2_3/ext/openssl/ossl.c#L515 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 @@ -525,21 +539,22 @@ static unsigned long ossl_thread_id(void https://github.com/ruby/ruby/blob/trunk/ruby_2_3/ext/openssl/ossl.c#L539 } #endif +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]); #ifdef HAVE_CRYPTO_THREADID_PTR CRYPTO_THREADID_set_callback(ossl_threadid_func); Index: ruby_2_3/version.h =================================================================== --- ruby_2_3/version.h (revision 62950) +++ ruby_2_3/version.h (revision 62951) @@ -1,6 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_3/version.h#L1 #define RUBY_VERSION "2.3.7" #define RUBY_RELEASE_DATE "2018-03-28" -#define RUBY_PATCHLEVEL 447 +#define RUBY_PATCHLEVEL 448 #define RUBY_RELEASE_YEAR 2018 #define RUBY_RELEASE_MONTH 3 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/