summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog33
-rw-r--r--ext/openssl/ossl.c65
-rw-r--r--ext/openssl/ossl_cipher.c2
-rw-r--r--ext/openssl/ossl_ssl.c31
-rw-r--r--test/openssl/test_cipher.rb7
-rw-r--r--test/openssl/test_pair.rb21
-rw-r--r--version.h2
7 files changed, 110 insertions, 51 deletions
diff --git a/ChangeLog b/ChangeLog
index a8e3b8a795..38432dfd33 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,9 @@
-Thu Mar 28 15:24:15 2018 Nobuyoshi Nakada <nobu@ruby-lang.org>
+Wed Mar 28 15:48:30 2018 Kazuki Yamaguchi <k@rhe.jp>
+
+ 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@ruby-lang.org>
Fix setting method visibility on method wrapped with prepend
@@ -8,7 +13,7 @@ Thu Mar 28 15:24:15 2018 Nobuyoshi Nakada <nobu@ruby-lang.org>
From: Dylan Thacker-Smith Dylan.Smith@shopify.com
-Thu Mar 28 15:02:43 2018 Nobuyoshi Nakada <nobu@ruby-lang.org>
+Wed Mar 28 15:02:43 2018 Nobuyoshi Nakada <nobu@ruby-lang.org>
resolv.rb: close socket
@@ -27,14 +32,14 @@ Thu Mar 28 15:02:43 2018 Nobuyoshi Nakada <nobu@ruby-lang.org>
From: quixoten (Devin Christensen) quixoten@gmail.com
-Thu Mar 28 14:59:27 2018 Nobuyoshi Nakada <nobu@ruby-lang.org>
+Wed Mar 28 14:59:27 2018 Nobuyoshi Nakada <nobu@ruby-lang.org>
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@ruby-lang.org>
+Wed Mar 28 14:53:57 2018 Nobuyoshi Nakada <nobu@ruby-lang.org>
date_core.c: defensive code
@@ -43,14 +48,14 @@ Thu Mar 28 14:53:57 2018 Nobuyoshi Nakada <nobu@ruby-lang.org>
* 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@ruby-lang.org>
+Wed Mar 28 14:50:52 2018 Nobuyoshi Nakada <nobu@ruby-lang.org>
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@ruby-lang.org>
+Wed Mar 28 14:48:13 2018 Nobuyoshi Nakada <nobu@ruby-lang.org>
win32.c: memcpy instead of strlcpy
@@ -59,7 +64,7 @@ Thu Mar 28 14:48:13 2018 Nobuyoshi Nakada <nobu@ruby-lang.org>
* win32/win32.c (w32_cmdvector): ditto, with NUL-terminating.
-Mon Mar 28 14:45:02 2018 Koichi Sasada <ko1@atdot.net>
+Wed Mar 28 14:45:02 2018 Koichi Sasada <ko1@atdot.net>
check array for zsuper. [Bug #14279]
@@ -68,7 +73,7 @@ Mon Mar 28 14:45:02 2018 Koichi Sasada <ko1@atdot.net>
* test/ruby/test_super.rb: add a test for this bug.
-Sun Mar 28 14:40:25 2018 Eric Wong <normalperson@yhbt.net>
+Wed Mar 28 14:40:25 2018 Eric Wong <normalperson@yhbt.net>
net/ftp: fix FrozenError in BufferedSocket
@@ -82,7 +87,7 @@ Sun Mar 28 14:40:25 2018 Eric Wong <normalperson@yhbt.net>
* test/net/ftp/test_buffered_socket.rb (test_read_nil): new test
[Bug #14323]
-Thu Mar 28 14:29:26 2018 Nobuyoshi Nakada <nobu@ruby-lang.org>
+Wed Mar 28 14:29:26 2018 Nobuyoshi Nakada <nobu@ruby-lang.org>
clean autogenerated files
@@ -96,7 +101,7 @@ Thu Mar 28 14:29:26 2018 Nobuyoshi Nakada <nobu@ruby-lang.org>
Ignore enc/jis/props.h
-Thu Mar 28 14:14:25 2018 URABE Shyouhei <shyouhei@ruby-lang.org>
+Wed Mar 28 14:14:25 2018 URABE Shyouhei <shyouhei@ruby-lang.org>
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 <shyouhei@ruby-lang.org>
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@ruby-lang.org>
+Wed Mar 28 13:56:17 2018 NARUSE, Yui <naruse@ruby-lang.org>
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 <naruse@ruby-lang.org>
like r59693, initialize_http_header also should raise error.
[Bug #14208]
-Thu Mar 28 13:48:35 2018 Nobuyoshi Nakada <nobu@ruby-lang.org>
+Wed Mar 28 13:48:35 2018 Nobuyoshi Nakada <nobu@ruby-lang.org>
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@mbf.nifty.com>
+Wed Mar 28 13:42:55 2018 Kazuhiro NISHIYAMA <zn@mbf.nifty.com>
[DOC] IO.new accepts external_encoding
Revert part of r61278 [Bug #13655]
[ci skip]
-Thu Mar 28 13:42:55 2018 NARUSE, Yui <naruse@ruby-lang.org>
+Wed Mar 28 13:42:55 2018 NARUSE, Yui <naruse@ruby-lang.org>
IO.new doesn't receive "-" as external_encoding [Bug #13655]
diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c
index fb8f2c8171..0ee380507a 100644
--- a/ext/openssl/ossl.c
+++ b/ext/openssl/ossl.c
@@ -468,32 +468,46 @@ ossl_fips_mode_set(VALUE self, VALUE enabled)
* 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 *file, int line)
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)
}
#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);
diff --git a/ext/openssl/ossl_cipher.c b/ext/openssl/ossl_cipher.c
index 24caba6e37..e167995d49 100644
--- a/ext/openssl/ossl_cipher.c
+++ b/ext/openssl/ossl_cipher.c
@@ -560,6 +560,8 @@ ossl_cipher_set_auth_data(VALUE self, VALUE data)
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");
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
index 7a0eb4ec90..cd35ee3771 100644
--- a/ext/openssl/ossl_ssl.c
+++ b/ext/openssl/ossl_ssl.c
@@ -427,6 +427,13 @@ ossl_sslctx_session_remove_cb(SSL_CTX *ctx, SSL_SESSION *sess)
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 *argv, VALUE self, int nonblock)
}
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 *argv, VALUE self, int nonblock)
end:
rb_str_set_len(str, nread);
- OBJ_TAINT(str);
-
return str;
}
diff --git a/test/openssl/test_cipher.rb b/test/openssl/test_cipher.rb
index 95058b5f19..a89bced254 100644
--- a/test/openssl/test_cipher.rb
+++ b/test/openssl/test_cipher.rb
@@ -253,6 +253,13 @@ class OpenSSL::TestCipher < Test::Unit::TestCase
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
diff --git a/test/openssl/test_pair.rb b/test/openssl/test_pair.rb
index e999d206cf..6c89f1969a 100644
--- a/test/openssl/test_pair.rb
+++ b/test/openssl/test_pair.rb
@@ -213,6 +213,27 @@ module OpenSSL::TestPairM
}
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
diff --git a/version.h b/version.h
index a47a684c15..1b2b176e5b 100644
--- a/version.h
+++ b/version.h
@@ -1,6 +1,6 @@
#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